// truncated multiplication for fmpz void fmpz_mul_trunc(fmpz_t res, fmpz_t a, fmpz_t b, unsigned long trunc) { unsigned long sizea = FLINT_MIN(fmpz_size(a), trunc); unsigned long sizeb = FLINT_MIN(fmpz_size(b), trunc); while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; if ((sizea == 0) || (sizeb == 0)) { res[0] = 0; return; } if (trunc >= sizea + sizeb) { mp_limb_t mslimb; if (sizea >= sizeb) mslimb = F_mpn_mul(res+1, a+1, sizea, b+1, sizeb); else mslimb = F_mpn_mul(res+1, b+1, sizeb, a+1, sizea); res[0] = sizea + sizeb - (mslimb == 0); } else { mp_limb_t mslimb; fmpz_t temp = flint_stack_alloc(sizea + sizeb + 1); if (sizea >= sizeb) mslimb = F_mpn_mul_trunc(temp+1, a+1, sizea, b+1, sizeb, trunc); else mslimb = F_mpn_mul_trunc(temp+1, b+1, sizeb, a+1, sizea, trunc); temp[0] = trunc; if (UNLIKELY(!mslimb)) __fmpz_normalise(temp); // normalise if most significant limb == 0 fmpz_set(res, temp); flint_stack_release(); } if ((long) (a[0] ^ b[0]) < 0L) res[0] = -res[0]; }
void fmpz_invert(fmpz_t res, fmpz_t x, fmpz_t m) { if (m[0] == 0) { printf("Error: division by zero!\n"); abort(); } fmpz_t s0, U, V, temp; unsigned long size = fmpz_size(m); // U may use fmpz_size(m) + 1 limbs after the sum, and gmp requires +1 U = fmpz_init(size + 2); V = fmpz_init(size + 2); s0 = fmpz_init(size + 2); temp = fmpz_init(size + 2); // U := (x%m) + abs(m) // V := abs(m) fmpz_abs(V, m); fmpz_mod(U, x, V); fmpz_add(U, U, V); // Compute s0 such that 1 = s0 * x % m mpn_gcdext(temp+1, s0+1, (long *) s0, U+1, fmpz_size(U), V+1, fmpz_size(V)); fmpz_mod(res, s0, m); fmpz_clear(temp); fmpz_clear(s0); fmpz_clear(V); fmpz_clear(U); }
// Compute a*b mod m void fmpz_mulmod(fmpz_t res, fmpz_t a, fmpz_t b, fmpz_t m) { fmpz_t ab = fmpz_init(fmpz_size(a) + fmpz_size(b)); fmpz_mul(ab, a, b); fmpz_mod(res, ab, m); fmpz_clear(ab); }
// Compute a/b mod m void fmpz_divmod(fmpz_t res, fmpz_t a, fmpz_t b, fmpz_t m) { fmpz_t b_inv = fmpz_init(fmpz_size(m)); fmpz_invert(b_inv, b, m); fmpz_t ab = fmpz_init(fmpz_size(a) + fmpz_size(b_inv)); fmpz_mul(ab, a, b_inv); fmpz_mod(res, ab, m); fmpz_clear(ab); fmpz_clear(b_inv); }
void __fmpz_multi_CRT_sign(fmpz_t output, fmpz_t input, fmpz_comb_t comb) { unsigned long n = comb->n; if (n == 0L) { if (input[0] == 0L) { fmpz_set_ui(output, 0L); return; } unsigned long p = comb->primes[0]; if ((p - input[1]) < input[1]) fmpz_set_si(output, (long) (input[1] - p)); else fmpz_set_ui(output, input[1]); return; } fmpz_t temp = fmpz_init(fmpz_size(comb->comb[n-1][0]) + 1); fmpz_sub(temp, input, comb->comb[comb->n - 1][0]); if (fmpz_cmpabs(temp, input) <= 0L) fmpz_set(output, temp); else fmpz_set(output, input); fmpz_clear(temp); return; }
__inline__ static int log2_L2_fmpz_3arg(mpfr_t tgt,const fmpz* vec,slong n) // 2*log2(L2 norm) rounded up // if row is zero, return 1 and do not initialize tgt // else return 0 and initialize tgt to a suitable precision { fmpz_t norm; fmpz_init(norm); slong i,i_is_big=0; square_L2_fmpz(norm,vec,n); i=fmpz_size(norm); if( 0==i ) { fmpz_clear(norm); return 1; } if(i>2) { i=2; i_is_big=1; } mpfr_t normF; mpfr_init2(normF,i*FLINT_BITS); fmpz_get_mpfr(normF,norm,MPFR_RNDU); fmpz_clear(norm); if(i_is_big) mpfr_init2(tgt,1+FLINT_BITS); else mpfr_init(tgt); mpfr_log2(tgt, normF, MPFR_RNDU); mpfr_clear(normF); return 0; }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("size...."); fflush(stdout); for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a; mpz_t b; mp_size_t r1, r2; fmpz_init(a); mpz_init(b); fmpz_randtest(a, state, 200); fmpz_get_mpz(b, a); r1 = fmpz_size(a); r2 = mpz_size(b); result = (r1 == r2); if (!result) { flint_printf("FAIL:\n"); gmp_printf("b = %Zd\n", b); abort(); } fmpz_clear(a); mpz_clear(b); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
/* Divide (arrayg, limbsg) by the positive value gc inplace and return the number of limbs written */ mp_size_t mpn_tdiv_q_fmpz_inplace(mp_ptr arrayg, mp_size_t limbsg, fmpz_t gc) { if (fmpz_size(gc) == 1) { mpn_divmod_1(arrayg, arrayg, limbsg, fmpz_get_ui(gc)); return limbsg - (arrayg[limbsg - 1] == 0); } else { mp_size_t tlimbs; __mpz_struct * mpz_ptr = COEFF_TO_PTR(*gc); mp_ptr temp = flint_malloc(limbsg*sizeof(mp_limb_t)); mpn_copyi(temp, arrayg, limbsg); mpn_tdiv_q(arrayg, temp, limbsg, mpz_ptr->_mp_d, mpz_ptr->_mp_size); tlimbs = limbsg - mpz_ptr->_mp_size + 1; tlimbs -= (arrayg[tlimbs - 1] == 0); flint_free(temp); return tlimbs; } }