示例#1
0
文件: sqrt.c 项目: aliddell/cadenza
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;
}
示例#2
0
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;
}
示例#3
0
文件: UseMpq.cpp 项目: duhadler/C
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);
}
示例#4
0
文件: QQ.cpp 项目: ChristineJost/M2
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);
}
示例#5
0
文件: UseMpq.cpp 项目: duhadler/C
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);
}
示例#6
0
文件: UseMpq.cpp 项目: duhadler/C
void Lib_Mpq_Mul(MpqPtr res, MpqPtr x, MpqPtr y)
{
    mpq_mul( (mpq_ptr) res,  (mpq_ptr) x,  (mpq_ptr) y);
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
void mult(Rational& res, const Rational& op1, const Rational& op2)
{
   mpq_mul(res.number, op1.number, op2.number);
   mpq_canonicalize(res.number);
}