inline Mtbdd readMPQAttribute(const TiXmlNode* node, const char* att) { const std::string numberString = readStringAttribute(node, att); mpq_t gmp_value; mpq_init(gmp_value); try { size_t pos = 0; if ((pos = numberString.find('.')) != std::string::npos) { mpf_t f_value; mpf_init(f_value); mpf_set_str(f_value, numberString.c_str(), 10); mpq_set_f(gmp_value, f_value); mpf_clear(f_value); } else { mpq_set_str(gmp_value, numberString.c_str(), 10); } if (mpq_sgn(gmp_value) == 0) { mpq_clear(gmp_value); return mtbdd_false; } MTBDD res = mtbdd_gmp(gmp_value); mpq_clear(gmp_value); return res; } catch(boost::bad_lexical_cast&) { throw ParseError("[ERROR] String " + numberString + " is not a number"); } }
void fmpq_poly_sample_D1(fmpq_poly_t f, int n, mpfr_prec_t prec, gmp_randstate_t state) { mpfr_t u1; mpfr_init2(u1, prec); mpfr_t u2; mpfr_init2(u2, prec); mpfr_t z1; mpfr_init2(z1, prec); mpfr_t z2; mpfr_init2(z2, prec); mpfr_t pi2; mpfr_init2(pi2, prec); mpfr_const_pi(pi2, MPFR_RNDN); mpfr_mul_si(pi2, pi2, 2, MPFR_RNDN); mpf_t tmp_f; mpq_t tmp_q; mpf_init(tmp_f); mpq_init(tmp_q); assert(n%2==0); for(long i=0; i<n; i+=2) { mpfr_urandomb(u1, state); mpfr_urandomb(u2, state); mpfr_log(u1, u1, MPFR_RNDN); mpfr_mul_si(u1, u1, -2, MPFR_RNDN); mpfr_sqrt(u1, u1, MPFR_RNDN); mpfr_mul(u2, pi2, u2, MPFR_RNDN); mpfr_cos(z1, u2, MPFR_RNDN); mpfr_mul(z1, z1, u1, MPFR_RNDN); //z1 = sqrt(-2*log(u1)) * cos(2*pi*u2) mpfr_sin(z2, u2, MPFR_RNDN); mpfr_mul(z2, z2, u1, MPFR_RNDN); //z1 = sqrt(-2*log(u1)) * sin(2*pi*U2) mpfr_get_f(tmp_f, z1, MPFR_RNDN); mpq_set_f(tmp_q, tmp_f); fmpq_poly_set_coeff_mpq(f, i, tmp_q); mpfr_get_f(tmp_f, z2, MPFR_RNDN); mpq_set_f(tmp_q, tmp_f); fmpq_poly_set_coeff_mpq(f, i+1, tmp_q); } mpf_clear(tmp_f); mpq_clear(tmp_q); mpfr_clear(pi2); mpfr_clear(u1); mpfr_clear(u2); mpfr_clear(z1); mpfr_clear(z2); }
int main (int argc, char **argv) { #if GMP_NAIL_BITS == 0 static const struct { int f_base; const char *f; int z_base; const char *want_num; const char *want_den; } data[] = { { -2, "0", 16, "0", "1" }, { -2, "1", 16, "1", "1" }, { -2, "1@1", 16, "2", "1" }, { -2, "1@2", 16, "4", "1" }, { -2, "1@3", 16, "8", "1" }, { -2, "1@30", 16, "40000000", "1" }, { -2, "1@31", 16, "80000000", "1" }, { -2, "1@32", 16, "100000000", "1" }, { -2, "1@33", 16, "200000000", "1" }, { -2, "1@34", 16, "400000000", "1" }, { -2, "1@62", 16, "4000000000000000", "1" }, { -2, "1@63", 16, "8000000000000000", "1" }, { -2, "1@64", 16, "10000000000000000", "1" }, { -2, "1@65", 16, "20000000000000000", "1" }, { -2, "1@66", 16, "40000000000000000", "1" }, { -2, "1@126", 16, "40000000000000000000000000000000", "1" }, { -2, "1@127", 16, "80000000000000000000000000000000", "1" }, { -2, "1@128", 16, "100000000000000000000000000000000", "1" }, { -2, "1@129", 16, "200000000000000000000000000000000", "1" }, { -2, "1@130", 16, "400000000000000000000000000000000", "1" }, { -2, "1@-1", 16, "1", "2" }, { -2, "1@-2", 16, "1", "4" }, { -2, "1@-3", 16, "1", "8" }, { -2, "1@-30", 16, "1", "40000000" }, { -2, "1@-31", 16, "1", "80000000" }, { -2, "1@-32", 16, "1", "100000000" }, { -2, "1@-33", 16, "1", "200000000" }, { -2, "1@-34", 16, "1", "400000000" }, { -2, "1@-62", 16, "1", "4000000000000000" }, { -2, "1@-63", 16, "1", "8000000000000000" }, { -2, "1@-64", 16, "1", "10000000000000000" }, { -2, "1@-65", 16, "1", "20000000000000000" }, { -2, "1@-66", 16, "1", "40000000000000000" }, { -2, "1@-126", 16, "1", "40000000000000000000000000000000" }, { -2, "1@-127", 16, "1", "80000000000000000000000000000000" }, { -2, "1@-128", 16, "1", "100000000000000000000000000000000" }, { -2, "1@-129", 16, "1", "200000000000000000000000000000000" }, { -2, "1@-130", 16, "1", "400000000000000000000000000000000" }, { -2, "1@-30", 16, "1", "40000000" }, { -2, "1@-31", 16, "1", "80000000" }, { -2, "1@-32", 16, "1", "100000000" }, { -2, "1@-33", 16, "1", "200000000" }, { -2, "1@-34", 16, "1", "400000000" }, { -2, "11@-62", 16, "3", "4000000000000000" }, { -2, "11@-63", 16, "3", "8000000000000000" }, { -2, "11@-64", 16, "3", "10000000000000000" }, { -2, "11@-65", 16, "3", "20000000000000000" }, { -2, "11@-66", 16, "3", "40000000000000000" }, { 16, "80000000.00000001", 16, "8000000000000001", "100000000" }, { 16, "80000000.00000008", 16, "1000000000000001", "20000000" }, { 16, "80000000.8", 16, "100000001", "2" }, }; mpf_t f; mpq_t got; mpz_t want_num, want_den; int i, neg; tests_start (); mpf_init2 (f, 1024L); mpq_init (got); mpz_init (want_num); mpz_init (want_den); for (i = 0; i < numberof (data); i++) { for (neg = 0; neg <= 1; neg++) { mpf_set_str_or_abort (f, data[i].f, data[i].f_base); mpz_set_str_or_abort (want_num, data[i].want_num, data[i].z_base); mpz_set_str_or_abort (want_den, data[i].want_den, data[i].z_base); if (neg) { mpf_neg (f, f); mpz_neg (want_num, want_num); } mpq_set_f (got, f); MPQ_CHECK_FORMAT (got); if (mpz_cmp (mpq_numref(got), want_num) != 0 || mpz_cmp (mpq_denref(got), want_den) != 0) { printf ("wrong at data[%d]\n", i); printf (" f_base %d, z_base %d\n", data[i].f_base, data[i].z_base); printf (" f \"%s\" hex ", data[i].f); mpf_out_str (stdout, 16, 0, f); printf ("\n"); printf (" want num 0x"); mpz_out_str (stdout, 16, want_num); printf ("\n"); printf (" want den 0x"); mpz_out_str (stdout, 16, want_den); printf ("\n"); printf (" got num 0x"); mpz_out_str (stdout, 16, mpq_numref(got)); printf ("\n"); printf (" got den 0x"); mpz_out_str (stdout, 16, mpq_denref(got)); printf ("\n"); abort (); } } } mpf_clear (f); mpq_clear (got); mpz_clear (want_num); mpz_clear (want_den); tests_end (); #endif exit (0); }
int sqrt_upper(mpq_t sqrt_x, mpq_t x, int digits) /***************************************************************\ * USAGE: compute a certified rational upper bound on the sqrt(x)* * that is within 10^-digits of the true value 0-good,1-error * \***************************************************************/ { int rV = 0, sign = mpq_sgn(x); // verify digits >= 0 if (digits < 0) { // error printf("ERROR: The number of digits must be nonnegative!\n"); errExit(ERROR_CONFIGURATION); } // check the sign of x if (sign == -1) { // x is negative - return error rV = 1; } else if (sign == 0) { // x is zero - sqrt(x) = 0 mpq_set_ui(sqrt_x, 0, 1); rV = 0; } else { // x is positive - compute sqrt(x) int prec; mpfr_t sqrt_x_float; mpf_t tempMPF; mpq_t sqrt_x_temp, tempMPQ; // determine the precision to use to get an approximation if (digits <= 16) prec = 64; else { // determine the precision needed prec = (int) ceil((digits + 0.5) / (32 * log10(2.0))); if (prec <= 2) prec = 64; else prec *= 32; } // initialize mpfr_init2(sqrt_x_float, prec); mpf_init2(tempMPF, prec); mpq_init(sqrt_x_temp); mpq_init(tempMPQ); // approximate sqrt(x) - round up! mpfr_set_q(sqrt_x_float, x, GMP_RNDU); mpfr_sqrt(sqrt_x_float, sqrt_x_float, GMP_RNDU); // convert to rational mpfr_get_f(tempMPF, sqrt_x_float, GMP_RNDU); mpq_set_f(sqrt_x_temp, tempMPF); // verify that sqrt_x_temp is an upper bound mpq_mul(tempMPQ, sqrt_x_temp, sqrt_x_temp); if (mpq_cmp(tempMPQ, x) >= 0) { // we have an upper bound - refine & certify it refine_sqrt_upper(sqrt_x_temp, x, digits); // copy to sqrt_x mpq_set(sqrt_x, sqrt_x_temp); rV = 0; } else { // try again with 2*x (Newton iterations still converge quadratically!) mpq_add(tempMPQ, x, x); mpfr_set_q(sqrt_x_float, tempMPQ, GMP_RNDU); mpfr_sqrt(sqrt_x_float, sqrt_x_float, GMP_RNDU); // convert to rational mpfr_get_f(tempMPF, sqrt_x_float, GMP_RNDU); mpq_set_f(sqrt_x_temp, tempMPF); // verify that sqrt_x_temp is an upper bound mpq_mul(tempMPQ, sqrt_x_temp, sqrt_x_temp); if (mpq_cmp(tempMPQ, x) >= 0) { // we have an upper bound - refine & certify it refine_sqrt_upper(sqrt_x_temp, x, digits); // copy to sqrt_x mpq_set(sqrt_x, sqrt_x_temp); rV = 0; } else { // take any upper bound if (mpq_cmp_ui(x, 1, 1) <= 0) { // 1 is an upper bound for sqrt(x) mpq_set_ui(sqrt_x_temp, 1, 1); } else { // x is an upper bound for sqrt(x) mpq_set(sqrt_x_temp, x); } // we have an upper bound - refine & certify it refine_sqrt_upper(sqrt_x_temp, x, digits); // copy to sqrt_x mpq_set(sqrt_x, sqrt_x_temp); rV = 0; } } // clear mpfr_clear(sqrt_x_float); mpf_clear(tempMPF); mpq_clear(sqrt_x_temp); mpq_clear(tempMPQ); } return rV; }