static void compute_pi(int prec) { //Chudnovsky brothers' Ramanujan formula //http://www.cs.uwaterloo.ca/~alopez-o/math-faq/mathtext/node12.html mpz_t k1, k2, k4, k5, d; unsigned int k3 = 640320; unsigned int k6 = 53360; mpz_t z0, z1, z2; mpq_t p, q; mpf_t f1; int toggle = 1; int n; //converges fast: each term gives over 47 bits int nlimit = prec / 47 + 1; mpz_init(k1); mpz_init(k2); mpz_init(k4); mpz_init(k5); mpz_init(d); mpz_init(z0); mpz_init(z1); mpz_init(z2); mpq_init(q); mpq_init(p); mpf_init(f1); mpz_set_str(k1, "545140134", 10); mpz_set_str(k2, "13591409", 10); mpz_set_str(k4, "100100025", 10); mpz_set_str(k5, "327843840", 10); mpz_mul(d, k4, k5); mpz_mul_2exp(d, d, 3); mpq_set_ui(p, 0, 1); for (n=0; n<nlimit; n++) { mpz_fac_ui(z0, 6*n); mpz_mul_ui(z1, k1, n); mpz_add(z1, z1, k2); mpz_mul(z0, z0, z1); mpz_fac_ui(z1, 3*n); mpz_fac_ui(z2, n); mpz_pow_ui(z2, z2, 3); mpz_mul(z1, z1, z2); mpz_pow_ui(z2, d, n); mpz_mul(z1, z1, z2); mpz_set(mpq_numref(q), z0); mpz_set(mpq_denref(q), z1); mpq_canonicalize(q); if (toggle) { mpq_add(p, p, q); } else { mpq_sub(p, p, q); } toggle = !toggle; } mpq_inv(q, p); mpz_mul_ui(mpq_numref(q), mpq_numref(q), k6); mpq_canonicalize(q); mpf_set_q(pi, q); mpf_sqrt_ui(f1, k3); mpf_mul(pi, pi, f1); //mpf_out_str(stdout, 0, 14 * nlimit, pi); //printf("\n"); mpz_clear(k1); mpz_clear(k2); mpz_clear(k4); mpz_clear(k5); mpz_clear(d); mpz_clear(z0); mpz_clear(z1); mpz_clear(z2); mpq_clear(q); mpq_clear(p); mpf_clear(f1); }
void check_monotonic (int argc, char **argv) { mpq_t a; mp_size_t size; int reps = 100; int i, j; double last_d, new_d; mpq_t qlast_d, qnew_d; mpq_t eps; if (argc == 2) reps = atoi (argv[1]); /* The idea here is to test the monotonousness of mpq_get_d by adding numbers to the numerator and denominator. */ mpq_init (a); mpq_init (eps); mpq_init (qlast_d); mpq_init (qnew_d); for (i = 0; i < reps; i++) { size = urandom () % SIZE - SIZE/2; mpz_random2 (mpq_numref (a), size); do { size = urandom () % SIZE - SIZE/2; mpz_random2 (mpq_denref (a), size); } while (mpz_cmp_ui (mpq_denref (a), 0) == 0); mpq_canonicalize (a); last_d = mpq_get_d (a); mpq_set_d (qlast_d, last_d); for (j = 0; j < 10; j++) { size = urandom () % EPSIZE + 1; mpz_random2 (mpq_numref (eps), size); size = urandom () % EPSIZE + 1; mpz_random2 (mpq_denref (eps), size); mpq_canonicalize (eps); mpq_add (a, a, eps); mpq_canonicalize (a); new_d = mpq_get_d (a); if (last_d > new_d) { printf ("\nERROR (test %d/%d): bad mpq_get_d results\n", i, j); printf ("last: %.16g\n", last_d); printf (" new: %.16g\n", new_d); dump (a); abort (); } mpq_set_d (qnew_d, new_d); MPQ_CHECK_FORMAT (qnew_d); if (mpq_cmp (qlast_d, qnew_d) > 0) { printf ("ERROR (test %d/%d): bad mpq_set_d results\n", i, j); printf ("last: %.16g\n", last_d); dump (qlast_d); printf (" new: %.16g\n", new_d); dump (qnew_d); abort (); } last_d = new_d; mpq_set (qlast_d, qnew_d); } } mpq_clear (a); mpq_clear (eps); mpq_clear (qlast_d); mpq_clear (qnew_d); }
static void test_genericq (mp_prec_t p0, mp_prec_t p1, unsigned int N, int (*func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t), const char *op) { mp_prec_t prec; mpfr_t arg1, dst_big, dst_small, tmp; mpq_t arg2; mp_rnd_t rnd; int inexact, compare, compare2; unsigned int n; mpfr_inits (arg1, dst_big, dst_small, tmp, (void *) 0); mpq_init (arg2); for (prec = p0; prec <= p1; prec++) { mpfr_set_prec (arg1, prec); mpfr_set_prec (tmp, prec); mpfr_set_prec (dst_small, prec); for (n=0; n<N; n++) { mpfr_urandomb (arg1, RANDS); mpq_set_ui (arg2, randlimb (), randlimb() ); mpq_canonicalize (arg2); rnd = (mp_rnd_t) RND_RAND (); mpfr_set_prec (dst_big, prec+10); compare = func(dst_big, arg1, arg2, rnd); if (mpfr_can_round (dst_big, prec+10, rnd, rnd, prec)) { mpfr_set (tmp, dst_big, rnd); inexact = func(dst_small, arg1, arg2, rnd); if (mpfr_cmp (tmp, dst_small)) { printf ("Results differ for prec=%u rnd_mode=%s and %s_q:\n" "arg1=", (unsigned) prec, mpfr_print_rnd_mode (rnd), op); mpfr_print_binary (arg1); printf("\narg2="); mpq_out_str(stdout, 2, arg2); printf ("\ngot "); mpfr_print_binary (dst_small); printf ("\nexpected "); mpfr_print_binary (tmp); printf ("\napprox "); mpfr_print_binary (dst_big); putchar('\n'); exit (1); } compare2 = mpfr_cmp (tmp, dst_big); /* if rounding to nearest, cannot know the sign of t - f(x) because of composed rounding: y = o(f(x)) and t = o(y) */ if (compare * compare2 >= 0) compare = compare + compare2; else compare = inexact; /* cannot determine sign(t-f(x)) */ if (((inexact == 0) && (compare != 0)) || ((inexact > 0) && (compare <= 0)) || ((inexact < 0) && (compare >= 0))) { printf ("Wrong inexact flag for rnd=%s and %s_q:\n" "expected %d, got %d", mpfr_print_rnd_mode (rnd), op, compare, inexact); printf ("\narg1="); mpfr_print_binary (arg1); printf ("\narg2="); mpq_out_str(stdout, 2, arg2); printf ("\ndstl="); mpfr_print_binary (dst_big); printf ("\ndsts="); mpfr_print_binary (dst_small); printf ("\ntmp ="); mpfr_print_binary (tmp); putchar('\n'); exit (1); } } } } mpq_clear (arg2); mpfr_clears (arg1, dst_big, dst_small, tmp, (void *) 0); }
SEXP impliedLinearity(SEXP m, SEXP h) { GetRNGstate(); if (! isMatrix(m)) error("'m' must be matrix"); if (! isLogical(h)) error("'h' must be logical"); if (LENGTH(h) != 1) error("'h' must be scalar"); if (! isString(m)) error("'m' must be character"); SEXP m_dim; PROTECT(m_dim = getAttrib(m, R_DimSymbol)); int nrow = INTEGER(m_dim)[0]; int ncol = INTEGER(m_dim)[1]; UNPROTECT(1); if (nrow <= 1) error("no use if only one row"); if (ncol <= 3) error("no use if only one col"); for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column one of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column one of 'm' not zero-or-one valued"); } if (! LOGICAL(h)[0]) for (int i = nrow; i < 2 * nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column two of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column two of 'm' not zero-or-one valued"); } dd_set_global_constants(); /* note actual type of "value" is mpq_t (defined in cddmp.h) */ mytype value; dd_init(value); dd_MatrixPtr mf = dd_CreateMatrix(nrow, ncol - 1); /* note our matrix has one more column than Fukuda's */ /* representation */ if(LOGICAL(h)[0]) mf->representation = dd_Inequality; else mf->representation = dd_Generator; mf->numbtype = dd_Rational; /* linearity */ for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (foo[0] == '1') set_addelem(mf->linset, i + 1); /* note conversion from zero-origin to one-origin indexing */ } /* matrix */ for (int j = 1, k = nrow; j < ncol; j++) for (int i = 0; i < nrow; i++, k++) { const char *rat_str = CHAR(STRING_ELT(m, k)); if (mpq_set_str(value, rat_str, 10) == -1) { dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); error("error converting string to GMP rational"); } mpq_canonicalize(value); dd_set(mf->matrix[i][j - 1], value); /* note our matrix has one more column than Fukuda's */ } dd_ErrorType err = dd_NoError; dd_rowset out = dd_ImplicitLinearityRows(mf, &err); if (err != dd_NoError) { rr_WriteErrorMessages(err); set_free(out); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); error("failed"); } SEXP foo; PROTECT(foo = rr_set_fwrite(out)); set_free(out); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); PutRNGstate(); UNPROTECT(1); return foo; }
int main(void) { int i, result; ulong cflags = UWORD(0); FLINT_TEST_INIT(state); flint_printf("scalar_div_mpq...."); fflush(stdout); /* Check aliasing of a and b */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpq_poly_t a, b; fmpz_t r, s; mpq_t z; mpq_init(z); fmpz_init(r); fmpz_init(s); fmpz_randtest_not_zero(r, state, 100); fmpz_randtest_not_zero(s, state, 100); fmpz_get_mpz(mpq_numref(z), r); fmpz_get_mpz(mpq_denref(z), s); mpq_canonicalize(z); fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_randtest(a, state, n_randint(state, 100), 200); fmpq_poly_scalar_div_mpq(b, a, z); fmpq_poly_scalar_div_mpq(a, a, z); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; result = (fmpq_poly_equal(a, b) && !cflags); if (!result) { flint_printf("FAIL (aliasing):\n\n"); fmpq_poly_debug(a), flint_printf("\n\n"); fmpq_poly_debug(b), flint_printf("\n\n"); gmp_printf("z = %Qd\n\n", z); flint_printf("cflags = %wu\n\n", cflags); abort(); } mpq_clear(z); fmpz_clear(r); fmpz_clear(s); fmpq_poly_clear(a); fmpq_poly_clear(b); } /* Check that (a / n1) / n2 == a / (n1 * n2) */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpq_poly_t a, lhs, rhs; fmpz_t r, s; mpq_t z1, z2, z; fmpz_init(r); fmpz_init(s); mpq_init(z1); mpq_init(z2); mpq_init(z); fmpz_randtest_not_zero(r, state, 100); fmpz_randtest_not_zero(s, state, 100); fmpz_get_mpz(mpq_numref(z1), r); fmpz_get_mpz(mpq_denref(z1), s); mpq_canonicalize(z1); fmpz_randtest_not_zero(r, state, 100); fmpz_randtest_not_zero(s, state, 100); fmpz_get_mpz(mpq_numref(z2), r); fmpz_get_mpz(mpq_denref(z2), s); mpq_canonicalize(z2); mpq_mul(z, z1, z2); fmpq_poly_init(a); fmpq_poly_init(lhs); fmpq_poly_init(rhs); fmpq_poly_randtest(a, state, n_randint(state, 100), 200); fmpq_poly_scalar_div_mpq(lhs, a, z1); fmpq_poly_scalar_div_mpq(lhs, lhs, z2); fmpq_poly_scalar_div_mpq(rhs, a, z); cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; result = (fmpq_poly_equal(lhs, rhs) && !cflags); if (!result) { flint_printf("FAIL (a / n1 / n2):\n"); fmpq_poly_debug(a), flint_printf("\n\n"); gmp_printf("z1 = %Qd\n\n", z1); gmp_printf("z2 = %Qd\n\n", z2); gmp_printf("z = %Qd\n\n", z); fmpq_poly_debug(lhs), flint_printf("\n\n"); fmpq_poly_debug(rhs), flint_printf("\n\n"); flint_printf("cflags = %wu\n\n", cflags); abort(); } mpq_clear(z1); mpq_clear(z2); mpq_clear(z); fmpz_clear(r); fmpz_clear(s); fmpq_poly_clear(a); fmpq_poly_clear(lhs); fmpq_poly_clear(rhs); } /* Check that (a + b) / n == a/n + b/n */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpq_poly_t a, b, lhs, rhs; fmpz_t r, s; mpq_t z; fmpz_init(r); fmpz_init(s); mpq_init(z); fmpz_randtest_not_zero(r, state, 100); fmpz_randtest_not_zero(s, state, 100); fmpz_get_mpz(mpq_numref(z), r); fmpz_get_mpz(mpq_denref(z), s); mpq_canonicalize(z); fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(lhs); fmpq_poly_init(rhs); fmpq_poly_randtest(a, state, n_randint(state, 100), 200); fmpq_poly_randtest(b, state, n_randint(state, 100), 200); fmpq_poly_scalar_div_mpq(lhs, a, z); fmpq_poly_scalar_div_mpq(rhs, b, z); fmpq_poly_add(rhs, lhs, rhs); fmpq_poly_add(lhs, a, b); fmpq_poly_scalar_div_mpq(lhs, lhs, z); cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; result = (fmpq_poly_equal(lhs, rhs) && !cflags); if (!result) { flint_printf("FAIL ((a + b) / n):\n"); fmpq_poly_debug(a), flint_printf("\n\n"); fmpq_poly_debug(b), flint_printf("\n\n"); gmp_printf("z = %Qd\n\n", z); fmpq_poly_debug(lhs), flint_printf("\n\n"); fmpq_poly_debug(rhs), flint_printf("\n\n"); flint_printf("cflags = %wu\n\n", cflags); abort(); } mpq_clear(z); fmpz_clear(r); fmpz_clear(s); fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(lhs); fmpq_poly_clear(rhs); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
bool try_depth(ulong depth) { frame_t *cur = &(stack[depth]); frame_t *next = &(stack[depth + 1]); int final = (depth + 1 >= max_depth) ? 1 : 0; bool locally_solved = 0; ulong bits_num, bits_den; ++count; if ((count & 0xfffffff) == 0) report_progress(depth); mpq_inv(next->q, cur->q); /* if final, we only care whether we can reach 1 */ if (final) { mpq_sub(next->q, next->q, rone); if (mpq_sgn(next->q) < 0) return 0; mpq_div(next->q, next->q, r); if (mpz_cmp_ui(mpq_denref(next->q), (ulong)1) != 0) return 0; next->count = mpz_strict_get_ui(mpq_numref(next->q)); report_depth(depth + 1); return 1; } if (mpq_cmp(next->q, limit) <= 0) { next->count = (ulong)0; } else { /* count = floor((q - limit) / r) */ mpq_sub(limit_calc, next->q, limit); mpq_div(limit_calc, limit_calc, r); mpz_fdiv_q(limit_div, mpq_numref(limit_calc), mpq_denref(limit_calc)); next->count = mpz_strict_get_ui(limit_div); /* q -= count * r */ mpq_set(limit_calc, r); mpz_mul_ui(mpq_numref(limit_calc), mpq_numref(limit_calc), next->count); mpq_canonicalize(limit_calc); mpq_sub(next->q, next->q, limit_calc); } /* now we've guaranteed curq - r <= limit, so all values we find are * useful. */ /* while ((q -= r) > 0) { ... } */ while (1) { mpq_sub(next->q, next->q, r); if (mpq_sgn(next->q) <= 0) return locally_solved; ++next->count; if (mpq_equal(next->q, rone)) { report_depth(depth + 1); max_depth = depth + 1; solved = 1; return 1; } ++next->actual; bits_num = mpz_bitsize(mpq_numref(next->q)); if (!next->best_bits_num || next->best_bits_num >= bits_num) { next->best_bits_num = bits_num; bits_den = mpz_bitsize(mpq_denref(next->q)); if (!next->best_bits_den || next->best_bits_den > bits_den) next->best_bits_den = bits_den; } /* and recurse */ if (try_depth(depth + 1)) locally_solved = 1; } /* not reached */ }
Rational& Rational::operator-=(const Rational& rhs) { mpq_sub(number, number, rhs.number); mpq_canonicalize(number); return *this; }
static PyObject * Pympq_round(PyObject *self, PyObject *args) { Py_ssize_t round_digits = 0; PympqObject *resultq; PympzObject *resultz; mpz_t temp, rem; /* If args is NULL or the size of args is 0, we just return an mpz. */ if (!args || PyTuple_GET_SIZE(args) == 0) { if (!(resultz = (PympzObject*)Pympz_new())) return NULL; mpz_inoc(rem); mpz_fdiv_qr(resultz->z, rem, mpq_numref(Pympq_AS_MPQ(self)), mpq_denref(Pympq_AS_MPQ(self))); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) > 0) { mpz_add_ui(resultz->z, resultz->z, 1); } else if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) == 0) { if (mpz_odd_p(resultz->z)) { mpz_add_ui(resultz->z, resultz->z, 1); } } mpz_cloc(rem); return (PyObject*)resultz; } if (PyTuple_GET_SIZE(args) > 1) { TYPE_ERROR("Too many arguments for __round__()."); return NULL; } if (PyTuple_GET_SIZE(args) == 1) { round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } } if (!(resultq = (PympqObject*)Pympq_new())) return NULL; mpz_inoc(temp); mpz_ui_pow_ui(temp, 10, round_digits > 0 ? round_digits : -round_digits); mpq_set(resultq->q, Pympq_AS_MPQ(self)); if (round_digits > 0) { mpz_mul(mpq_numref(resultq->q), mpq_numref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) { mpz_cloc(temp); return NULL; } mpz_set(mpq_numref(resultq->q), resultz->z); Py_DECREF((PyObject*)resultz); mpz_set(mpq_denref(resultq->q), temp); mpz_cloc(temp); mpq_canonicalize(resultq->q); } else { mpz_mul(mpq_denref(resultq->q), mpq_denref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) { mpz_cloc(temp); return NULL; } mpq_set_ui(resultq->q, 0, 1); mpz_mul(mpq_numref(resultq->q), resultz->z, temp); Py_DECREF((PyObject*)resultz); mpz_cloc(temp); mpq_canonicalize(resultq->q); } return (PyObject*)resultq; }
void div(Rational& res, const Rational& op1, const Rational& op2) { mpq_div(res.number, op1.number, op2.number); mpq_canonicalize(res.number); }
void mult(Rational& res, const Rational& op1, const Rational& op2) { mpq_mul(res.number, op1.number, op2.number); mpq_canonicalize(res.number); }
Rational::Rational(double val) { mpq_init(number); mpq_set_d(number, val); mpq_canonicalize(number); }
Rational::Rational(int num, int den) { mpq_init(number); mpq_set_si(number, num, den); mpq_canonicalize(number); }
/* A surprising omission from the exported mpq_* functions */ static inline void mpq_mul_z(mpq_t dest, mpq_t src1, mpz_t src2) { mpz_mul(mpq_numref(dest), mpq_numref(src1), src2); if (&dest != &src1) mpz_set(mpq_denref(dest), mpq_denref(src1)); mpq_canonicalize(dest); }