void bisect_sfdlProverExo::baseline(const mpq_t* input_q, int num_inputs, mpq_t* output_recomputed, int num_outputs) { int m = bisect_sfdl_cons::m; int L = bisect_sfdl_cons::L; mpq_t temp_q; alloc_init_scalar(temp_q); mpq_t* a = output_recomputed; mpq_t* b = output_recomputed + m; mpq_t& f = temp_q; for(int i = 0; i < m; i++) { mpq_set(a[i], input_q[i]); mpq_set(b[i], input_q[i+m]); } for(int i = 0; i < L; i++) { exogenous_fAtMidpt(f, a, b); if (mpq_sgn(f) > 0) { for(int j = 0; j < m; j++) { mpq_add(b[j], a[j], b[j]); mpq_div_2exp(b[j], b[j], 1); } } else { for(int j = 0; j < m; j++) { mpq_add(a[j], a[j], b[j]); mpq_div_2exp(a[j], a[j], 1); } } } clear_scalar(temp_q); }
void bisect_sfdlProverExo::exogenous_fAtMidpt(mpq_t& f, mpq_t* a, mpq_t* b) { mpq_t t2; mpq_t t3; alloc_init_scalar(t2); alloc_init_scalar(t3); mpq_set_ui(f, 0, 1); int m = bisect_sfdl_cons::m; int rctr = 0; for(int i = 0; i < m; i++) { mpq_add(t2, a[i], b[i]); mpq_set_si(t3, bisect_sfdl_cons::fAtMidpt_FUNCTION_STATIC_RANDOM_INT[rctr++], 1); mpq_mul(t2, t3, t2); mpq_div_2exp(t2, t2, 1); mpq_add(f, f, t2); } for(int i = 0; i < m; i++) { for(int j = 0; j < m; j++) { mpq_add(t2, a[i], b[i]); mpq_add(t3, a[j], b[j]); mpq_mul(t2, t2, t3); mpq_set_si(t3, bisect_sfdl_cons::fAtMidpt_FUNCTION_STATIC_RANDOM_INT[rctr++], 1); mpq_mul(t2, t2, t3); mpq_div_2exp(t2, t2, 2); mpq_add(f, f, t2); } } mpq_clear(t2); mpq_clear(t3); }
void check_random () { gmp_randstate_ptr rands; mpz_t bs; unsigned long arg_size, size_range; mpq_t q, r; int i; mp_bitcnt_t shift; int reps = 10000; rands = RANDS; mpz_init (bs); mpq_init (q); mpq_init (r); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */ mpz_urandomb (bs, rands, size_range); arg_size = mpz_get_ui (bs); mpz_rrandomb (mpq_numref (q), rands, arg_size); do { mpz_urandomb (bs, rands, size_range); arg_size = mpz_get_ui (bs); mpz_rrandomb (mpq_denref (q), rands, arg_size); } while (mpz_sgn (mpq_denref (q)) == 0); /* We now have a random rational in q, albeit an unnormalised one. The lack of normalisation should not matter here, so let's save the time a gcd would require. */ mpz_urandomb (bs, rands, 32); shift = mpz_get_ui (bs) % 4096; mpq_mul_2exp (r, q, shift); if (mpq_cmp (r, q) < 0) { printf ("mpq_mul_2exp wrong on random\n"); abort (); } mpq_div_2exp (r, r, shift); if (mpq_cmp (r, q) != 0) { printf ("mpq_mul_2exp or mpq_div_2exp wrong on random\n"); abort (); } } mpq_clear (q); mpq_clear (r); mpz_clear (bs); }
static void _taylor_mpfr (gulong l, mpq_t q, mpfr_ptr res, mp_rnd_t rnd) { NcmBinSplit **bs_ptr = _ncm_mpsf_sbessel_get_bs (); NcmBinSplit *bs = *bs_ptr; _binsplit_spherical_bessel *data = (_binsplit_spherical_bessel *) bs->userdata; gulong n; data->l = l; mpq_mul (data->mq2_2, q, q); mpq_neg (data->mq2_2, data->mq2_2); mpq_div_2exp (data->mq2_2, data->mq2_2, 1); //mpfr_printf ("# Taylor %ld %Qd | %Qd\n", l, q, data->mq2_2); ncm_binsplit_eval_prec (bs, binsplit_spherical_bessel_taylor, 10, mpfr_get_prec (res)); //mpfr_printf ("# Taylor %ld %Qd | %Zd %Zd\n", l, q, bs->T, bs->Q); mpfr_set_q (res, q, rnd); mpfr_pow_ui (res, res, l, rnd); mpfr_mul_z (res, res, bs->T, rnd); mpfr_div_z (res, res, bs->Q, rnd); for (n = 1; n <= l; n++) mpfr_div_ui (res, res, 2L * n + 1, rnd); ncm_memory_pool_return (bs_ptr); return; }
/* Check various values 2^n and 1/2^n. */ void check_onebit (void) { static const long data[] = { -3*GMP_NUMB_BITS-1, -3*GMP_NUMB_BITS, -3*GMP_NUMB_BITS+1, -2*GMP_NUMB_BITS-1, -2*GMP_NUMB_BITS, -2*GMP_NUMB_BITS+1, -GMP_NUMB_BITS-1, -GMP_NUMB_BITS, -GMP_NUMB_BITS+1, -5, -2, -1, 0, 1, 2, 5, GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1, 2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1, 3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1, }; int i, neg; long exp, l; mpq_t q; double got, want; mpq_init (q); for (i = 0; i < numberof (data); i++) { exp = data[i]; mpq_set_ui (q, 1L, 1L); if (exp >= 0) mpq_mul_2exp (q, q, exp); else mpq_div_2exp (q, q, -exp); want = 1.0; for (l = 0; l < exp; l++) want *= 2.0; for (l = 0; l > exp; l--) want /= 2.0; for (neg = 0; neg <= 1; neg++) { if (neg) { mpq_neg (q, q); want = -want; } got = mpq_get_d (q); if (got != want) { printf ("mpq_get_d wrong on %s2**%ld\n", neg ? "-" : "", exp); mpq_trace (" q ", q); d_trace (" want ", want); d_trace (" got ", got); abort(); } } } mpq_clear (q); }
void Lib_Mpq_Div_2exp(MpqPtr x, MpqPtr y, uint32_t e) { mpq_div_2exp( (mpq_ptr) x, (mpq_ptr) y, e); }
static void _assympt_mpfr (gulong l, mpq_t q, mpfr_ptr res, mp_rnd_t rnd) { NcmBinSplit **bs_ptr = _ncm_mpsf_sbessel_get_bs (); NcmBinSplit *bs = *bs_ptr; _binsplit_spherical_bessel *data = (_binsplit_spherical_bessel *) bs->userdata; gulong prec = mpfr_get_prec (res); #define sin_x data->sin #define cos_x data->cos mpfr_set_prec (sin_x, prec); mpfr_set_prec (cos_x, prec); mpfr_set_q (res, q, rnd); mpfr_sin_cos (sin_x, cos_x, res, rnd); switch (l % 4) { case 0: break; case 1: mpfr_swap (sin_x, cos_x); mpfr_neg (sin_x, sin_x, rnd); break; case 2: mpfr_neg (sin_x, sin_x, rnd); mpfr_neg (cos_x, cos_x, rnd); break; case 3: mpfr_swap (sin_x, cos_x); mpfr_neg (cos_x, cos_x, rnd); break; } if (l > 0) { mpfr_mul_ui (cos_x, cos_x, l * (l + 1), rnd); mpfr_div (cos_x, cos_x, res, rnd); mpfr_div (cos_x, cos_x, res, rnd); mpfr_div_2ui (cos_x, cos_x, 1, rnd); } mpfr_div (sin_x, sin_x, res, rnd); data->l = l; mpq_inv (data->mq2_2, q); mpq_mul (data->mq2_2, data->mq2_2, data->mq2_2); mpq_neg (data->mq2_2, data->mq2_2); mpq_div_2exp (data->mq2_2, data->mq2_2, 2); data->sincos = 0; binsplit_spherical_bessel_assympt (bs, 0, (l + 1) / 2 + (l + 1) % 2); mpfr_mul_z (sin_x, sin_x, bs->T, rnd); mpfr_div_z (sin_x, sin_x, bs->Q, rnd); data->sincos = 1; if (l > 0) { binsplit_spherical_bessel_assympt (bs, 0, l / 2 + l % 2); mpfr_mul_z (cos_x, cos_x, bs->T, rnd); mpfr_div_z (cos_x, cos_x, bs->Q, rnd); mpfr_add (res, sin_x, cos_x, rnd); } else mpfr_set (res, sin_x, rnd); ncm_memory_pool_return (bs_ptr); return; }