1 /*
2     Copyright (C) 2009 William Hart
3     Copyright (C) 2011 Fredrik Johansson
4     Copyright (C) 2012 Lina Kulakova
5     Copyright (C) 2013 Martin Lee
6 
7     This file is part of FLINT.
8 
9     FLINT is free software: you can redistribute it and/or modify it under
10     the terms of the GNU Lesser General Public License (LGPL) as published
11     by the Free Software Foundation; either version 2.1 of the License, or
12     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
13 */
14 
15 #undef ulong
16 #define ulong ulongxx/* interferes with system includes */
17 
18 #include <stdlib.h>
19 #include <stdio.h>
20 
21 #undef ulong
22 
23 #include <gmp.h>
24 
25 #define ulong mp_limb_t
26 
27 #include "flint.h"
28 #include "fmpz_vec.h"
29 #include "fmpz_mod_poly.h"
30 #include "ulong_extras.h"
31 
32 int
main(void)33 main(void)
34 {
35     int i, result;
36     FLINT_TEST_INIT(state);
37 
38 
39     flint_printf("powmod_x_fmpz_preinv....");
40     fflush(stdout);
41 
42     /* No aliasing */
43     for (i = 0; i < 50 * flint_test_multiplier(); i++)
44     {
45         fmpz_mod_poly_t a, res1, res2, f, finv;
46         fmpz_t p;
47         ulong exp;
48         fmpz_t expz;
49 
50         fmpz_init(p);
51         fmpz_set_ui(p, n_randtest_prime(state, 0));
52         exp = n_randint(state, 50);
53 
54 
55         fmpz_mod_poly_init(f, p);
56         fmpz_mod_poly_init(finv, p);
57         fmpz_mod_poly_init(res1, p);
58         fmpz_mod_poly_init(res2, p);
59 
60         fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1);
61         fmpz_init_set_ui(expz, exp);
62 
63         fmpz_mod_poly_reverse (finv, f, f->length);
64         fmpz_mod_poly_inv_series_newton (finv, finv, f->length);
65 
66         fmpz_mod_poly_init2(a, p, f->length-1);
67         fmpz_mod_poly_set_coeff_ui (a, 1, 1);
68         fmpz_mod_poly_powmod_x_fmpz_preinv(res1, expz, f, finv);
69         fmpz_mod_poly_powmod_fmpz_binexp_preinv(res2, a, expz, f, finv);
70 
71         result = (fmpz_mod_poly_equal(res1, res2));
72         if (!result)
73         {
74             flint_printf("FAIL:\n");
75             flint_printf("expz:\n"); fmpz_print(expz), flint_printf("\n\n");
76             flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n");
77             flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n");
78             flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n");
79             flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n");
80             flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n");
81             abort();
82         }
83 
84         fmpz_clear(p);
85         fmpz_mod_poly_clear(a);
86         fmpz_mod_poly_clear(f);
87         fmpz_mod_poly_clear(res1);
88         fmpz_mod_poly_clear(res2);
89         fmpz_mod_poly_clear(finv);
90         fmpz_clear(expz);
91     }
92 
93     /* Aliasing of res and f */
94     for (i = 0; i < 25 * flint_test_multiplier(); i++)
95     {
96         fmpz_mod_poly_t res, f, finv;
97         fmpz_t p;
98         ulong exp;
99         fmpz_t expz;
100 
101         fmpz_init(p);
102         fmpz_set_ui(p, n_randtest_prime(state, 0));
103         exp = n_randint(state, 50);
104         fmpz_init_set_ui(expz, exp);
105 
106         fmpz_mod_poly_init(f, p);
107         fmpz_mod_poly_init(finv, p);
108         fmpz_mod_poly_init(res, p);
109 
110         fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1);
111 
112         fmpz_mod_poly_reverse (finv, f, f->length);
113         fmpz_mod_poly_inv_series_newton (finv, finv, f->length);
114 
115         fmpz_mod_poly_powmod_x_fmpz_preinv(res, expz, f, finv);
116         fmpz_mod_poly_powmod_x_fmpz_preinv(f, expz, f, finv);
117 
118         result = (fmpz_mod_poly_equal(res, f));
119         if (!result)
120         {
121             flint_printf("FAIL:\n");
122             flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n");
123             flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n");
124             flint_printf("expz:\n"); fmpz_print(expz), flint_printf("\n\n");
125             flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n");
126             abort();
127         }
128 
129         fmpz_clear(p);
130         fmpz_mod_poly_clear(f);
131         fmpz_mod_poly_clear(finv);
132         fmpz_mod_poly_clear(res);
133         fmpz_clear(expz);
134     }
135 
136     /* Aliasing of res and finv */
137     for (i = 0; i < 25 * flint_test_multiplier(); i++)
138     {
139         fmpz_mod_poly_t res, f, finv;
140         fmpz_t p;
141         ulong exp;
142         fmpz_t expz;
143 
144         fmpz_init(p);
145         fmpz_set_ui(p, n_randtest_prime(state, 0));
146         exp = n_randint(state, 50);
147         fmpz_init_set_ui(expz, exp);
148 
149         fmpz_mod_poly_init(f, p);
150         fmpz_mod_poly_init(finv, p);
151         fmpz_mod_poly_init(res, p);
152 
153         fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1);
154 
155 
156         fmpz_mod_poly_reverse (finv, f, f->length);
157         fmpz_mod_poly_inv_series_newton (finv, finv, f->length);
158 
159         fmpz_mod_poly_powmod_x_fmpz_preinv(res, expz, f, finv);
160         fmpz_mod_poly_powmod_x_fmpz_preinv(finv, expz, f, finv);
161 
162         result = (fmpz_mod_poly_equal(res, finv));
163         if (!result)
164         {
165             flint_printf("FAIL:\n");
166             flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n");
167             flint_printf("expz:\n"); fmpz_print(expz), flint_printf("\n\n");
168             flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n");
169             flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n");
170             abort();
171         }
172 
173         fmpz_clear(p);
174         fmpz_mod_poly_clear(f);
175         fmpz_mod_poly_clear(finv);
176         fmpz_mod_poly_clear(res);
177         fmpz_clear(expz);
178     }
179 
180     /* Check that x^(b+c) = x^b * x^c */
181     for (i = 0; i < 50 * flint_test_multiplier(); i++)
182     {
183         fmpz_mod_poly_t res1, res2, res3, res4, f, finv;
184         fmpz_t p;
185         fmpz_t exp1, exp2, exp3;
186 
187         fmpz_init(p);
188         fmpz_set_ui(p, n_randtest_prime(state, 0));
189 
190         fmpz_init(exp1);
191         fmpz_init(exp2);
192         fmpz_randtest(exp1, state, 200);
193         if (fmpz_sgn(exp1) == -1) fmpz_neg(exp1, exp1);
194         fmpz_randtest(exp2, state, 200);
195         if (fmpz_sgn(exp2) == -1) fmpz_neg(exp2, exp2);
196 
197         fmpz_mod_poly_init(f, p);
198         fmpz_mod_poly_init(finv, p);
199         fmpz_mod_poly_init(res1, p);
200         fmpz_mod_poly_init(res2, p);
201         fmpz_mod_poly_init(res3, p);
202         fmpz_mod_poly_init(res4, p);
203 
204         fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1);
205 
206         fmpz_mod_poly_reverse (finv, f, f->length);
207         fmpz_mod_poly_inv_series_newton (finv, finv, f->length);
208 
209         fmpz_mod_poly_powmod_x_fmpz_preinv(res1, exp1, f, finv);
210         fmpz_mod_poly_powmod_x_fmpz_preinv(res2, exp2, f, finv);
211         fmpz_mod_poly_mulmod(res4, res1, res2, f);
212         fmpz_init(exp3);
213         fmpz_add(exp3, exp1, exp2);
214         fmpz_mod_poly_powmod_x_fmpz_preinv(res3, exp3, f, finv);
215 
216         result = (fmpz_mod_poly_equal(res4, res3));
217         if (!result)
218         {
219             flint_printf("FAIL:\n");
220             flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n");
221             flint_printf("res3:\n"); fmpz_mod_poly_print(res3), flint_printf("\n\n");
222             flint_printf("res4:\n"); fmpz_mod_poly_print(res4), flint_printf("\n\n");
223             abort();
224         }
225 
226         fmpz_clear(p);
227         fmpz_mod_poly_clear(f);
228         fmpz_mod_poly_clear(finv);
229         fmpz_mod_poly_clear(res1);
230         fmpz_mod_poly_clear(res2);
231         fmpz_mod_poly_clear(res3);
232         fmpz_mod_poly_clear(res4);
233         fmpz_clear(exp1);
234         fmpz_clear(exp2);
235         fmpz_clear(exp3);
236     }
237 
238     FLINT_TEST_CLEANUP(state);
239 
240     flint_printf("PASS\n");
241     return 0;
242 }
243