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 "n_poly.h"
13
14
n_fq_bpoly_is_canonical(const n_fq_bpoly_t A,const fq_nmod_ctx_t ctx)15 int n_fq_bpoly_is_canonical(const n_fq_bpoly_t A, const fq_nmod_ctx_t ctx)
16 {
17 slong i;
18
19 if (A->length < 0)
20 return 0;
21
22 if (A->length > A->alloc)
23 return 0;
24
25 for (i = 0; i < A->length; i++)
26 {
27 if (!n_fq_poly_is_canonical(A->coeffs + i, ctx))
28 return 0;
29 if (i + 1 == A->length && n_fq_poly_is_zero(A->coeffs + i))
30 return 0;
31 }
32
33 return 1;
34 }
35
36
n_fq_bpoly_print_pretty(const n_fq_bpoly_t A,const char * xvar,const char * yvar,const fq_nmod_ctx_t ctx)37 void n_fq_bpoly_print_pretty(
38 const n_fq_bpoly_t A,
39 const char * xvar,
40 const char * yvar,
41 const fq_nmod_ctx_t ctx)
42 {
43 slong i;
44 int first;
45
46 first = 1;
47 for (i = A->length - 1; i >= 0; i--)
48 {
49 if (i + 1 != A->length && n_fq_poly_is_zero(A->coeffs + i))
50 continue;
51
52 if (!first)
53 flint_printf(" + ");
54
55 first = 0;
56
57 flint_printf("(");
58 n_fq_poly_print_pretty(A->coeffs + i, yvar, ctx);
59 flint_printf(")*%s^%wd", xvar, i);
60 }
61
62 if (first)
63 flint_printf("0");
64 }
65
66
n_fq_bpoly_one(n_fq_bpoly_t A,const fq_nmod_ctx_t ctx)67 void n_fq_bpoly_one(n_fq_bpoly_t A, const fq_nmod_ctx_t ctx)
68 {
69 n_fq_bpoly_fit_length(A, 1);
70 A->length = 1;
71 n_fq_poly_one(A->coeffs + 0, ctx);
72 }
73
n_fq_bpoly_set(n_fq_bpoly_t A,const n_fq_bpoly_t B,const fq_nmod_ctx_t ctx)74 void n_fq_bpoly_set(
75 n_fq_bpoly_t A,
76 const n_fq_bpoly_t B,
77 const fq_nmod_ctx_t ctx)
78 {
79 slong i;
80
81 if (A == B)
82 return;
83
84 n_fq_bpoly_fit_length(A, B->length);
85 A->length = B->length;
86 for (i = 0; i < B->length; i++)
87 n_fq_poly_set(A->coeffs + i, B->coeffs + i, ctx);
88 }
89
n_fq_bpoly_equal(const n_bpoly_t A,const n_bpoly_t B,const fq_nmod_ctx_t ctx)90 int n_fq_bpoly_equal(
91 const n_bpoly_t A,
92 const n_bpoly_t B,
93 const fq_nmod_ctx_t ctx)
94 {
95 slong i;
96
97 if (A->length != B->length)
98 return 0;
99
100 for (i = 0; i < A->length; i++)
101 {
102 if (!n_fq_poly_equal(A->coeffs + i, B->coeffs + i, ctx))
103 return 0;
104 }
105
106 return 1;
107 }
108
109
n_fq_bpoly_get_coeff_n_fq(mp_limb_t * c,const n_bpoly_t A,slong e0,slong e1,const fq_nmod_ctx_t ctx)110 void n_fq_bpoly_get_coeff_n_fq(
111 mp_limb_t * c,
112 const n_bpoly_t A,
113 slong e0,
114 slong e1,
115 const fq_nmod_ctx_t ctx)
116 {
117 if (e0 >= A->length)
118 _n_fq_zero(c, fq_nmod_ctx_degree(ctx));
119 else
120 n_fq_poly_get_coeff_n_fq(c, A->coeffs + e0, e1, ctx);
121 }
122
n_fq_bpoly_set_coeff_n_fq(n_bpoly_t A,slong e0,slong e1,const mp_limb_t * c,const fq_nmod_ctx_t ctx)123 void n_fq_bpoly_set_coeff_n_fq(
124 n_bpoly_t A,
125 slong e0,
126 slong e1,
127 const mp_limb_t * c,
128 const fq_nmod_ctx_t ctx)
129 {
130 slong i;
131
132 if (e0 >= A->length)
133 {
134 n_fq_bpoly_fit_length(A, e0 + 1);
135 for (i = A->length; i <= e0; i++)
136 n_fq_poly_zero(A->coeffs + i);
137 A->length = e0 + 1;
138 }
139
140 n_fq_poly_set_coeff_n_fq(A->coeffs + e0, e1, c, ctx);
141
142 n_fq_bpoly_normalise(A);
143
144 FLINT_ASSERT(n_fq_bpoly_is_canonical(A, ctx));
145 }
146
147
n_fq_bpoly_get_coeff_fq_nmod(fq_nmod_t c,const n_bpoly_t A,slong e0,slong e1,const fq_nmod_ctx_t ctx)148 void n_fq_bpoly_get_coeff_fq_nmod(
149 fq_nmod_t c,
150 const n_bpoly_t A,
151 slong e0,
152 slong e1,
153 const fq_nmod_ctx_t ctx)
154 {
155 if (e0 >= A->length)
156 fq_nmod_zero(c, ctx);
157 else
158 n_fq_poly_get_coeff_fq_nmod(c, A->coeffs + e0, e1, ctx);
159 }
160
161
n_fq_bpoly_set_fq_nmod_poly_gen0(n_fq_bpoly_t A,const fq_nmod_poly_t B,const fq_nmod_ctx_t ctx)162 void n_fq_bpoly_set_fq_nmod_poly_gen0(
163 n_fq_bpoly_t A,
164 const fq_nmod_poly_t B,
165 const fq_nmod_ctx_t ctx)
166 {
167 slong i;
168 n_bpoly_fit_length(A, B->length);
169 A->length = 0;
170 for (i = 0; i < B->length; i++)
171 n_fq_poly_set_fq_nmod(A->coeffs + i, B->coeffs + i, ctx);
172 A->length = B->length;
173 n_bpoly_normalise(A);
174 }
175
n_fq_bpoly_set_n_fq_poly_gen0(n_fq_bpoly_t A,const n_fq_poly_t B,const fq_nmod_ctx_t ctx)176 void n_fq_bpoly_set_n_fq_poly_gen0(
177 n_fq_bpoly_t A,
178 const n_fq_poly_t B,
179 const fq_nmod_ctx_t ctx)
180 {
181 slong d = fq_nmod_ctx_degree(ctx);
182 slong i;
183 n_bpoly_fit_length(A, B->length);
184 for (i = 0; i < B->length; i++)
185 n_fq_poly_set_n_fq(A->coeffs + i, B->coeffs + d*i, ctx);
186 A->length = B->length;
187 n_bpoly_normalise(A);
188 }
189
n_fq_bpoly_set_n_fq_poly_gen1(n_fq_bpoly_t A,const n_fq_poly_t B,const fq_nmod_ctx_t ctx)190 void n_fq_bpoly_set_n_fq_poly_gen1(
191 n_fq_bpoly_t A,
192 const n_fq_poly_t B,
193 const fq_nmod_ctx_t ctx)
194 {
195 n_bpoly_fit_length(A, 1);
196 n_fq_poly_set(A->coeffs + 0, B, ctx);
197 A->length = !n_poly_is_zero(A->coeffs + 0);
198 }
199
200
n_fq_bpoly_derivative_gen0(n_bpoly_t A,const n_bpoly_t B,const fq_nmod_ctx_t ctx)201 void n_fq_bpoly_derivative_gen0(
202 n_bpoly_t A,
203 const n_bpoly_t B,
204 const fq_nmod_ctx_t ctx)
205 {
206 slong i;
207 slong Blen = B->length;
208
209 if (Blen < 2)
210 {
211 n_bpoly_zero(A);
212 return;
213 }
214
215 n_bpoly_fit_length(A, Blen - 1);
216
217 for (i = 1; i < Blen; i++)
218 n_fq_poly_scalar_mul_ui(A->coeffs + i - 1, B->coeffs + i, i, ctx);
219
220 A->length = Blen - 1;
221 n_bpoly_normalise(A);
222 }
223
224
n_fq_bpoly_scalar_mul_n_fq(n_fq_bpoly_t A,const mp_limb_t * c,const fq_nmod_ctx_t ctx)225 void n_fq_bpoly_scalar_mul_n_fq(
226 n_fq_bpoly_t A,
227 const mp_limb_t * c,
228 const fq_nmod_ctx_t ctx)
229 {
230 slong d = fq_nmod_ctx_degree(ctx);
231 slong i;
232
233 if (_n_fq_is_zero(c, d))
234 {
235 A->length = 0;
236 return;
237 }
238
239 if (_n_fq_is_one(c, d))
240 {
241 return;
242 }
243
244 for (i = 0; i < A->length; i++)
245 n_fq_poly_scalar_mul_n_fq(A->coeffs + i, A->coeffs + i, c, ctx);
246 }
247