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 <stdio.h>
13 #include <stdlib.h>
14 #include "fmpz_mod_mpoly.h"
15 
_test_root(fmpz_mod_mpoly_t x,const fmpz_mod_mpoly_t a,const fmpz_mod_mpoly_t b,const fmpz_mod_mpoly_ctx_t ctx,int sol_exists)16 void _test_root(
17     fmpz_mod_mpoly_t x,
18     const fmpz_mod_mpoly_t a,
19     const fmpz_mod_mpoly_t b,
20     const fmpz_mod_mpoly_ctx_t ctx,
21     int sol_exists)
22 {
23     int success, success2;
24     fmpz_mod_mpoly_t s, t;
25 
26     fmpz_mod_mpoly_init(s, ctx);
27     fmpz_mod_mpoly_init(t, ctx);
28 
29     success = fmpz_mod_mpoly_quadratic_root(x, a, b, ctx);
30 
31     if (sol_exists && !success)
32     {
33         flint_printf("FAIL: solution exists but root failed\n");
34         flint_abort();
35     }
36 
37     if (success)
38     {
39         fmpz_mod_mpoly_add(t, x, a, ctx);
40         fmpz_mod_mpoly_mul(s, t, x, ctx);
41         if (!fmpz_mod_mpoly_equal(s, b, ctx))
42         {
43 
44             flint_printf("FAIL: reported solution is not a solution\n");
45             flint_abort();
46         }
47     }
48 
49     fmpz_mod_mpoly_set(t, a, ctx);
50     success2 = fmpz_mod_mpoly_quadratic_root(t, t, b, ctx);
51     if (success != success2 || (success && !fmpz_mod_mpoly_equal(x, t, ctx)))
52     {
53         flint_printf("FAIL: Check aliasing first argument\n");
54         flint_abort();
55     }
56 
57     fmpz_mod_mpoly_set(t, b, ctx);
58     success2 = fmpz_mod_mpoly_quadratic_root(t, a, t, ctx);
59     if (success != success2 || (success && !fmpz_mod_mpoly_equal(x, t, ctx)))
60     {
61         flint_printf("FAIL: Check aliasing second argument\n");
62         flint_abort();
63     }
64 
65     fmpz_mod_mpoly_clear(s, ctx);
66     fmpz_mod_mpoly_clear(t, ctx);
67 }
68 
69 int
main(void)70 main(void)
71 {
72     slong i, j, tmul = 20;
73     FLINT_TEST_INIT(state);
74 
75     flint_printf("quadratic_root....");
76     fflush(stdout);
77 
78     for (i = 0; i < tmul * flint_test_multiplier(); i++)
79     {
80         fmpz_mod_mpoly_ctx_t ctx;
81         fmpz_mod_mpoly_t f, a, b, x;
82         slong len, len1;
83         flint_bitcnt_t exp_bits, exp_bits1;
84 
85         fmpz_mod_mpoly_ctx_init_rand_bits_prime(ctx, state, 10, 100);
86 
87         fmpz_mod_mpoly_init(f, ctx);
88         fmpz_mod_mpoly_init(a, ctx);
89         fmpz_mod_mpoly_init(b, ctx);
90         fmpz_mod_mpoly_init(x, ctx);
91 
92         for (j = 0; j < 5; j++)
93         {
94             len = n_randint(state, 100);
95             len1 = n_randint(state, 100) + 1;
96             exp_bits =  n_randint(state, 100) + 1;
97             exp_bits1 = n_randint(state, 100) + 1;
98             fmpz_mod_mpoly_randtest_bits(a, state, len1, exp_bits1, ctx);
99             fmpz_mod_mpoly_randtest_bits(f, state, len, exp_bits, ctx);
100             fmpz_mod_mpoly_add(b, f, a, ctx);
101             fmpz_mod_mpoly_mul(b, b, f, ctx);
102             _test_root(x, a, b, ctx, 1);
103 
104             len = n_randint(state, 50);
105             len1 = n_randint(state, 50) + 1;
106             exp_bits =  n_randint(state, 20) + 1;
107             exp_bits1 = n_randint(state, 20) + 1;
108             fmpz_mod_mpoly_randtest_bits(a, state, len1, 10, ctx);
109             fmpz_mod_mpoly_randtest_bits(b, state, len, 10, ctx);
110             _test_root(x, a, b, ctx, 0);
111         }
112 
113         fmpz_mod_mpoly_clear(f, ctx);
114         fmpz_mod_mpoly_clear(a, ctx);
115         fmpz_mod_mpoly_clear(b, ctx);
116         fmpz_mod_mpoly_clear(x, ctx);
117         fmpz_mod_mpoly_ctx_clear(ctx);
118     }
119 
120     FLINT_TEST_CLEANUP(state);
121 
122     flint_printf("PASS\n");
123     return 0;
124 }
125 
126