Пример #1
0
void
mag_rfac_ui(mag_t z, ulong n)
{
    if (n < MAG_FAC_TABLE_NUM)
    {
        _fmpz_demote(MAG_EXPREF(z));
        MAG_EXP(z) = mag_rfac_tab[n * 2];
        MAG_MAN(z) = mag_rfac_tab[n * 2 + 1];
    }
    else
    {
        double x = n;

        x = ceil((((x+0.5)*mag_d_log_lower_bound(x) - x) * 1.4426950408889634074) * -0.9999999);

        /* x + 1 could round down for huge x, but this doesn't matter
           as long as the value was perturbed up above */
        fmpz_set_d(MAG_EXPREF(z), x + 1);
        MAG_MAN(z) = MAG_ONE_HALF;
    }
}
Пример #2
0
void
dedekind_sum_coprime(fmpq_t s, const fmpz_t h, const fmpz_t k)
{
    if (fmpz_cmp_ui(k, DOUBLE_CUTOFF) < 0)
    {
        double t;

        t = dedekind_sum_coprime_d(*h, *k) * (6 * (*k));

        /* Round to nearest after truncation */
        if (t > 0)
            t += 0.5;
        else
            t -= 0.5;

        fmpz_set_d(fmpq_numref(s), t);
        fmpz_set_ui(fmpq_denref(s), 6UL * (*k));
        fmpq_canonicalise(s);
    }
    else
    {
        dedekind_sum_coprime_large(s, h, k);
    }
}
void
acb_modular_fundamental_domain_approx_d(psl2z_t g,
    double x, double y, double one_minus_eps)
{
    double a, b, c, d, aa, bb, t;
    int i;

    a = d = 1;
    b = c = 0;

    for (i = 0; i < 20; i++)
    {
        if (!d_is_ok(x) || !d_is_ok(y) || !(y > 0.0))
        {
            psl2z_one(g);
            return;
        }

        /* shift */
        if (x < -0.5 || x > 0.5)
        {
            t = floor(x + 0.5);
            x -= t;
            a -= t * c;
            b -= t * d;

            /* too large to guarantee exactness */
            if (!d_is_ok(a) || !d_is_ok(b))
            {
                psl2z_one(g);
                return;
            }

            continue;
        }

        t = x*x + y*y;

        /* can't divide by a too small number */
        if (t < 1e-30)
        {
            psl2z_one(g);
            break;
        }

        /* inversion */
        if (t < one_minus_eps)
        {
            t = 1.0 / t;
            x *= -t;
            y *= t;
            aa = a;
            bb = b;
            a = -c;
            b = -d;
            c = aa;
            d = bb;
            continue;
        }

        /* we're good */
        break;
    }

    if (c < 0 || (c == 0 && d < 0))
    {
        a = -a;
        b = -b;
        c = -c;
        d = -d;
    }

    fmpz_set_d(&g->a, a);
    fmpz_set_d(&g->b, b);
    fmpz_set_d(&g->c, c);
    fmpz_set_d(&g->d, d);
}