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; }
static PyObject * GMPy_Real_DivMod_2(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *quo = NULL, *rem = NULL; PyObject *result; CHECK_CONTEXT(context); if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPFR_New(0, context)) || !(quo = GMPy_MPFR_New(0, context)) ) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)quo); Py_XDECREF((PyObject*)rem); return NULL; } if (IS_REAL(x) && IS_REAL(y)) { if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context)) ) { goto error; } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("divmod() division by zero"); goto error; } } if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } else { mpfr_set_nan(quo->f); mpfr_set_nan(rem->f); } } else if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } if (mpfr_zero_p(tempx->f)) { mpfr_set_zero(quo->f, mpfr_sgn(tempy->f)); mpfr_set_zero(rem->f, mpfr_sgn(tempy->f)); } else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) { mpfr_set_si(quo->f, -1, MPFR_RNDN); mpfr_set_inf(rem->f, mpfr_sgn(tempy->f)); } else { mpfr_set_si(quo->f, 0, MPFR_RNDN); rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN); } } else { MPQ_Object *mpqx = NULL, *mpqy = NULL, *temp_rem = NULL; MPZ_Object *temp_quo = NULL; if (!(mpqx = GMPy_MPQ_From_MPFR(tempx, context)) || !(mpqy = GMPy_MPQ_From_MPFR(tempy, context)) ) { Py_XDECREF((PyObject*)mpqx); Py_XDECREF((PyObject*)mpqy); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF(result); return NULL; } Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); temp_rem = GMPy_MPQ_New(context); temp_quo = GMPy_MPZ_New(context); if (!(temp_rem = GMPy_MPQ_New(context)) || !(temp_quo = GMPy_MPZ_New(context)) ) { Py_XDECREF((PyObject*)temp_rem); Py_XDECREF((PyObject*)temp_quo); Py_DECREF((PyObject*)mpqx); Py_DECREF((PyObject*)mpqy); Py_DECREF(result); return NULL; } mpq_div(temp_rem->q, mpqx->q, mpqy->q); mpz_fdiv_q(temp_quo->z, mpq_numref(temp_rem->q), mpq_denref(temp_rem->q)); /* Need to calculate x - quo * y. */ mpq_set_z(temp_rem->q, temp_quo->z); mpq_mul(temp_rem->q, temp_rem->q, mpqy->q); mpq_sub(temp_rem->q, mpqx->q, temp_rem->q); Py_DECREF((PyObject*)mpqx); Py_DECREF((PyObject*)mpqy); quo->rc = mpfr_set_z(quo->f, temp_quo->z, MPFR_RNDD); rem->rc = mpfr_set_q(rem->f, temp_rem->q, MPFR_RNDN); Py_DECREF((PyObject*)temp_rem); Py_DECREF((PyObject*)temp_quo); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); Py_RETURN_NOTIMPLEMENTED; error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; }
void Lib_Mpq_Mul_Si64(MpqPtr res, MpqPtr x, int64_t y) { mpq_t q; mpq_init(q); Lib_Mpq_Set_Si64(q, y); mpq_mul( (mpq_ptr) res, (mpq_ptr) x, q); mpq_clear(q); }
ring_elem QQ::mult(const ring_elem f, const ring_elem g) const { gmp_QQ result = QQ::new_elem(); mpq_mul(result, MPQ_VAL(f), MPQ_VAL(g)); return MPQ_RINGELEM(result); }
void Lib_Mpq_Mul_Ui(MpqPtr res, MpqPtr x, uint32_t y) { mpq_t q; mpq_init(q); Lib_Mpq_Set_Ui(q, y); mpq_mul( (mpq_ptr) res, (mpq_ptr) x, q); mpq_clear(q); }
void Lib_Mpq_Mul(MpqPtr res, MpqPtr x, MpqPtr y) { mpq_mul( (mpq_ptr) res, (mpq_ptr) x, (mpq_ptr) y); }
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; }
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; }
void mult(Rational& res, const Rational& op1, const Rational& op2) { mpq_mul(res.number, op1.number, op2.number); mpq_canonicalize(res.number); }