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 
fq_nmod_mpolyv_clear(fq_nmod_mpolyv_t A,const fq_nmod_mpoly_ctx_t ctx)15 void fq_nmod_mpolyv_clear(fq_nmod_mpolyv_t A, const fq_nmod_mpoly_ctx_t ctx)
16 {
17     slong i;
18     if (A->alloc > 0)
19     {
20         for (i = 0; i < A->alloc; i++)
21             fq_nmod_mpoly_clear(A->coeffs + i, ctx);
22         flint_free(A->coeffs);
23     }
24 }
25 
26 
fq_nmod_mpolyv_print_pretty(const fq_nmod_mpolyv_t poly,const char ** x,const fq_nmod_mpoly_ctx_t ctx)27 void fq_nmod_mpolyv_print_pretty(
28     const fq_nmod_mpolyv_t poly,
29     const char ** x,
30     const fq_nmod_mpoly_ctx_t ctx)
31 {
32     slong i;
33     for (i = 0; i < poly->length; i++)
34     {
35         flint_printf("coeff[%wd]: ", i);
36         fq_nmod_mpoly_print_pretty(poly->coeffs + i, x, ctx);
37         flint_printf("\n");
38     }
39 }
40 
41 
fq_nmod_mpolyv_fit_length(fq_nmod_mpolyv_t A,slong length,const fq_nmod_mpoly_ctx_t ctx)42 void fq_nmod_mpolyv_fit_length(
43     fq_nmod_mpolyv_t A,
44     slong length,
45     const fq_nmod_mpoly_ctx_t ctx)
46 {
47     slong i;
48     slong old_alloc = A->alloc;
49     slong new_alloc = FLINT_MAX(length, 2*A->alloc);
50 
51     if (length <= old_alloc)
52         return;
53 
54     if (old_alloc > 0)
55     {
56         A->coeffs = (fq_nmod_mpoly_struct *) flint_realloc(A->coeffs,
57                                        new_alloc*sizeof(fq_nmod_mpoly_struct));
58     }
59     else
60     {
61         A->coeffs = (fq_nmod_mpoly_struct *) flint_malloc(
62                                        new_alloc*sizeof(fq_nmod_mpoly_struct));
63     }
64 
65     for (i = old_alloc; i < new_alloc; i++)
66         fq_nmod_mpoly_init(A->coeffs + i, ctx);
67 
68     A->alloc = new_alloc;
69 }
70 
fq_nmod_mpolyv_set_coeff(fq_nmod_mpolyv_t A,slong i,fq_nmod_mpoly_t c,const fq_nmod_mpoly_ctx_t ctx)71 void fq_nmod_mpolyv_set_coeff(
72     fq_nmod_mpolyv_t A,
73     slong i,
74     fq_nmod_mpoly_t c, /* clobbered */
75     const fq_nmod_mpoly_ctx_t ctx)
76 {
77     slong j;
78     FLINT_ASSERT(!fq_nmod_mpoly_is_zero(c, ctx));
79     fq_nmod_mpolyv_fit_length(A, i + 1, ctx);
80     for (j = A->length; j < i; j++)
81         fq_nmod_mpoly_zero(A->coeffs + j, ctx);
82     fq_nmod_mpoly_swap(A->coeffs + i, c, ctx);
83     A->length = FLINT_MAX(A->length, i + 1);
84 }
85 
86 
fq_nmod_mpoly_to_mpolyv(fq_nmod_mpolyv_t A,const fq_nmod_mpoly_t B,const fq_nmod_mpoly_t xalpha,const fq_nmod_mpoly_ctx_t ctx)87 void fq_nmod_mpoly_to_mpolyv(
88     fq_nmod_mpolyv_t A,
89     const fq_nmod_mpoly_t B,
90     const fq_nmod_mpoly_t xalpha,
91     const fq_nmod_mpoly_ctx_t ctx)
92 {
93     fq_nmod_mpoly_t Q, T;
94 
95     fq_nmod_mpoly_init(Q, ctx);
96     fq_nmod_mpoly_init(T, ctx);
97 
98     fq_nmod_mpolyv_fit_length(A, 8, ctx);
99     fq_nmod_mpoly_divrem(Q, A->coeffs + 0, B, xalpha, ctx);
100     A->length = 1;
101 
102     while (!fq_nmod_mpoly_is_zero(Q, ctx))
103     {
104         fq_nmod_mpolyv_fit_length(A, A->length + 1, ctx);
105         fq_nmod_mpoly_divrem(T, A->coeffs + A->length, Q, xalpha, ctx);
106         fq_nmod_mpoly_swap(Q, T, ctx);
107         A->length++;
108     }
109 
110     while (A->length > 0 && fq_nmod_mpoly_is_zero(A->coeffs + A->length - 1, ctx))
111         A->length--;
112 
113     fq_nmod_mpoly_clear(Q, ctx);
114     fq_nmod_mpoly_clear(T, ctx);
115 }
116 
117 
fq_nmod_mpoly_from_mpolyv(fq_nmod_mpoly_t A,flint_bitcnt_t Abits,const fq_nmod_mpolyv_t B,const fq_nmod_mpoly_t xalpha,const fq_nmod_mpoly_ctx_t ctx)118 void fq_nmod_mpoly_from_mpolyv(
119     fq_nmod_mpoly_t A,
120     flint_bitcnt_t Abits,
121     const fq_nmod_mpolyv_t B,
122     const fq_nmod_mpoly_t xalpha,
123     const fq_nmod_mpoly_ctx_t ctx)
124 {
125     slong i;
126     fq_nmod_mpoly_t T;
127 
128     fq_nmod_mpoly_init(T, ctx);
129 
130     fq_nmod_mpoly_zero(A, ctx);
131     for (i = B->length - 1; i >= 0; i--)
132     {
133         fq_nmod_mpoly_mul(T, A, xalpha, ctx);
134         fq_nmod_mpoly_add(A, T, B->coeffs + i, ctx);
135     }
136 
137     fq_nmod_mpoly_clear(T, ctx);
138 
139     fq_nmod_mpoly_repack_bits_inplace(A, Abits, ctx);
140 }
141 
142 
_fq_nmod_mpoly_vec_content_mpoly(fq_nmod_mpoly_t g,const fq_nmod_mpoly_struct * A,slong Alen,const fq_nmod_mpoly_ctx_t ctx)143 int _fq_nmod_mpoly_vec_content_mpoly(
144     fq_nmod_mpoly_t g,
145     const fq_nmod_mpoly_struct * A,
146     slong Alen,
147     const fq_nmod_mpoly_ctx_t ctx)
148 {
149     slong i;
150     int success;
151 
152     fq_nmod_mpoly_zero(g, ctx);
153 
154     for (i = 0; i < Alen; i++)
155     {
156         success = fq_nmod_mpoly_gcd(g, g, A + i, ctx);
157         if (!success)
158             return 0;
159     }
160 
161     return 1;
162 }
163 
_fq_nmod_mpoly_vec_divexact_mpoly(fq_nmod_mpoly_struct * A,slong Alen,const fq_nmod_mpoly_t c,const fq_nmod_mpoly_ctx_t ctx)164 void _fq_nmod_mpoly_vec_divexact_mpoly(
165     fq_nmod_mpoly_struct * A, slong Alen,
166     const fq_nmod_mpoly_t c,
167     const fq_nmod_mpoly_ctx_t ctx)
168 {
169     slong i;
170 
171     for (i = 0; i < Alen; i++)
172         fq_nmod_mpoly_divexact(A + i, A + i, c, ctx);
173 }
174 
_fq_nmod_mpoly_vec_mul_mpoly(fq_nmod_mpoly_struct * A,slong Alen,const fq_nmod_mpoly_t c,const fq_nmod_mpoly_ctx_t ctx)175 void _fq_nmod_mpoly_vec_mul_mpoly(
176     fq_nmod_mpoly_struct * A, slong Alen,
177     const fq_nmod_mpoly_t c,
178     const fq_nmod_mpoly_ctx_t ctx)
179 {
180     slong i;
181 
182     for (i = 0; i < Alen; i++)
183         fq_nmod_mpoly_mul(A + i, A + i, c, ctx);
184 }
185 
186