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; }
void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, const fmpz_t a, const fmpz_t p) { if (len == 0) { fmpz_zero(res); } else if (len == 1 || fmpz_is_zero(a)) { fmpz_set(res, poly); } else { slong i = len - 1; fmpz_t t; fmpz_init(t); fmpz_set(res, poly + i); for (i = len - 2; i >= 0; i--) { fmpz_mul(t, res, a); fmpz_mod(t, t, p); fmpz_add(res, poly + i, t); } fmpz_clear(t); if (fmpz_cmpabs(res, p) >= 0) fmpz_sub(res, res, p); } }
void fmpz_multi_mod_ui(unsigned long * out, fmpz_t in, fmpz_comb_t comb, fmpz_t ** temp) { ulong i, j, k; ulong n = comb->n; long log_comb; ulong size; mp_limb_t * ptr; ulong num; unsigned long num_primes = comb->num_primes; if (num_primes == 1) // we are reducing modulo a single prime which is assumed to be big enough { if ((long)in[0] > 0L) out[0] = in[1]; else if ((long)in[0] < 0L) out[0] = comb->primes[0] - in[1]; else out[0] = 0L; return; } log_comb = n - 1; // find level in comb with entries bigger than the input integer log_comb = 0; if ((long) in[0] < 0L) while ((fmpz_bits(in) >= fmpz_bits(comb->comb[log_comb][0]) - 1) && (log_comb < comb->n - 1)) log_comb++; else while (fmpz_cmpabs(in, comb->comb[log_comb][0]) >= 0) log_comb++; num = (1L<<(n - log_comb - 1)); // set each entry of this level of temp to the input integer for (i = 0; i < num; i++) { fmpz_set(temp[log_comb][i], in); } log_comb--; num *= 2; // fill in other entries of temp by taking entries of temp at higher level mod pairs from comb while (log_comb > FLINT_LOG_MULTI_MOD_CUTOFF) // keep going until we reach the basecase { for (i = 0, j = 0; i < num; i += 2, j++) { fmpz_mod(temp[log_comb][i], temp[log_comb + 1][j], comb->comb[log_comb][i]); fmpz_mod(temp[log_comb][i+1], temp[log_comb + 1][j], comb->comb[log_comb][i+1]); } num *= 2; log_comb--; } // do basecase num /= 2; log_comb++; ulong stride = (1L << (log_comb + 1)); for (i = 0, j = 0; j < num_primes; i++, j += stride) { fmpz_multi_mod_ui_basecase(out + j, temp[log_comb][i], comb->primes + j, FLINT_MIN(stride, num_primes - j)); } }
void elem_add(elem_ptr res, elem_srcptr op1, elem_srcptr op2, const ring_t ring) { switch (ring->type) { case TYPE_FMPZ: fmpz_add(res, op1, op2); break; case TYPE_LIMB: *((mp_ptr) res) = *((mp_srcptr) op1) + *((mp_srcptr) op2); break; case TYPE_POLY: elem_poly_add(res, op1, op2, ring); break; case TYPE_MOD: { switch (RING_PARENT(ring)->type) { case TYPE_LIMB: *((mp_ptr) res) = n_addmod(*((mp_srcptr) op1), *((mp_srcptr) op2), ring->nmod.n); break; case TYPE_FMPZ: fmpz_add(res, op1, op2); if (fmpz_cmpabs(res, RING_MODULUS(ring)) >= 0) fmpz_sub(res, res, RING_MODULUS(ring)); break; default: NOT_IMPLEMENTED("add (mod)", ring); } } break; case TYPE_FRAC: elem_frac_add(res, op1, op2, ring); break; case TYPE_COMPLEX: elem_add(REALPART(res, ring), REALPART(op1, ring), REALPART(op2, ring), ring->parent); elem_add(IMAGPART(res, ring), IMAGPART(op1, ring), IMAGPART(op2, ring), ring->parent); break; default: NOT_IMPLEMENTED("add", ring); } }
void test1(mp_limb_t log2,const fmpz_t b,const fmpz_t z) { if( (fmpz_cmp_ui(z,0)<=0) || (log2==0) ) return; int r0=fmpz_cmpabs(z,b); int r1=cmp_positive_log2(z,log2); #if LOUD fmpz_hex_print("2**y=",b,0); fmpz_hex_print(" z=",z,0); flint_printf(" r0/1: %d/%d\n",r0,r1); #endif if( r0>0 ) assert( r1>0 ); if( r0<0 ) assert( r1<0 ); if( r0==0 ) assert( 0 == r1 ); }
int fmpr_cmpabs(const fmpr_t x, const fmpr_t y) { int res, xsign, ysign; fmpr_t t; if (fmpr_equal(x, y)) return 0; if (fmpr_is_special(x) || fmpr_is_special(y)) { if (fmpr_is_nan(x) || fmpr_is_nan(y)) return 0; if (fmpr_is_zero(x)) return -1; if (fmpr_is_zero(y)) return 1; if (fmpr_is_inf(x)) return fmpr_is_inf(y) ? 0 : 1; if (fmpr_is_inf(y)) return -1; return -1; } /* Reduces to integer comparison if bottom exponents are the same */ if (fmpz_equal(fmpr_expref(x), fmpr_expref(y))) { res = fmpz_cmpabs(fmpr_manref(x), fmpr_manref(y)); if (res != 0) res = (res < 0) ? -1 : 1; } else { /* TODO: compare position of top exponents to avoid subtraction */ xsign = fmpr_sgn(x); ysign = fmpr_sgn(y); fmpr_init(t); if (xsign == ysign) fmpr_sub(t, x, y, 2, FMPR_RND_DOWN); else fmpr_add(t, x, y, 2, FMPR_RND_DOWN); res = fmpr_sgn(t) * xsign; fmpr_clear(t); } return res; }
void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, long len1, const fmpz *poly2, long len2, const fmpz_t p) { if (len1 == 1 || len2 == 0) { fmpz_set(res, poly1); } else { const long alloc = (len1 - 1) * (len2 - 1) + 1; long i = len1 - 1, lenr = len2; fmpz * t = _fmpz_vec_init(alloc); /* Perform the first two steps as one, "res = a(m) * poly2 + a(m-1)". */ { _fmpz_mod_poly_scalar_mul_fmpz(res, poly2, len2, poly1 + i, p); i--; fmpz_add(res, res, poly1 + i); if (fmpz_cmpabs(res, p) >= 0) fmpz_sub(res, res, p); } while (i > 0) { i--; _fmpz_mod_poly_mul(t, res, lenr, poly2, len2, p); lenr += len2 - 1; _fmpz_mod_poly_add(res, t, lenr, poly1 + i, 1, p); } _fmpz_vec_clear(t, alloc); } }
int main() { slong iter; flint_rand_t state; flint_printf("cmpabs...."); fflush(stdout); flint_randinit(state); /* compare with fmpz */ { arf_t x, y; fmpz_t X, Y; arf_init(x); arf_init(y); fmpz_init(X); fmpz_init(Y); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { int cmp1, cmp2; fmpz_randtest(X, state, 1 + n_randint(state, 1000)); switch (n_randint(state, 8)) { case 0: fmpz_neg(Y, X); break; case 1: fmpz_set(Y, X); break; default: fmpz_randtest(Y, state, 1 + n_randint(state, 1000)); } arf_set_fmpz(x, X); arf_set_fmpz(y, Y); cmp1 = arf_cmpabs(x, y); cmp2 = fmpz_cmpabs(X, Y); cmp2 = (cmp2 > 0) - (cmp2 < 0); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_debug(x); flint_printf("\n\n"); flint_printf("y = "); arf_debug(y); flint_printf("\n\n"); flint_printf("X = "); fmpz_print(X); flint_printf("\n\n"); flint_printf("Y = "); fmpz_print(Y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); abort(); } } arf_clear(x); arf_clear(y); fmpz_clear(X); fmpz_clear(Y); } /* compare with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits; arf_t x, y; mpfr_t X, Y; int cmp1, cmp2; bits = 2 + n_randint(state, 200); arf_init(x); arf_init(y); mpfr_init2(X, bits); mpfr_init2(Y, bits); arf_randtest_special(x, state, bits, 10); arf_randtest_special(y, state, bits, 10); arf_get_mpfr(X, x, MPFR_RNDN); arf_get_mpfr(Y, y, MPFR_RNDN); mpfr_abs(X, X, MPFR_RNDN); mpfr_abs(Y, Y, MPFR_RNDN); cmp1 = arf_cmpabs(x, y); cmp2 = mpfr_cmp(X, Y); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); abort(); } arf_clear(x); arf_clear(y); mpfr_clear(X); mpfr_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int fmpz_divides(fmpz_t q, const fmpz_t a, const fmpz_t b) { long a0 = a[0]; long b0 = b[0]; unsigned long sizea = FLINT_ABS(a0); unsigned long sizeb = FLINT_ABS(b0); mp_limb_t mslimb; fmpz_t temp; if (sizeb == 0) { printf("Error: division by zero!\n"); abort(); } else if (sizea == 0) { q[0] = 0; return 1; } else if (sizea < sizeb) { return 0; } else if (sizea == sizeb) { int cmp = fmpz_cmpabs(a, b); if (cmp < 0) return 0; if (cmp == 0) { if ((long) (a0 ^ b0) < 0L) q[0] = -1L; else q[0] = 1L; q[1] = 1; return 1; } } if (fmpz_is_one(b)) { fmpz_set(q, a); return 1; } if (fmpz_is_m1(b)) { fmpz_neg(q, a); return 1; } temp = (fmpz_t) flint_stack_alloc(sizeb + 2); mpn_tdiv_qr(q+1, temp+1, 0, a+1, sizea, b+1, sizeb); temp[0] = sizeb; NORM(temp); if (temp[0] != 0) { flint_stack_release(); return 0; } q[0] = sizea - sizeb + 1; NORM(q); if ((long) (a0 ^ b0) < 0L) q[0] = -q[0]; flint_stack_release(); return 1; }
void fmpz_mod(fmpz_t res, const fmpz_t a, const fmpz_t b) { long a0 = a[0]; long b0 = b[0]; unsigned long sizea = FLINT_ABS(a0); unsigned long sizeb = b0; while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; mp_limb_t mslimb; fmpz_t temp, temp2; if (sizeb == 0) { printf("Error: division by zero!\n"); abort(); } else if (sizea < sizeb) { if ((long) a0 < 0L) { temp = (fmpz_t) flint_stack_alloc(sizeb + 2); fmpz_add(temp, a, b); fmpz_set(res, temp); flint_stack_release(); } else fmpz_set(res, a); return; } else if ((sizea == sizeb) && (fmpz_cmpabs(a, b) < 0L)) { if (fmpz_sgn(a) < 0) fmpz_add(res, a, b); else fmpz_set(res, a); return; } else { if (fmpz_is_one(b)) { fmpz_set_ui(res, 0L); return; } temp = (fmpz_t) flint_stack_alloc(sizea - sizeb + 1); temp2 = (fmpz_t) flint_stack_alloc(sizeb + 2); mpn_tdiv_qr(temp, temp2+1, 0, a+1, sizea, b+1, sizeb); temp2[0] = sizeb; NORM(temp2); if (a0 < 0L) { unsigned long i = 0; for (; i < sizeb; i++) { if (temp2[i+1]) break; } if (i < sizeb) { fmpz_sub(temp2, b, temp2); } fmpz_set(res, temp2); } else fmpz_set(res, temp2); flint_stack_release(); flint_stack_release(); } }