1 /*
2     Copyright (C) 2011, 2012 Sebastian Pancratz
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 <http://www.gnu.org/licenses/>.
10 */
11 
12 #include "padic.h"
13 #include "ulong_extras.h"
14 #include "long_extras.h"
15 
main(void)16 int main(void)
17 {
18     int i, result;
19     FLINT_TEST_INIT(state);
20 
21     flint_printf("sqrt... ");
22     fflush(stdout);
23 
24 
25 
26 /* PRIME p = 2 ***************************************************************/
27 
28     /* Check aliasing: a = sqrt(a) */
29     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
30     {
31         fmpz_t p;
32         slong N;
33         padic_ctx_t ctx;
34 
35         int ans1, ans2;
36         padic_t a, d;
37 
38         fmpz_init_set_ui(p, 2);
39         N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN)
40             + PADIC_TEST_PREC_MIN;
41         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
42 
43         padic_init2(a, N);
44         padic_init2(d, N);
45 
46         padic_randtest(a, state, ctx);
47 
48         ans1 = padic_sqrt(d, a, ctx);
49         ans2 = padic_sqrt(a, a, ctx);
50 
51         result = ((ans1 == ans2) && (!ans1 || padic_equal(a, d)));
52         if (!result)
53         {
54             flint_printf("FAIL (aliasing):\n\n");
55             flint_printf("p = "), fmpz_print(p), flint_printf("\n");
56             flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
57             flint_printf("d = "), padic_print(d, ctx), flint_printf("\n");
58             abort();
59         }
60 
61         padic_clear(a);
62         padic_clear(d);
63 
64         fmpz_clear(p);
65         padic_ctx_clear(ctx);
66     }
67 
68     /* Test random elements */
69     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
70     {
71         fmpz_t p;
72         slong N;
73         padic_ctx_t ctx;
74 
75         int ans;
76         padic_t a, b, d;
77 
78         fmpz_init_set_ui(p, 2);
79         N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN)
80             + PADIC_TEST_PREC_MIN;
81         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
82 
83         padic_init2(a, N);
84         padic_init2(b, N);
85         padic_init2(d, N);
86 
87         padic_randtest(a, state, ctx);
88 
89         ans = padic_sqrt(b, a, ctx);
90 
91         padic_mul(d, b, b, ctx);
92 
93         if (ans && padic_val(a) < 0)
94         {
95             slong N2 = N + padic_val(a);
96             padic_t a2, d2;
97 
98             padic_init2(a2, N2);
99             padic_init2(d2, N2);
100 
101             padic_set(a2, a, ctx);
102             padic_set(d2, d, ctx);
103 
104             result = (padic_equal(a2, d2));
105             if (!result)
106             {
107                 flint_printf("FAIL (random elements):\n\n");
108                 flint_printf("a  = "), padic_print(a, ctx),  flint_printf("\n");
109                 flint_printf("b  = "), padic_print(b, ctx),  flint_printf("\n");
110                 flint_printf("d  = "), padic_print(d, ctx),  flint_printf("\n");
111                 flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n");
112                 flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n");
113                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
114                 flint_printf("ans = %d\n", ans);
115                 abort();
116             }
117 
118             padic_clear(a2);
119             padic_clear(d2);
120         }
121         else
122         {
123             result = (!ans || padic_equal(a, d));
124             if (!result)
125             {
126                 flint_printf("FAIL (random elements):\n\n");
127                 flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
128                 flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
129                 flint_printf("d = "), padic_print(d, ctx), flint_printf("\n");
130                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
131                 flint_printf("ans = %d\n", ans);
132                 abort();
133             }
134         }
135 
136         padic_clear(a);
137         padic_clear(b);
138         padic_clear(d);
139 
140         fmpz_clear(p);
141         padic_ctx_clear(ctx);
142     }
143 
144     /* Test random squares */
145     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
146     {
147         fmpz_t p;
148         slong N;
149         padic_ctx_t ctx;
150 
151         int ans;
152         padic_t a, b, c, d;
153 
154         fmpz_init_set_ui(p, 2);
155         N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN)
156             + PADIC_TEST_PREC_MIN;
157         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
158 
159         padic_init2(a, N);
160         padic_init2(b, N);
161         padic_init2(c, N);
162         padic_init2(d, N);
163 
164         padic_randtest(b, state, ctx);
165         padic_mul(a, b, b, ctx);
166 
167         ans = padic_sqrt(c, a, ctx);
168 
169         padic_mul(d, c, c, ctx);
170 
171         if (ans && padic_val(a) < 0)
172         {
173             slong N2 = N + padic_val(a);
174             padic_t a2, d2;
175 
176             padic_init2(a2, N2);
177             padic_init2(d2, N2);
178 
179             padic_set(a2, a, ctx);
180             padic_set(d2, d, ctx);
181 
182             result = (padic_equal(a2, d2));
183             if (!result)
184             {
185                 flint_printf("FAIL (random elements):\n\n");
186                 flint_printf("a  = "), padic_print(a, ctx),  flint_printf("\n");
187                 flint_printf("b  = "), padic_print(b, ctx),  flint_printf("\n");
188                 flint_printf("c  = "), padic_print(c, ctx),  flint_printf("\n");
189                 flint_printf("d  = "), padic_print(d, ctx),  flint_printf("\n");
190                 flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n");
191                 flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n");
192                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
193                 flint_printf("ans = %d\n", ans);
194                 abort();
195             }
196 
197             padic_clear(a2);
198             padic_clear(d2);
199         }
200         else
201         {
202             result = (ans && padic_equal(a, d));
203             if (!result)
204             {
205                 flint_printf("FAIL (random squares):\n\n");
206                 flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
207                 flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
208                 flint_printf("c = "), padic_print(c, ctx), flint_printf("\n");
209                 flint_printf("d = "), padic_print(d, ctx), flint_printf("\n");
210                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
211                 flint_printf("ans = %d\n", ans);
212                 abort();
213             }
214         }
215 
216         padic_clear(a);
217         padic_clear(b);
218         padic_clear(c);
219         padic_clear(d);
220 
221         fmpz_clear(p);
222         padic_ctx_clear(ctx);
223     }
224 
225 /* PRIME p > 2 ***************************************************************/
226 
227     /* Check aliasing: a = sqrt(a) */
228     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
229     {
230         fmpz_t p;
231         slong N;
232         padic_ctx_t ctx;
233 
234         int ans1, ans2;
235         padic_t a, d;
236 
237         fmpz_init_set_ui(p, n_randtest_prime(state, 0));
238         N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN)
239             + PADIC_TEST_PREC_MIN;
240         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
241 
242         padic_init2(a, N);
243         padic_init2(d, N);
244 
245         padic_randtest(a, state, ctx);
246 
247         ans1 = padic_sqrt(d, a, ctx);
248         ans2 = padic_sqrt(a, a, ctx);
249 
250         result = ((ans1 == ans2) && (!ans1 || padic_equal(a, d)));
251         if (!result)
252         {
253             flint_printf("FAIL (aliasing):\n\n");
254             flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
255             flint_printf("d = "), padic_print(d, ctx), flint_printf("\n");
256             abort();
257         }
258 
259         padic_clear(a);
260         padic_clear(d);
261 
262         fmpz_clear(p);
263         padic_ctx_clear(ctx);
264     }
265 
266     /* Test random elements */
267     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
268     {
269         fmpz_t p;
270         slong N;
271         padic_ctx_t ctx;
272 
273         int ans;
274         padic_t a, b, d;
275 
276         fmpz_init_set_ui(p, n_randtest_prime(state, 0));
277         N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN)
278             + PADIC_TEST_PREC_MIN;
279         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
280 
281         padic_init2(a, N);
282         padic_init2(b, N);
283         padic_init2(d, N);
284 
285         padic_randtest(a, state, ctx);
286 
287         ans = padic_sqrt(b, a, ctx);
288 
289         padic_mul(d, b, b, ctx);
290 
291         if (ans && padic_val(a) < 0)
292         {
293             slong N2 = N + padic_val(a);
294             padic_t a2, d2;
295 
296             padic_init2(a2, N2);
297             padic_init2(d2, N2);
298 
299             padic_set(a2, a, ctx);
300             padic_set(d2, d, ctx);
301 
302             result = (padic_equal(a2, d2));
303             if (!result)
304             {
305                 flint_printf("FAIL (random elements):\n\n");
306                 flint_printf("a  = "), padic_print(a, ctx),  flint_printf("\n");
307                 flint_printf("b  = "), padic_print(b, ctx),  flint_printf("\n");
308                 flint_printf("d  = "), padic_print(d, ctx),  flint_printf("\n");
309                 flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n");
310                 flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n");
311                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
312                 flint_printf("ans = %d\n", ans);
313                 abort();
314             }
315 
316             padic_clear(a2);
317             padic_clear(d2);
318         }
319         else
320         {
321             result = (!ans || padic_equal(a, d));
322             if (!result)
323             {
324                 flint_printf("FAIL (random elements):\n\n");
325                 flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
326                 flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
327                 flint_printf("d = "), padic_print(d, ctx), flint_printf("\n");
328                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
329                 flint_printf("ans = %d\n", ans);
330                 abort();
331             }
332         }
333 
334         padic_clear(a);
335         padic_clear(b);
336         padic_clear(d);
337 
338         fmpz_clear(p);
339         padic_ctx_clear(ctx);
340     }
341 
342     /* Test random squares */
343     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
344     {
345         fmpz_t p;
346         slong N;
347         padic_ctx_t ctx;
348 
349         int ans;
350         padic_t a, b, c, d;
351 
352         fmpz_init_set_ui(p, n_randtest_prime(state, 0));
353         N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN)
354             + PADIC_TEST_PREC_MIN;
355         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
356 
357         padic_init2(a, N);
358         padic_init2(b, N);
359         padic_init2(c, N);
360         padic_init2(d, N);
361 
362         padic_randtest(b, state, ctx);
363         padic_mul(a, b, b, ctx);
364 
365         ans = padic_sqrt(c, a, ctx);
366 
367         padic_mul(d, c, c, ctx);
368 
369         if (ans && padic_val(a) < 0)
370         {
371             slong N2 = N + padic_val(a);
372             padic_t a2, d2;
373 
374             padic_init2(a2, N2);
375             padic_init2(d2, N2);
376             padic_set(a2, a, ctx);
377             padic_set(d2, d, ctx);
378 
379             result = (padic_equal(a2, d2));
380             if (!result)
381             {
382                 flint_printf("FAIL (random elements):\n\n");
383                 flint_printf("a  = "), padic_print(a, ctx),  flint_printf("\n");
384                 flint_printf("b  = "), padic_print(b, ctx),  flint_printf("\n");
385                 flint_printf("c  = "), padic_print(c, ctx),  flint_printf("\n");
386                 flint_printf("d  = "), padic_print(d, ctx),  flint_printf("\n");
387                 flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n");
388                 flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n");
389                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
390                 flint_printf("ans = %d\n", ans);
391                 abort();
392             }
393 
394             padic_clear(a2);
395             padic_clear(d2);
396         }
397         else
398         {
399             result = (ans && padic_equal(a, d));
400             if (!result)
401             {
402                 flint_printf("FAIL (random squares):\n\n");
403                 flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
404                 flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
405                 flint_printf("c = "), padic_print(c, ctx), flint_printf("\n");
406                 flint_printf("d = "), padic_print(d, ctx), flint_printf("\n");
407                 flint_printf("p = "), fmpz_print(p), flint_printf("\n");
408                 flint_printf("ans = %d\n", ans);
409                 abort();
410             }
411         }
412 
413         padic_clear(a);
414         padic_clear(b);
415         padic_clear(c);
416         padic_clear(d);
417 
418         fmpz_clear(p);
419         padic_ctx_clear(ctx);
420     }
421 
422     FLINT_TEST_CLEANUP(state);
423 
424     flint_printf("PASS\n");
425     return EXIT_SUCCESS;
426 }
427