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); }
int main() { long i, j; int sign; fmpz_t input; fmpz_t result; fmpz_t r1; fmpz_t m1; fmpz_t mprod; ulong r2, m2; flint_rand_t state; printf("CRT_ui...."); fflush(stdout); fmpz_init(input); fmpz_init(result); fmpz_init(r1); fmpz_init(m1); fmpz_init(mprod); flint_randinit(state); for (i = 0; i < 10000; i++) { long nprimes; m2 = n_randtest_prime(state, 0); nprimes = 1 + n_randint(state, 4); fmpz_set_ui(m1, 1UL); for (j = 0; j < nprimes; ) { ulong t = n_randtest_prime(state, 0); if (t != m2) { fmpz_mul_ui(m1, m1, t); j++; } } fmpz_mul_ui(mprod, m1, m2); sign = n_randint(state, 2); if (sign) fmpz_randtest_mod_signed(input, state, mprod); else fmpz_randtest_mod(input, state, mprod); fmpz_mod(r1, input, m1); r2 = fmpz_fdiv_ui(input, m2); if (sign) fmpz_CRT_ui(result, r1, m1, r2, m2); else fmpz_CRT_ui_unsigned(result, r1, m1, r2, m2); if (!fmpz_equal(result, input)) { printf("FAIL:\n"); printf("m1: "); fmpz_print(m1); printf("\n"); printf("m2: %lu\n", m2); printf("m1*m2: "); fmpz_print(mprod); printf("\n"); printf("input: "); fmpz_print(input); printf("\n"); printf("r1: "); fmpz_print(r1); printf("\n"); printf("r2: %lu\n", r2); printf("result: "); fmpz_print(result); printf("\n"); printf("%ld Equalness: %d\n", i, fmpz_equal(result, input)); printf("\n"); abort(); } } fmpz_clear(input); fmpz_clear(result); fmpz_clear(r1); fmpz_clear(m1); fmpz_clear(mprod); flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
int main() { slong i, j; int sign; fmpz_t input; fmpz_t result; fmpz_t r1; fmpz_t m1; fmpz_t mprod; ulong r2, m2; FLINT_TEST_INIT(state); flint_printf("CRT_ui...."); fflush(stdout); fmpz_init(input); fmpz_init(result); fmpz_init(r1); fmpz_init(m1); fmpz_init(mprod); for (i = 0; i < 1000 * flint_test_multiplier(); i++) { slong nprimes; m2 = n_randtest_prime(state, 0); nprimes = 1 + n_randint(state, 4); fmpz_set_ui(m1, UWORD(1)); for (j = 0; j < nprimes; ) { ulong t = n_randtest_prime(state, 0); if (t != m2) { fmpz_mul_ui(m1, m1, t); j++; } } fmpz_mul_ui(mprod, m1, m2); sign = n_randint(state, 2); if (sign) fmpz_randtest_mod_signed(input, state, mprod); else fmpz_randtest_mod(input, state, mprod); fmpz_mod(r1, input, m1); r2 = fmpz_fdiv_ui(input, m2); fmpz_CRT_ui(result, r1, m1, r2, m2, sign); if (!fmpz_equal(result, input)) { flint_printf("FAIL:\n"); flint_printf("m1: "); fmpz_print(m1); flint_printf("\n"); flint_printf("m2: %wu\n", m2); flint_printf("m1*m2: "); fmpz_print(mprod); flint_printf("\n"); flint_printf("input: "); fmpz_print(input); flint_printf("\n"); flint_printf("r1: "); fmpz_print(r1); flint_printf("\n"); flint_printf("r2: %wu\n", r2); flint_printf("result: "); fmpz_print(result); flint_printf("\n"); flint_printf("%wd Equalness: %d\n", i, fmpz_equal(result, input)); flint_printf("\n"); abort(); } } fmpz_clear(input); fmpz_clear(result); fmpz_clear(r1); fmpz_clear(m1); fmpz_clear(mprod); FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }