Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qqbar: higher-degree guessing hack #20

Open
fredrik-johansson opened this issue Apr 6, 2021 · 1 comment
Open

qqbar: higher-degree guessing hack #20

fredrik-johansson opened this issue Apr 6, 2021 · 1 comment

Comments

@fredrik-johansson
Copy link
Collaborator

qqbar binary operations guess and check for a rational solution when the inputs have high degree. This could be generalized to higher degree guesses (2? 4?) when the inputs have high enough degree, as long as things don't slow down noticeably in the generic case.

@fredrik-johansson
Copy link
Collaborator Author

Simple attempt to guess high-degree results:

if (dx >= 8 && dy >= 8)
{
    slong d, bits, prec;
    acb_t z, z1, z2;
    qqbar_t q;
    int found = 0;

    d = n_gcd(qqbar_degree(x), qqbar_degree(y));
    bits = qqbar_height_bits(x) + qqbar_height_bits(y) + 5;
    prec = d * bits;

    acb_init(z);
    acb_init(z1);
    acb_init(z2);
    qqbar_init(q);

    qqbar_get_acb(z1, x, prec);
    qqbar_get_acb(z2, y, prec);

    if (op == 0)
        acb_add(z, z1, z2, prec);
    else if (op == 1)
        acb_sub(z, z1, z2, prec);
    else if (op == 2)
        acb_mul(z, z1, z2, prec);
    else
        acb_div(z, z1, z2, prec);

    if (qqbar_guess(q, z, d, bits, 0, prec))
    {
        fmpz_poly_t H, Q;

        fmpz_poly_init(H);
        fmpz_poly_init(Q);

        qqbar_fmpz_poly_composed_op(H, QQBAR_POLY(x), QQBAR_POLY(y), op);

        if (fmpz_poly_divides(Q, H, QQBAR_POLY(q)))
        {
            arb_fmpz_poly_evaluate_acb(z, Q, z, prec);
            if (!acb_contains_zero(z))
            {
                qqbar_swap(res, q);
                found = 1;
            }
        }

        fmpz_poly_clear(H);
        fmpz_poly_clear(Q);
    }

    acb_clear(z);
    acb_clear(z1);
    acb_clear(z2);
    qqbar_clear(q);

    printf("found [%ld, %ld : %ld, bits = %ld, prec = %ld] = %i   {%ld, %ld}\n", dx, dy, d, bits, prec, found, found * qqbar_degree(res), found * qqbar_height_bits(res));

    if (found)
        return;
}

This seems to slow things down, so it needs to be done much more selectively and/or cleverly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant