コード例 #1
0
ファイル: t-forward_nmod_mat.c プロジェクト: jwbober/arb
int main()
{
    long iter;
    flint_rand_t state;

    printf("forward_nmod_mat....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        fmpz_holonomic_t op;
        fmpz_mat_t M1;
        fmpz_t Q1;
        nmod_mat_t M2, L, R;
        mp_limb_t Q2;
        long start, n, r;
        mp_limb_t p;

        fmpz_holonomic_init(op);

        fmpz_holonomic_randtest(op, state, 4, 4, 10);

        r = fmpz_holonomic_order(op);
        start = n_randint(state, 10);
        n = n_randint(state, 100);
        p = n_randtest_prime(state, 0);

        fmpz_mat_init(M1, r, r);
        fmpz_init(Q1);
        nmod_mat_init(M2, r, r, p);
        nmod_mat_init(L, r, r, p);
        nmod_mat_init(R, r, r, p);

        fmpz_holonomic_forward_fmpz_mat(M1, Q1, op, start, n);
        fmpz_holonomic_forward_nmod_mat(M2, &Q2, op, start, n);

        fmpz_mat_get_nmod_mat(L, M1);
        nmod_mat_scalar_mul(L, L, Q2);

        nmod_mat_scalar_mul(R, M2, fmpz_fdiv_ui(Q1, p));

        /* check Q2 * M1 = Q1 * M2 */

        if (!nmod_mat_equal(L, R))
        {
            printf("FAIL\n");

            fmpz_holonomic_print(op, "n", "Sn"); printf("\n\n");
            printf("start = %lu, n = %lu\n", start, n);

            fmpz_mat_print_pretty(M1); printf("\n\n");
            fmpz_print(Q1); printf("\n\n");

            nmod_mat_print_pretty(M2); printf("\n\n");
            printf("%lu\n\n", Q2);

            abort();
        }

        fmpz_mat_clear(M1);
        fmpz_clear(Q1);
        nmod_mat_clear(M2);
        nmod_mat_clear(L);
        nmod_mat_clear(R);

        fmpz_holonomic_clear(op);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
コード例 #2
0
void 
fmpz_mat_det_modular_given_divisor_8arg(mpz_t det, nmod_mat_t Amod,
  mpfr_t hadamard_log2, mpfr_prec_t pr, p_k_pk_t* pp, n_primes_rev_t iT,
  mp_limb_t xmod, const fmpz_mat_t A)
/*
act like fmpz_mat_det_modular_given_divisor_4block(), but
 * decrease primes using iT, rather than increase them
 * don't count H.B., use hadamard_log2 which is 1+log2(H.B.)
 * sum logarithms instead of multiplying together found primes
 * re-use found prime pp->p and xmod which is determinant of A modulo pp->p

hadamard_log2 on entry is upper bound on log2(2*H.B)
              on exit, decreased to an unspecified value 

iT on entry just found prime pp->p
   possibly gets shifted 
*/
 {
  // loop bound = 2*H.B / known det divisor
  decrease_bound_mpz(hadamard_log2,pr,det);

  #if 0
   flint_printf("det modulo %llX = %llX\n",pp->p_deg_k,xmod);
  #endif
  // re-use known det A modulo pp->p_deg_k
  mp_limb_t divisor_inv=invert_det_divisor_modulo_pk(det,pp,&Amod->mod);
  xmod=n_mulmod2_preinv(xmod,divisor_inv, Amod->mod.n,Amod->mod.ninv);
  fmpz_t xnew,x;
  fmpz_init(xnew); 
  fmpz_init(x); 
  fmpz_t prod; fmpz_init_set_ui(prod, UWORD(1) );

  fmpz_CRT_ui(xnew, x, prod, xmod, pp->p_deg_k, 1);
  fmpz_set_ui(prod, pp->p_deg_k);
  fmpz_set(x, xnew);

  #if LOUD_DET_BOUND
   mpfr_printf("fmpz_mat_det_modular_given_divisor_8arg(): log2 bound=%Rf\n",
    hadamard_log2);
   slong primes_used=1;
  #endif
  // for orthogonal matrice the bound might be reached at this point.
  //  Attempt to skip main loop
  if(comp_bound_ui(hadamard_log2,pp->p_deg_k))
   {
    mp_limb_t* scratch=flint_malloc( 4*(A->r-4)*sizeof(mp_limb_t) );
    mp_limb_t bound=mpfr_get_uj(hadamard_log2,MPFR_RNDU);

    for(;;)
     {
      divisor_inv=choose_prime_and_degree( pp, &Amod->mod, iT, det );
      // TODO: optimize fmpz_mat_get_nmod_mat()
      fmpz_mat_get_nmod_mat(Amod, A);
      // TODO: call a faster subroutine instead of nmod_mat_det_mod_pk_4block()
      //  when pp->p is 64 bit long
      xmod=nmod_mat_det_mod_pk_4block(Amod,pp[0],scratch);
      xmod=n_mulmod2_preinv(xmod,divisor_inv, Amod->mod.n,Amod->mod.ninv);
      // TODO: rewrite fmpz_CRT_ui() -> mpz_CRT_ui_5arg()
      fmpz_CRT_ui(xnew, x, prod, xmod, pp->p_deg_k, 1);
      fmpz_mul_ui(prod, prod, pp->p_deg_k);
      #if LOUD_DET_BOUND
       primes_used++;
      #endif
      if(cmp_positive_log2(prod,bound) >= 0)
       break;
      fmpz_set(x, xnew);
     }
  
    flint_free(scratch);
   }

  #if LOUD_DET_BOUND
   flint_printf("fmpz_mat_det_modular_given_divisor_8arg() primes used: %d\n\n\n",
    primes_used);
  #endif
  fmpz_clear(prod);
  mpz_fmpz_mul_det_2arg(det,xnew);
  fmpz_clear(prod);
  fmpz_clear(x);
  fmpz_clear(xnew);
 }