Пример #1
0
void
nmod_poly_xgcd_hgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T,
                         const nmod_poly_t A, const nmod_poly_t B)
{
    if (A->length < B->length)
    {
        nmod_poly_xgcd_hgcd(G, T, S, B, A);
    }
    else  /* lenA >= lenB >= 0 */
    {
        const slong lenA = A->length, lenB = B->length;
        mp_limb_t inv;

        if (lenA == 0)  /* lenA = lenB = 0 */
        {
            nmod_poly_zero(G);
            nmod_poly_zero(S);
            nmod_poly_zero(T);
        }
        else if (lenB == 0)  /* lenA > lenB = 0 */
        {
            inv = n_invmod(A->coeffs[lenA - 1], A->mod.n);
            nmod_poly_scalar_mul_nmod(G, A, inv);
            nmod_poly_zero(T);
            nmod_poly_set_coeff_ui(S, 0, inv);
            S->length = 1;
        }
        else if (lenB == 1)  /* lenA >= lenB = 1 */
        {
            nmod_poly_fit_length(T, 1);
            T->length = 1;
            T->coeffs[0] = n_invmod(B->coeffs[0], A->mod.n);
            nmod_poly_one(G);
            nmod_poly_zero(S);
        }
        else  /* lenA >= lenB >= 2 */
        {
            mp_ptr g, s, t;
            slong lenG;

            if (G == A || G == B)
            {
                g = _nmod_vec_init(FLINT_MIN(lenA, lenB));
            }
            else
            {
                nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB));
                g = G->coeffs;
            }
            if (S == A || S == B)
            {
                s = _nmod_vec_init(FLINT_MAX(lenB - 1, 2));
            }
            else
            {
                nmod_poly_fit_length(S, FLINT_MAX(lenB - 1, 2));
                s = S->coeffs;
            }
            if (T == A || T == B)
            {
                t = _nmod_vec_init(FLINT_MAX(lenA - 1, 2));
            }
            else
            {
                nmod_poly_fit_length(T, FLINT_MAX(lenA - 1, 2));
                t = T->coeffs;
            }

            if (lenA >= lenB)
                lenG = _nmod_poly_xgcd_hgcd(g, s, t, A->coeffs, lenA,
                                                          B->coeffs, lenB, A->mod);
            else
                lenG = _nmod_poly_xgcd_hgcd(g, t, s, B->coeffs, lenB,
                                                          A->coeffs, lenA, A->mod);

            if (G == A || G == B)
            {
                flint_free(G->coeffs);
                G->coeffs = g;
                G->alloc  = FLINT_MIN(lenA, lenB);
            }
            if (S == A || S == B)
            {
                flint_free(S->coeffs);
                S->coeffs = s;
                S->alloc  = FLINT_MAX(lenB - 1, 2);
            }
            if (T == A || T == B)
            {
                flint_free(T->coeffs);
                T->coeffs = t;
                T->alloc  = FLINT_MAX(lenA - 1, 2);
            }

            G->length = lenG;
            S->length = FLINT_MAX(lenB - lenG, 1);
            T->length = FLINT_MAX(lenA - lenG, 1);
            MPN_NORM(S->coeffs, S->length);
            MPN_NORM(T->coeffs, T->length);

            if (G->coeffs[lenG - 1] != 1)
            {
                inv = n_invmod(G->coeffs[lenG - 1], A->mod.n);
                nmod_poly_scalar_mul_nmod(G, G, inv);
                nmod_poly_scalar_mul_nmod(S, S, inv);
                nmod_poly_scalar_mul_nmod(T, T, inv);
            }
        }
    }
}
Пример #2
0
void
nmod_poly_xgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T,
                              const nmod_poly_t A, const nmod_poly_t B)
{
    const long lenA = A->length, lenB = B->length;
    mp_limb_t inv;

    if (lenA == 0)
    {
        if (lenB == 0) 
        {
            nmod_poly_zero(G);
            nmod_poly_zero(S);
            nmod_poly_zero(T);
        }
        else 
        {
            inv = n_invmod(B->coeffs[lenB - 1], B->mod.n);
            nmod_poly_scalar_mul_nmod(G, B, inv);
            nmod_poly_zero(S);
            nmod_poly_set_coeff_ui(T, 0, inv);
            T->length = 1;
        }
    } 
    else if (lenB == 0)
    {
        inv = n_invmod(A->coeffs[lenA - 1], A->mod.n);
        nmod_poly_scalar_mul_nmod(G, A, inv);
        nmod_poly_zero(T);
        nmod_poly_set_coeff_ui(S, 0, inv);
        S->length = 1;
    }
    else
    {
        nmod_poly_t tG, tS, tT;
        mp_ptr g, s, t;
        long lenG;

        if (G == A || G == B)
        {
            nmod_poly_init2(tG, A->mod.n, FLINT_MIN(lenA, lenB));
            g = tG->coeffs;
        }
        else
        {
            nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB));
            g = G->coeffs;
        }
        if (S == A || S == B)
        {
            nmod_poly_init2(tS, A->mod.n, lenB - 1);
            s = tS->coeffs;
        }
        else
        {
            nmod_poly_fit_length(S, lenB - 1);
            s = S->coeffs;
        }
        if (T == A || T == B)
        {
            nmod_poly_init2(tT, A->mod.n, lenA - 1);
            t = tT->coeffs;
        }
        else
        {
            nmod_poly_fit_length(T, lenA - 1);
            t = T->coeffs;
        }

        if (lenA >= lenB)
            lenG = _nmod_poly_xgcd(g, s, t, A->coeffs, lenA,
                                            B->coeffs, lenB, A->mod);
        else
            lenG = _nmod_poly_xgcd(g, t, s, B->coeffs, lenB,
                                            A->coeffs, lenA, A->mod);

        if (G == A || G == B)
        {
            nmod_poly_swap(tG, G);
            nmod_poly_clear(tG);
        }
        if (S == A || S == B)
        {
            nmod_poly_swap(tS, S);
            nmod_poly_clear(tS);
        }
        if (T == A || T == B)
        {
            nmod_poly_swap(tT, T);
            nmod_poly_clear(tT);
        }
        
        G->length = lenG;
        S->length = lenB - lenG;
        T->length = lenA - lenG;
        MPN_NORM(S->coeffs, S->length);
        MPN_NORM(T->coeffs, T->length);

        if (G->coeffs[lenG - 1] != 1)
        {
            inv = n_invmod(G->coeffs[lenG - 1], A->mod.n);
            nmod_poly_scalar_mul_nmod(G, G, inv);
            nmod_poly_scalar_mul_nmod(S, S, inv);
            nmod_poly_scalar_mul_nmod(T, T, inv);
        }
    }
}
Пример #3
0
int
main(void)
{
    int iter;
    flint_rand_t state;
    flint_randinit(state);

    printf("factor....");
    fflush(stdout);

    /* Default algorithm */
    for (iter = 0; iter < 100; iter++)
    {
        int result = 1;
        nmod_poly_t pol1, poly, quot, rem, product;
        nmod_poly_factor_t res;
        mp_limb_t modulus, lead = 1;
        long length, num, i, j;
        ulong exp[5], prod1;

        modulus = n_randtest_prime(state, 0);

        nmod_poly_init(pol1, modulus);
        nmod_poly_init(poly, modulus);
        nmod_poly_init(quot, modulus);
        nmod_poly_init(rem, modulus);

        nmod_poly_zero(pol1);
        nmod_poly_set_coeff_ui(pol1, 0, 1);

        length = n_randint(state, 7) + 2;
        do 
        {
            nmod_poly_randtest(poly, state, length); 
            if (poly->length)
                nmod_poly_make_monic(poly, poly);
        }
        while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2));

        exp[0] = n_randint(state, 30) + 1;
        prod1 = exp[0];
        for (i = 0; i < exp[0]; i++)
            nmod_poly_mul(pol1, pol1, poly);

        num = n_randint(state, 5) + 1;
        for (i = 1; i < num; i++)
        {
            do 
            {
                length = n_randint(state, 7) + 2;
                nmod_poly_randtest(poly, state, length); 
                if (poly->length)
                {
                    nmod_poly_make_monic(poly, poly);
                    nmod_poly_divrem(quot, rem, pol1, poly);
                }
            }
            while ((!nmod_poly_is_irreducible(poly)) ||
                (poly->length < 2) || (rem->length == 0));
            exp[i] = n_randint(state, 30) + 1;
            prod1 *= exp[i];

            for (j = 0; j < exp[i]; j++)
                nmod_poly_mul(pol1, pol1, poly);
        }

        nmod_poly_factor_init(res);

        switch (n_randint(state, 3))
        {
            case 0:
                lead = nmod_poly_factor(res, pol1);
                break;
            case 1:
                lead = nmod_poly_factor_with_berlekamp(res, pol1);
                break;
            case 2:
                if (modulus == 2)
                    lead = nmod_poly_factor(res, pol1);
                else
                    lead = nmod_poly_factor_with_cantor_zassenhaus(res, pol1);
                break;
        }

        result &= (res->num == num);
        if (!result)
        {
            printf("Error: number of factors incorrect, %ld, %ld\n",
                res->num, num);
            abort();
        }

        nmod_poly_init(product, pol1->mod.n);
        nmod_poly_set_coeff_ui(product, 0, 1);
        for (i = 0; i < res->num; i++)
            for (j = 0; j < res->exp[i]; j++)
                nmod_poly_mul(product, product, res->p + i);
        nmod_poly_scalar_mul_nmod(product, product, lead);
        result &= nmod_poly_equal(pol1, product);
        if (!result)
        {
            printf("Error: product of factors does not equal original polynomial\n");
            nmod_poly_print(pol1); printf("\n");
            nmod_poly_print(product); printf("\n");
            abort();
        }
        nmod_poly_clear(product);

        nmod_poly_clear(quot);
        nmod_poly_clear(rem);
        nmod_poly_clear(pol1);
        nmod_poly_clear(poly);
        nmod_poly_factor_clear(res);
    }

    /* Test deflation trick */
    for (iter = 0; iter < 100; iter++)
    {
        nmod_poly_t pol1, poly, quot, rem;
        nmod_poly_factor_t res, res2;
        mp_limb_t modulus;
        long length, num, i, j;
        long exp[5], prod1;
        ulong inflation;
        int found;

        do {
            modulus = n_randtest_prime(state, 0);
        } while (modulus == 2); /* To compare with CZ */

        nmod_poly_init(pol1, modulus);
        nmod_poly_init(poly, modulus);
        nmod_poly_init(quot, modulus);
        nmod_poly_init(rem, modulus);

        nmod_poly_zero(pol1);
        nmod_poly_set_coeff_ui(pol1, 0, 1);

        inflation = n_randint(state, 7) + 1;

        length = n_randint(state, 7) + 2;
        do 
        {
            nmod_poly_randtest(poly, state, length); 
            if (poly->length)
                nmod_poly_make_monic(poly, poly);
        }
        while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2));
        nmod_poly_inflate(poly, poly, inflation);

        exp[0] = n_randint(state, 6) + 1;
        prod1 = exp[0];
        for (i = 0; i < exp[0]; i++)
            nmod_poly_mul(pol1, pol1, poly);

        num = n_randint(state, 5) + 1;
        for (i = 1; i < num; i++)
        {
            do
            {
                length = n_randint(state, 6) + 2;
                nmod_poly_randtest(poly, state, length); 
                if (poly->length)
                {
                    nmod_poly_make_monic(poly, poly);
                    nmod_poly_divrem(quot, rem, pol1, poly);
                }
            }
            while ((!nmod_poly_is_irreducible(poly)) ||
                (poly->length < 2) || (rem->length == 0));
            exp[i] = n_randint(state, 6) + 1;
            prod1 *= exp[i];
            nmod_poly_inflate(poly, poly, inflation);

            for (j = 0; j < exp[i]; j++)
                nmod_poly_mul(pol1, pol1, poly);
        }

        nmod_poly_factor_init(res);
        nmod_poly_factor_init(res2);

        switch (n_randint(state, 3))
        {
            case 0:
                nmod_poly_factor(res, pol1);
                break;
            case 1:
                nmod_poly_factor_with_berlekamp(res, pol1);
                break;
            case 2:
                nmod_poly_factor_with_cantor_zassenhaus(res, pol1);
                break;
        }

        nmod_poly_factor_cantor_zassenhaus(res2, pol1);

        if (res->num != res2->num)
        {
            printf("FAIL: different number of factors found\n");
            abort();
        }

        for (i = 0; i < res->num; i++)
        {
            found = 0;
            for (j = 0; j < res2->num; j++)
            {
                if (nmod_poly_equal(res->p + i, res2->p + j) &&
                        res->exp[i] == res2->exp[j])
                {
                    found = 1;
                    break;
                }
            }

            if (!found)
            {
                printf("FAIL: factor not found\n");
                abort();
            }
        }

        nmod_poly_clear(quot);
        nmod_poly_clear(rem);
        nmod_poly_clear(pol1);
        nmod_poly_clear(poly);
        nmod_poly_factor_clear(res);
        nmod_poly_factor_clear(res2);
    }

    flint_randclear(state);
    printf("PASS\n");
    return 0;
}
Пример #4
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);
    

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

    /* Check aliasing of a and b */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        nmod_poly_t a, b;
        mp_limb_t n = n_randtest_not_zero(state);
        mp_limb_t c = n_randint(state, n);

        nmod_poly_init(a, n);
        nmod_poly_init(b, n);
        nmod_poly_randtest(a, state, n_randint(state, 100));

        nmod_poly_scalar_mul_nmod(b, a, c);
        nmod_poly_scalar_mul_nmod(a, a, c);

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

        nmod_poly_clear(a);
        nmod_poly_clear(b);
    }

    /* Check (a + b)*c = a*c + b*c */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        nmod_poly_t a, b, d1, d2;
        mp_limb_t n = n_randtest_not_zero(state);
        mp_limb_t c = n_randint(state, n);

        nmod_poly_init(a, n);
        nmod_poly_init(b, n);
        nmod_poly_init(d1, n);
        nmod_poly_init(d2, n);
        nmod_poly_randtest(a, state, n_randint(state, 100));
        nmod_poly_randtest(b, state, n_randint(state, 100));

        nmod_poly_add(d1, a, b);
        nmod_poly_scalar_mul_nmod(d1, d1, c);

        nmod_poly_scalar_mul_nmod(d2, a, c);
        nmod_poly_scalar_mul_nmod(b, b, c);
        nmod_poly_add(d2, d2, b);

        result = (nmod_poly_equal(d1, d2));
        if (!result)
        {
            flint_printf("FAIL:\n");
            nmod_poly_print(d1), flint_printf("\n\n");
            nmod_poly_print(d2), flint_printf("\n\n");
            abort();
        }

        nmod_poly_clear(a);
        nmod_poly_clear(b);
        nmod_poly_clear(d1);
        nmod_poly_clear(d2);
    }

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