Beispiel #1
0
void
fmpz_poly_mul_karatsuba(fmpz_poly_t res,
                        const fmpz_poly_t poly1, const fmpz_poly_t poly2)
{
    long len_out;

    if ((poly1->length == 0) || (poly2->length == 0))
    {
        fmpz_poly_zero(res);
        return;
    }

    len_out = poly1->length + poly2->length - 1;

    fmpz_poly_fit_length(res, len_out);

    if (poly1->length >= poly2->length)
        _fmpz_poly_mul_karatsuba(res->coeffs, poly1->coeffs, poly1->length,
                                 poly2->coeffs, poly2->length);
    else
        _fmpz_poly_mul_karatsuba(res->coeffs, poly2->coeffs, poly2->length,
                                 poly1->coeffs, poly1->length);

    _fmpz_poly_set_length(res, len_out);
}
Beispiel #2
0
void target(void* y, unsigned long count)
{
    arg_t* arg = (arg_t*) y;

    mpz_t x;
    mpz_init(x);

    mpz_poly_t in1, in2, out;
    mpz_poly_init(in1);
    mpz_poly_init(in2);
    mpz_poly_init(out);

    fmpz_poly_t in1f, in2f, outf;
    fmpz_poly_init2(in1f, arg->length1, (arg->bits1-1)/FLINT_BITS+1);
    fmpz_poly_init2(in2f, arg->length2, (arg->bits2-1)/FLINT_BITS+1);
    _fmpz_poly_stack_init(outf, arg->length1 + arg->length2 - 1,
                          in1f->limbs + in2f->limbs + 1);

    for (unsigned long i = 0; i < arg->length1; i++)
    {
        mpz_urandomb(x, randstate, arg->bits1);
        mpz_poly_set_coeff(in1, i, x);
    }
    mpz_poly_to_fmpz_poly(in1f, in1);

    for (unsigned long i = 0; i < arg->length2; i++)
    {
        mpz_urandomb(x, randstate, arg->bits2);
        mpz_poly_set_coeff(in2, i, x);
    }
    mpz_poly_to_fmpz_poly(in2f, in2);

    start_clock(0);

    if (arg->which)
    {
        for (unsigned long i = 0; i < count; i++)
            _fmpz_poly_mul_karatsuba(outf, in1f, in2f);
    }
    else
    {
        for (unsigned long i = 0; i < count; i++)
            mpz_poly_mul_karatsuba(out, in1, in2);
    }

    stop_clock(0);

    _fmpz_poly_stack_clear(outf);
    fmpz_poly_clear(in2f);
    fmpz_poly_clear(in1f);

    mpz_poly_clear(out);
    mpz_poly_clear(in2);
    mpz_poly_clear(in1);
    mpz_clear(x);
}
Beispiel #3
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("mul_karatsuba....");
    fflush(stdout);

    

    /* Check aliasing of a and b */
    for (i = 0; i < 200 * flint_test_multiplier(); i++)
    {
        fmpz_poly_t a, b, c;

        fmpz_poly_init(a);
        fmpz_poly_init(b);
        fmpz_poly_init(c);
        fmpz_poly_randtest(b, state, n_randint(state, 50), 200);
        fmpz_poly_randtest(c, state, n_randint(state, 50), 200);

        fmpz_poly_mul_karatsuba(a, b, c);
        fmpz_poly_mul_karatsuba(b, b, c);

        result = (fmpz_poly_equal(a, b));
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpz_poly_print(a), flint_printf("\n\n");
            fmpz_poly_print(b), flint_printf("\n\n");
            abort();
        }

        fmpz_poly_clear(a);
        fmpz_poly_clear(b);
        fmpz_poly_clear(c);
    }

    /* Check aliasing of a and c */
    for (i = 0; i < 200 * flint_test_multiplier(); i++)
    {
        fmpz_poly_t a, b, c;

        fmpz_poly_init(a);
        fmpz_poly_init(b);
        fmpz_poly_init(c);
        fmpz_poly_randtest(b, state, n_randint(state, 50), 200);
        fmpz_poly_randtest(c, state, n_randint(state, 50), 200);

        fmpz_poly_mul_karatsuba(a, b, c);
        fmpz_poly_mul_karatsuba(c, b, c);

        result = (fmpz_poly_equal(a, c));
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpz_poly_print(a), flint_printf("\n\n");
            fmpz_poly_print(c), flint_printf("\n\n");
            abort();
        }

        fmpz_poly_clear(a);
        fmpz_poly_clear(b);
        fmpz_poly_clear(c);
    }

    /* Compare with mul_classical */
    for (i = 0; i < 200 * flint_test_multiplier(); i++)
    {
        fmpz_poly_t a, b, c, d;

        fmpz_poly_init(a);
        fmpz_poly_init(b);
        fmpz_poly_init(c);
        fmpz_poly_init(d);
        fmpz_poly_randtest(b, state, n_randint(state, 50), 200);
        fmpz_poly_randtest(c, state, n_randint(state, 50), 200);

        fmpz_poly_mul_karatsuba(a, b, c);
        fmpz_poly_mul_classical(d, b, c);

        result = (fmpz_poly_equal(a, d));
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpz_poly_print(a), flint_printf("\n\n");
            fmpz_poly_print(d), flint_printf("\n\n");
            abort();
        }

        fmpz_poly_clear(a);
        fmpz_poly_clear(b);
        fmpz_poly_clear(c);
        fmpz_poly_clear(d);
    }

    /* Check _fmpz_poly_mul_karatsuba directly */
    for (i = 0; i < 200 * flint_test_multiplier(); i++)
    {
        slong len1, len2;
        fmpz_poly_t a, b, out1, out2;

        len1 = n_randint(state, 100) + 1;
        len2 = n_randint(state, 100) + 1;
        fmpz_poly_init(a);
        fmpz_poly_init(b);
        fmpz_poly_init(out1);
        fmpz_poly_init(out2);
        fmpz_poly_randtest(a, state, len1, 200);
        fmpz_poly_randtest(b, state, len2, 200);

        fmpz_poly_mul_karatsuba(out1, a, b);
        fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10));
        fmpz_poly_fit_length(b, b->alloc + n_randint(state, 10));
        a->length = a->alloc;
        b->length = b->alloc;
        fmpz_poly_fit_length(out2, a->length + b->length - 1);
        if (a->length >= b->length)
            _fmpz_poly_mul_karatsuba(out2->coeffs, a->coeffs, a->length,
                                                   b->coeffs, b->length);
        else
            _fmpz_poly_mul_karatsuba(out2->coeffs, b->coeffs, b->length,
                                                   a->coeffs, a->length);
        _fmpz_poly_set_length(out2, a->length + b->length - 1);
        _fmpz_poly_normalise(out2);

        result = (fmpz_poly_equal(out1, out2));
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpz_poly_print(out1), flint_printf("\n\n");
            fmpz_poly_print(out2), flint_printf("\n\n");
            abort();
        }

        fmpz_poly_clear(a);
        fmpz_poly_clear(b);
        fmpz_poly_clear(out1);
        fmpz_poly_clear(out2);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}