1 /*
2     Copyright (C) 2018 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 "nmod_mpoly.h"
15 
16 int
main(void)17 main(void)
18 {
19     slong i, j, v;
20     int tmul = 20;
21     FLINT_TEST_INIT(state);
22 
23     flint_printf("evaluate....");
24     fflush(stdout);
25 
26     /* Check repeated evalone matches evalall */
27     for (i = 0; i < tmul * flint_test_multiplier(); i++)
28     {
29         nmod_mpoly_ctx_t ctx;
30         nmod_mpoly_t f, g;
31         mp_limb_t fe;
32         mp_limb_t * vals;
33         slong * perm;
34         slong nvars, len;
35         flint_bitcnt_t exp_bits;
36         mp_limb_t modulus;
37 
38         modulus = n_randint(state, FLINT_BITS - 1) + 1;
39         modulus = n_randbits(state, modulus);
40         nmod_mpoly_ctx_init_rand(ctx, state, 20, modulus);
41         nvars = ctx->minfo->nvars;
42 
43         nmod_mpoly_init(f, ctx);
44         nmod_mpoly_init(g, ctx);
45 
46         len = n_randint(state, 50);
47         exp_bits = n_randint(state, 200) + 1;
48 
49         perm = (slong *) flint_malloc(nvars*sizeof(slong));
50         vals = (mp_limb_t *) flint_malloc(nvars*sizeof(mp_limb_t));
51         for (v = 0; v < nvars; v++)
52         {
53             vals[v] = n_randlimb(state);
54             perm[v] = v;
55         }
56 
57         for (j = 0; j < 2*nvars; j++)
58         {
59             slong a, b, c;
60             a = n_randint(state, nvars);
61             b = n_randint(state, nvars);
62             c = perm[a];
63             perm[a] = perm[b];
64             perm[b] = c;
65         }
66 
67         for (j = 0; j < 4; j++)
68         {
69             nmod_mpoly_randtest_bits(f, state, len, exp_bits, ctx);
70             fe = nmod_mpoly_evaluate_all_ui(f, vals, ctx);
71 
72             for (v = 0; v < nvars; v++)
73             {
74                 nmod_mpoly_evaluate_one_ui(g, f, perm[v], vals[perm[v]], ctx);
75                 nmod_mpoly_assert_canonical(g, ctx);
76                 nmod_mpoly_evaluate_one_ui(f, f, perm[v], vals[perm[v]], ctx);
77                 nmod_mpoly_assert_canonical(f, ctx);
78                 if (!nmod_mpoly_equal(f, g, ctx))
79                 {
80                     printf("FAIL\n");
81                     flint_printf("Check evalone aliasing\ni: %wd  j: %wd\n", i, j);
82                     flint_abort();
83                 }
84             }
85             if (!nmod_mpoly_equal_ui(f, fe, ctx))
86             {
87                 printf("FAIL\n");
88                 flint_printf("Check repeated evalone matches evalall\ni: %wd  j: %wd\n", i, j);
89                 flint_abort();
90             }
91         }
92 
93         flint_free(vals);
94 
95         nmod_mpoly_clear(f, ctx);
96         nmod_mpoly_clear(g, ctx);
97         nmod_mpoly_ctx_clear(ctx);
98 
99         flint_free(perm);
100     }
101 
102 
103     /* Check add commutes with evalall */
104     for (i = 0; i < tmul * flint_test_multiplier(); i++)
105     {
106         nmod_mpoly_ctx_t ctx;
107         nmod_mpoly_t f, g, fg;
108         mp_limb_t fe, ge, fge;
109         mp_limb_t * vals;
110         slong nvars, len1, len2;
111         flint_bitcnt_t exp_bits1, exp_bits2;
112         mp_limb_t modulus;
113 
114         modulus = n_randint(state, FLINT_BITS - 1) + 1;
115         modulus = n_randbits(state, modulus);
116         nmod_mpoly_ctx_init_rand(ctx, state, 20, modulus);
117         nvars = ctx->minfo->nvars;
118 
119         nmod_mpoly_init(f, ctx);
120         nmod_mpoly_init(g, ctx);
121         nmod_mpoly_init(fg, ctx);
122 
123         len1 = n_randint(state, 100);
124         len2 = n_randint(state, 100);
125         exp_bits1 = n_randint(state, 200) + 1;
126         exp_bits2 = n_randint(state, 200) + 1;
127 
128         vals = (mp_limb_t *) flint_malloc(nvars*sizeof(mp_limb_t));
129         for (v = 0; v < nvars; v++)
130         {
131             vals[v] = n_randlimb(state);
132         }
133 
134         for (j = 0; j < 4; j++)
135         {
136             nmod_mpoly_randtest_bits(f, state, len1, exp_bits1, ctx);
137             nmod_mpoly_randtest_bits(g, state, len2, exp_bits2, ctx);
138             nmod_mpoly_add(fg, f, g, ctx);
139 
140             fe = nmod_mpoly_evaluate_all_ui(f, vals, ctx);
141             ge = nmod_mpoly_evaluate_all_ui(g, vals, ctx);
142             fge = nmod_mpoly_evaluate_all_ui(fg, vals, ctx);
143 
144             if (fge != nmod_add(fe, ge, ctx->mod))
145             {
146                 printf("FAIL\n");
147                 flint_printf("Check add commutes with evalall\ni: %wd  j: %wd\n", i, j);
148                 flint_abort();
149             }
150         }
151 
152         flint_free(vals);
153 
154         nmod_mpoly_clear(f, ctx);
155         nmod_mpoly_clear(g, ctx);
156         nmod_mpoly_clear(fg, ctx);
157         nmod_mpoly_ctx_clear(ctx);
158     }
159 
160     /* Check mul commutes with evalall */
161     for (i = 0; i < tmul * flint_test_multiplier(); i++)
162     {
163         nmod_mpoly_ctx_t ctx;
164         nmod_mpoly_t f, g, fg;
165         mp_limb_t fe, ge, fge;
166         mp_limb_t * vals;
167         slong nvars, len1, len2;
168         flint_bitcnt_t exp_bits1, exp_bits2;
169         mp_limb_t modulus;
170 
171         modulus = n_randint(state, FLINT_BITS - 1) + 1;
172         modulus = n_randbits(state, modulus);
173         nmod_mpoly_ctx_init_rand(ctx, state, 20, modulus);
174         nvars = ctx->minfo->nvars;
175 
176         nmod_mpoly_init(f, ctx);
177         nmod_mpoly_init(g, ctx);
178         nmod_mpoly_init(fg, ctx);
179 
180         len1 = n_randint(state, 20);
181         len2 = n_randint(state, 20);
182         exp_bits1 = n_randint(state, 200) + 1;
183         exp_bits2 = n_randint(state, 200) + 1;
184 
185         vals = (mp_limb_t *) flint_malloc(nvars*sizeof(mp_limb_t));
186         for (v = 0; v < nvars; v++)
187         {
188             vals[v] = n_randlimb(state);
189         }
190 
191         for (j = 0; j < 4; j++)
192         {
193             nmod_mpoly_randtest_bits(f, state, len1, exp_bits1, ctx);
194             nmod_mpoly_randtest_bits(g, state, len2, exp_bits2, ctx);
195             nmod_mpoly_add(fg, f, g, ctx);
196 
197             fe = nmod_mpoly_evaluate_all_ui(f, vals, ctx);
198             ge = nmod_mpoly_evaluate_all_ui(g, vals, ctx);
199             fge = nmod_mpoly_evaluate_all_ui(fg, vals, ctx);
200 
201             if (fge != nmod_add(fe, ge, ctx->mod))
202             {
203                 printf("FAIL\n");
204                 flint_printf("Check mul commutes with evalall\ni: %wd  j: %wd\n", i, j);
205                 flint_abort();
206             }
207         }
208 
209         flint_free(vals);
210 
211         nmod_mpoly_clear(f, ctx);
212         nmod_mpoly_clear(g, ctx);
213         nmod_mpoly_clear(fg, ctx);
214         nmod_mpoly_ctx_clear(ctx);
215     }
216 
217     printf("PASS\n");
218     FLINT_TEST_CLEANUP(state);
219 
220     return 0;
221 }
222