1 /*
2     Copyright (C) 2020 Daniel Schultz
3 
4     This file is part of FLINT.
5 
6     FLINT is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
10 */
11 
12 #include "fq_nmod_mpoly_factor.h"
13 
14 
15 /* check total number of factors with multiplicity is between lower and upper */
check_it(const fq_nmod_mpoly_t p,const fq_nmod_mpoly_ctx_t ctx)16 void check_it(const fq_nmod_mpoly_t p, const fq_nmod_mpoly_ctx_t ctx)
17 {
18     slong i, j;
19     fq_nmod_mpoly_t q;
20     fq_nmod_mpoly_factor_t g, h;
21 
22     fq_nmod_mpoly_factor_init(g, ctx);
23     fq_nmod_mpoly_factor_init(h, ctx);
24     fq_nmod_mpoly_init(q, ctx);
25 
26     if (!fq_nmod_mpoly_factor_squarefree(g, p, ctx))
27     {
28         flint_printf("FAIL:\ncheck factorization 1 could be computed\n");
29         flint_abort();
30     }
31 
32     for (i = 0; i < g->num; i++)
33     {
34         if (!fq_nmod_mpoly_is_monic(g->poly + i, ctx))
35         {
36             flint_printf("FAIL:\nfactorization is not unit normal\n");
37             flint_abort();
38         }
39     }
40 
41     fq_nmod_mpoly_factor_expand(q, g, ctx);
42     if (!fq_nmod_mpoly_equal(q, p, ctx))
43     {
44         flint_printf("FAIL:\nfactorization does not match original polynomial\n");
45         flint_abort();
46     }
47 
48     for (i = 0; i < g->num; i++)
49     {
50         fq_nmod_mpoly_factor_squarefree(h, g->poly + i, ctx);
51         for (j = 0; j < h->num; j++)
52         {
53             if (!fmpz_is_one(h->exp + j))
54             {
55                 flint_printf("FAIL:\nfactor has a square factor\n");
56                 flint_abort();
57             }
58         }
59     }
60 
61     for (i = 1; i < g->num; i++)
62     for (j = 0; j < i; j++)
63     {
64         if (!fq_nmod_mpoly_gcd(q, g->poly + i, g->poly + j, ctx))
65         {
66             flint_printf("FAIL:\ncheck gcd could be computed\n");
67         }
68 
69         if (!fq_nmod_mpoly_is_one(q, ctx))
70         {
71             flint_printf("FAIL:\nbases have a common factor\n");
72         }
73     }
74 
75     fq_nmod_mpoly_clear(q, ctx);
76     fq_nmod_mpoly_factor_clear(g, ctx);
77     fq_nmod_mpoly_factor_clear(h, ctx);
78 }
79 
80 
81 int
main(void)82 main(void)
83 {
84     slong i, j, tmul = 30;
85     FLINT_TEST_INIT(state);
86 
87     flint_printf("factor_squarefree....");
88     fflush(stdout);
89 
90     for (i = 0; i < tmul * flint_test_multiplier(); i++)
91     {
92         fq_nmod_mpoly_ctx_t ctx;
93         fq_nmod_mpoly_t a, t;
94         slong nfacs, len;
95         ulong expbound, powbound, pow;
96 
97         fq_nmod_mpoly_ctx_init_rand(ctx, state, 5, FLINT_BITS, 4);
98         fq_nmod_mpoly_init(a, ctx);
99         fq_nmod_mpoly_init(t, ctx);
100 
101         nfacs = 2 + n_randint(state, 4);
102         powbound = 3;
103         expbound = 2 + 20/nfacs/ctx->minfo->nvars;
104 
105         fq_nmod_mpoly_one(a, ctx);
106         for (j = 0; j < nfacs; j++)
107         {
108             pow = 1 + n_randint(state, powbound);
109             len = 1 + n_randint(state, 2 + 15/pow/nfacs);
110             fq_nmod_mpoly_randtest_bound(t, state, len, expbound, ctx);
111             if (fq_nmod_mpoly_is_zero(t, ctx))
112                 fq_nmod_mpoly_one(t, ctx);
113 
114             fq_nmod_mpoly_pow_ui(t, t, pow, ctx);
115             fq_nmod_mpoly_mul(a, a, t, ctx);
116         }
117 
118         check_it(a, ctx);
119 
120         fq_nmod_mpoly_clear(t, ctx);
121         fq_nmod_mpoly_clear(a, ctx);
122         fq_nmod_mpoly_ctx_clear(ctx);
123     }
124 
125     FLINT_TEST_CLEANUP(state);
126 
127     flint_printf("PASS\n");
128     return 0;
129 }
130