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 "fmpz_mpoly_factor.h"
13
check_omega(slong lower,slong upper,const fmpz_mpoly_t p,const fmpz_mpoly_ctx_t ctx)14 void check_omega(slong lower, slong upper, const fmpz_mpoly_t p, const fmpz_mpoly_ctx_t ctx)
15 {
16 slong i;
17 fmpz_mpoly_t q;
18 fmpz_mpoly_factor_t g, h;
19 fmpz_t omega;
20
21 fmpz_init(omega);
22 fmpz_mpoly_factor_init(g, ctx);
23 fmpz_mpoly_factor_init(h, ctx);
24 fmpz_mpoly_init(q, ctx);
25
26 if (!fmpz_mpoly_factor_wang(g, p, ctx))
27 {
28 flint_printf("check factorization 1 could be computed\n");
29 flint_abort();
30 }
31
32 if (!fmpz_mpoly_factor(h, p, ctx))
33 {
34 flint_printf("check factorization 2 could be computed\n");
35 flint_abort();
36 }
37
38 for (i = 0; i < g->num; i++)
39 {
40 if (g->poly[i].length < 1 || fmpz_sgn(g->poly[i].coeffs + 0) <= 0)
41 {
42 flint_printf("factorization is not unit normal\n");
43 flint_abort();
44 }
45 }
46
47 fmpz_zero(omega);
48 for (i = 0; i < g->num; i++)
49 fmpz_add(omega, omega, g->exp + i);
50
51 if (fmpz_cmp_si(omega, lower) < 0 || fmpz_cmp_si(omega, upper) > 0)
52 {
53 flint_printf("factorization has wrong number of factors\n");
54 flint_abort();
55 }
56
57 fmpz_mpoly_factor_expand(q, g, ctx);
58
59 if (!fmpz_mpoly_equal(q, p, ctx))
60 {
61 flint_printf("factorization does not match original polynomial\n");
62 flint_abort();
63 }
64
65 fmpz_mpoly_factor_sort(g, ctx);
66 fmpz_mpoly_factor_sort(h, ctx);
67 if (fmpz_mpoly_factor_cmp(g, h, ctx) != 0)
68 {
69 flint_printf("factorizations do not match\n");
70 flint_abort();
71 }
72
73 for (i = 0; i < g->num; i++)
74 {
75 fmpz_mpoly_factor(h, g->poly + i, ctx);
76 if (h->num != 1 || !fmpz_is_one(h->exp + 0))
77 {
78 flint_printf("FAIL:\nfactor is reducible\n");
79 flint_abort();
80 }
81 }
82
83 fmpz_mpoly_clear(q, ctx);
84 fmpz_mpoly_factor_clear(g, ctx);
85 fmpz_mpoly_factor_clear(h, ctx);
86 fmpz_clear(omega);
87 return;
88 }
89
90
91 int
main(void)92 main(void)
93 {
94 slong i, j, tmul = 20;
95
96 FLINT_TEST_INIT(state);
97
98 flint_printf("factor_wang....");
99 fflush(stdout);
100
101 for (i = 0; i < tmul * flint_test_multiplier(); i++)
102 {
103 slong lower;
104 fmpz_mpoly_ctx_t ctx;
105 fmpz_mpoly_t a, at, t;
106 flint_bitcnt_t coeff_bits;
107 slong nfacs, len;
108 ulong expbound, powbound, pow;
109
110 fmpz_mpoly_ctx_init_rand(ctx, state, 6);
111
112 fmpz_mpoly_init(a, ctx);
113 fmpz_mpoly_init(at, ctx);
114 fmpz_mpoly_init(t, ctx);
115
116 nfacs = 1 + (4 + n_randint(state, 5))/ctx->minfo->nvars;
117 expbound = 2 + 25/nfacs/ctx->minfo->nvars;
118 powbound = 1 + n_randint(state, 3);
119
120 lower = 0;
121 fmpz_mpoly_one(a, ctx);
122 for (j = 0; j < nfacs; j++)
123 {
124 do {
125 len = 2 + n_randint(state, 10);
126 coeff_bits = 100 + n_randint(state, 300)/nfacs;
127 fmpz_mpoly_randtest_bound(t, state, len, coeff_bits, expbound, ctx);
128 } while (t->length == 0);
129 pow = 1 + n_randint(state, powbound);
130
131 fmpz_mpoly_pow_ui(t, t, pow, ctx);
132 fmpz_mpoly_mul(at, a, t, ctx);
133
134 if (t->length < 200)
135 {
136 fmpz_mpoly_swap(a, at, ctx);
137 if (!fmpz_mpoly_is_fmpz(t, ctx))
138 lower += pow;
139 }
140 }
141
142 check_omega(lower, WORD_MAX, a, ctx);
143
144 fmpz_mpoly_clear(t, ctx);
145 fmpz_mpoly_clear(at, ctx);
146 fmpz_mpoly_clear(a, ctx);
147 fmpz_mpoly_ctx_clear(ctx);
148 }
149
150 FLINT_TEST_CLEANUP(state);
151
152 flint_printf("PASS\n");
153 return 0;
154 }
155