示例#1
0
文件: hilbert.c 项目: blynn/pbc
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);
}
示例#2
0
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);
}
示例#3
0
文件: tgmpop.c 项目: mmanley/Antares
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);
}
示例#4
0
文件: linearity.c 项目: cjgeyer/rcdd
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;
}
示例#5
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;
}
示例#6
0
文件: depth.c 项目: hvds/seq
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 */
}
示例#7
0
Rational& Rational::operator-=(const Rational& rhs)
{
   mpq_sub(number, number, rhs.number);
   mpq_canonicalize(number);
   return *this;
}
示例#8
0
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;
}
示例#9
0
void div(Rational& res, const Rational& op1, const Rational& op2)
{
   mpq_div(res.number, op1.number, op2.number);
   mpq_canonicalize(res.number);
}
示例#10
0
void mult(Rational& res, const Rational& op1, const Rational& op2)
{
   mpq_mul(res.number, op1.number, op2.number);
   mpq_canonicalize(res.number);
}
示例#11
0
Rational::Rational(double val)
{
   mpq_init(number);
   mpq_set_d(number, val);
   mpq_canonicalize(number);
}
示例#12
0
Rational::Rational(int num, int den)
{
   mpq_init(number);
   mpq_set_si(number, num, den);
   mpq_canonicalize(number);
}
示例#13
0
文件: pp.c 项目: hvds/seq
/* 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);
}