1 /*
2     Copyright (C) 2018-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 "fmpq_mpoly.h"
15 
16 int
main(void)17 main(void)
18 {
19     int i, j, result;
20     FLINT_TEST_INIT(state);
21 
22     flint_printf("add/sub....");
23     fflush(stdout);
24 
25     /* Check (f + g) - g = f */
26     for (i = 0; i < 10 * flint_test_multiplier(); i++)
27     {
28         fmpq_mpoly_ctx_t ctx;
29         fmpq_mpoly_t f, g, h, k;
30         slong len, len1, len2;
31         flint_bitcnt_t coeff_bits, exp_bits, exp_bits1, exp_bits2;
32 
33         fmpq_mpoly_ctx_init_rand(ctx, state, 20);
34 
35         fmpq_mpoly_init(f, ctx);
36         fmpq_mpoly_init(g, ctx);
37         fmpq_mpoly_init(h, ctx);
38         fmpq_mpoly_init(k, ctx);
39 
40         len = n_randint(state, 100);
41         len1 = n_randint(state, 100);
42         len2 = n_randint(state, 100);
43 
44         exp_bits = n_randint(state, 200) + 2;
45         exp_bits1 = n_randint(state, 200) + 2;
46         exp_bits2 = n_randint(state, 200) + 2;
47 
48         coeff_bits = n_randint(state, 200);
49 
50         for (j = 0; j < 4; j++)
51         {
52             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
53             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
54             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
55             fmpq_mpoly_randtest_bits(k, state, len, coeff_bits, exp_bits, ctx);
56 
57             fmpq_mpoly_add(h, g, f, ctx);
58             fmpq_mpoly_sub(k, h, g, ctx);
59             result = fmpq_mpoly_equal(f, k, ctx);
60 
61             if (!result)
62             {
63                 printf("FAIL\n");
64                 flint_printf("Check (f + g) - g = f\ni = %wd, j = %wd\n", i ,j);
65                 flint_abort();
66             }
67         }
68 
69         fmpq_mpoly_clear(f, ctx);
70         fmpq_mpoly_clear(g, ctx);
71         fmpq_mpoly_clear(h, ctx);
72         fmpq_mpoly_clear(k, ctx);
73         fmpq_mpoly_ctx_clear(ctx);
74     }
75 
76     /* Check f + g = g + f */
77     for (i = 0; i < 10 * flint_test_multiplier(); i++)
78     {
79         fmpq_mpoly_ctx_t ctx;
80         fmpq_mpoly_t f, g, h, k;
81         slong len, len1, len2;
82         flint_bitcnt_t coeff_bits, exp_bits, exp_bits1, exp_bits2;
83 
84         fmpq_mpoly_ctx_init_rand(ctx, state, 20);
85 
86         fmpq_mpoly_init(f, ctx);
87         fmpq_mpoly_init(g, ctx);
88         fmpq_mpoly_init(h, ctx);
89         fmpq_mpoly_init(k, ctx);
90 
91         len = n_randint(state, 100);
92         len1 = n_randint(state, 100);
93         len2 = n_randint(state, 100);
94 
95         exp_bits = n_randint(state, 200) + 2;
96         exp_bits1 = n_randint(state, 200) + 2;
97         exp_bits2 = n_randint(state, 200) + 2;
98 
99         coeff_bits = n_randint(state, 200);
100 
101         for (j = 0; j < 4; j++)
102         {
103             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
104             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
105             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
106             fmpq_mpoly_randtest_bits(k, state, len, coeff_bits, exp_bits, ctx);
107 
108             fmpq_mpoly_add(h, f, g, ctx);
109             fmpq_mpoly_add(k, g, f, ctx);
110             result = fmpq_mpoly_equal(h, k, ctx);
111 
112             if (!result)
113             {
114                 printf("FAIL\n");
115                 flint_printf("Check f + g = g + f\ni = %wd, j = %wd\n", i ,j);
116                 flint_abort();
117             }
118         }
119 
120         fmpq_mpoly_clear(f, ctx);
121         fmpq_mpoly_clear(g, ctx);
122         fmpq_mpoly_clear(h, ctx);
123         fmpq_mpoly_clear(k, ctx);
124         fmpq_mpoly_ctx_clear(ctx);
125     }
126 
127     /* Check f - g = -g + f */
128     for (i = 0; i < 10 * flint_test_multiplier(); i++)
129     {
130         fmpq_mpoly_ctx_t ctx;
131         fmpq_mpoly_t f, g, h, k;
132         slong len, len1, len2;
133         flint_bitcnt_t coeff_bits, exp_bits, exp_bits1, exp_bits2;
134 
135         fmpq_mpoly_ctx_init_rand(ctx, state, 20);
136 
137         fmpq_mpoly_init(f, ctx);
138         fmpq_mpoly_init(g, ctx);
139         fmpq_mpoly_init(h, ctx);
140         fmpq_mpoly_init(k, ctx);
141 
142         len = n_randint(state, 100);
143         len1 = n_randint(state, 100);
144         len2 = n_randint(state, 100);
145 
146         exp_bits = n_randint(state, 200) + 2;
147         exp_bits1 = n_randint(state, 200) + 2;
148         exp_bits2 = n_randint(state, 200) + 2;
149 
150         coeff_bits = n_randint(state, 200);
151 
152         for (j = 0; j < 10; j++)
153         {
154             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
155             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
156             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
157             fmpq_mpoly_randtest_bits(k, state, len, coeff_bits, exp_bits, ctx);
158 
159             fmpq_mpoly_sub(h, f, g, ctx);
160             fmpq_mpoly_neg(k, g, ctx);
161             fmpq_mpoly_add(k, k, f, ctx);
162             result = fmpq_mpoly_equal(h, k, ctx);
163 
164             if (!result)
165             {
166                 printf("FAIL\n");
167                 flint_printf("Check f - g = -g + f\ni = %wd, j = %wd\n", i ,j);
168                 flint_abort();
169             }
170         }
171 
172         fmpq_mpoly_clear(f, ctx);
173         fmpq_mpoly_clear(g, ctx);
174         fmpq_mpoly_clear(h, ctx);
175         fmpq_mpoly_clear(k, ctx);
176         fmpq_mpoly_ctx_clear(ctx);
177     }
178 
179     /* Check f + (g + h) = (f + g) + h */
180     for (i = 0; i < 10 * flint_test_multiplier(); i++)
181     {
182         fmpq_mpoly_ctx_t ctx;
183         fmpq_mpoly_t f, g, h, k1, k2;
184         slong len, len1, len2;
185         flint_bitcnt_t coeff_bits, exp_bits, exp_bits1, exp_bits2;
186 
187         fmpq_mpoly_ctx_init_rand(ctx, state, 20);
188 
189         fmpq_mpoly_init(f, ctx);
190         fmpq_mpoly_init(g, ctx);
191         fmpq_mpoly_init(h, ctx);
192         fmpq_mpoly_init(k1, ctx);
193         fmpq_mpoly_init(k2, ctx);
194 
195         len = n_randint(state, 100);
196         len1 = n_randint(state, 100);
197         len2 = n_randint(state, 100);
198 
199         exp_bits = n_randint(state, 200) + 2;
200         exp_bits1 = n_randint(state, 200) + 2;
201         exp_bits2 = n_randint(state, 200) + 2;
202 
203         coeff_bits = n_randint(state, 200);
204 
205         for (j = 0; j < 4; j++)
206         {
207             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
208             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
209             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
210             fmpq_mpoly_randtest_bits(k1, state, len, coeff_bits, exp_bits, ctx);
211             fmpq_mpoly_randtest_bits(k2, state, len, coeff_bits, exp_bits, ctx);
212 
213             fmpq_mpoly_add(k1, f, g, ctx);
214             fmpq_mpoly_add(k1, k1, h, ctx);
215             fmpq_mpoly_add(k2, g, h, ctx);
216             fmpq_mpoly_add(k2, k2, f, ctx);
217             result = fmpq_mpoly_equal(k1, k2, ctx);
218 
219             if (!result)
220             {
221                 printf("FAIL\n");
222                 flint_printf("Check f + (g + h) = (f + g) + h\ni = %wd, j = %wd\n", i ,j);
223                 flint_abort();
224             }
225         }
226 
227         fmpq_mpoly_clear(f, ctx);
228         fmpq_mpoly_clear(g, ctx);
229         fmpq_mpoly_clear(h, ctx);
230         fmpq_mpoly_clear(k1, ctx);
231         fmpq_mpoly_clear(k2, ctx);
232         fmpq_mpoly_ctx_clear(ctx);
233     }
234 
235     /* Check f - (g + h) = (f - g) - h */
236     for (i = 0; i < 10 * flint_test_multiplier(); i++)
237     {
238         fmpq_mpoly_ctx_t ctx;
239         fmpq_mpoly_t f, g, h, k1, k2;
240         slong len, len1, len2;
241         flint_bitcnt_t coeff_bits, exp_bits, exp_bits1, exp_bits2;
242 
243         fmpq_mpoly_ctx_init_rand(ctx, state, 20);
244 
245         fmpq_mpoly_init(f, ctx);
246         fmpq_mpoly_init(g, ctx);
247         fmpq_mpoly_init(h, ctx);
248         fmpq_mpoly_init(k1, ctx);
249         fmpq_mpoly_init(k2, ctx);
250 
251         len = n_randint(state, 100);
252         len1 = n_randint(state, 100);
253         len2 = n_randint(state, 100);
254 
255         exp_bits = n_randint(state, 200) + 2;
256         exp_bits1 = n_randint(state, 200) + 2;
257         exp_bits2 = n_randint(state, 200) + 2;
258 
259         coeff_bits = n_randint(state, 200);
260 
261         for (j = 0; j < 4; j++)
262         {
263             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
264             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
265             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
266             fmpq_mpoly_randtest_bits(k1, state, len, coeff_bits, exp_bits, ctx);
267             fmpq_mpoly_randtest_bits(k2, state, len, coeff_bits, exp_bits, ctx);
268 
269             fmpq_mpoly_add(k1, g, h, ctx);
270             fmpq_mpoly_sub(k1, f, k1, ctx);
271             fmpq_mpoly_sub(k2, f, g, ctx);
272             fmpq_mpoly_sub(k2, k2, h, ctx);
273             result = fmpq_mpoly_equal(k1, k2, ctx);
274 
275             if (!result)
276             {
277                 printf("FAIL\n");
278                 flint_printf("Check f - (g + h) = (f - g) - h\ni = %wd, j = %wd\n", i ,j);
279                 flint_abort();
280             }
281         }
282 
283         fmpq_mpoly_clear(f, ctx);
284         fmpq_mpoly_clear(g, ctx);
285         fmpq_mpoly_clear(h, ctx);
286         fmpq_mpoly_clear(k1, ctx);
287         fmpq_mpoly_clear(k2, ctx);
288         fmpq_mpoly_ctx_clear(ctx);
289     }
290 
291     /* Check aliasing */
292     for (i = 0; i < 50 * flint_test_multiplier(); i++)
293     {
294         fmpq_mpoly_ctx_t ctx;
295         fmpq_mpoly_t f, g, h;
296         slong len, len1, len2;
297         flint_bitcnt_t coeff_bits, exp_bits, exp_bits1, exp_bits2;
298 
299         fmpq_mpoly_ctx_init_rand(ctx, state, 20);
300 
301         fmpq_mpoly_init(f, ctx);
302         fmpq_mpoly_init(g, ctx);
303         fmpq_mpoly_init(h, ctx);
304 
305         len = n_randint(state, 100);
306         len1 = n_randint(state, 100);
307         len2 = n_randint(state, 100);
308 
309         exp_bits = n_randint(state, 200) + 2;
310         exp_bits1 = n_randint(state, 200) + 2;
311         exp_bits2 = n_randint(state, 200) + 2;
312 
313         coeff_bits = n_randint(state, 200);
314 
315         for (j = 0; j < 4; j++)
316         {
317             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
318             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
319             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
320 
321             if ((j % 2) == 0)
322             {
323                 fmpq_mpoly_add(h, g, f, ctx);
324                 fmpq_mpoly_assert_canonical(h, ctx);
325                 fmpq_mpoly_add(f, g, f, ctx);
326                 fmpq_mpoly_assert_canonical(f, ctx);
327             }
328             else
329             {
330                 fmpq_mpoly_sub(h, g, f, ctx);
331                 fmpq_mpoly_assert_canonical(h, ctx);
332                 fmpq_mpoly_sub(f, g, f, ctx);
333                 fmpq_mpoly_assert_canonical(f, ctx);
334             }
335             result = fmpq_mpoly_equal(f, h, ctx);
336 
337             if (!result)
338             {
339                 printf("FAIL\n");
340                 flint_printf("Check aliasing second arg\ni = %wd, j = %wd\n", i ,j);
341                 flint_abort();
342             }
343 
344             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
345             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
346             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
347 
348             if ((j % 2) == 0)
349             {
350                 fmpq_mpoly_add(h, g, f, ctx);
351                 fmpq_mpoly_assert_canonical(h, ctx);
352                 fmpq_mpoly_add(g, g, f, ctx);
353                 fmpq_mpoly_assert_canonical(f, ctx);
354             }
355             else
356             {
357                 fmpq_mpoly_sub(h, g, f, ctx);
358                 fmpq_mpoly_assert_canonical(h, ctx);
359                 fmpq_mpoly_sub(g, g, f, ctx);
360                 fmpq_mpoly_assert_canonical(f, ctx);
361             }
362             result = fmpq_mpoly_equal(g, h, ctx);
363 
364             if (!result)
365             {
366                 printf("FAIL\n");
367                 flint_printf("Check aliasing first arg\ni = %wd, j = %wd\n", i ,j);
368                 flint_abort();
369             }
370 
371             fmpq_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
372             fmpq_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
373             fmpq_mpoly_randtest_bits(h, state, len, coeff_bits, exp_bits, ctx);
374 
375             if ((j % 2) == 0)
376             {
377                 fmpq_mpoly_add(h, f, f, ctx);
378                 fmpq_mpoly_assert_canonical(h, ctx);
379                 fmpq_mpoly_add(f, f, f, ctx);
380                 fmpq_mpoly_assert_canonical(f, ctx);
381             }
382             else
383             {
384                 fmpq_mpoly_sub(h, f, f, ctx);
385                 fmpq_mpoly_assert_canonical(h, ctx);
386                 fmpq_mpoly_sub(f, f, f, ctx);
387                 fmpq_mpoly_assert_canonical(f, ctx);
388             }
389             result = fmpq_mpoly_equal(f, h, ctx);
390 
391             if (!result)
392             {
393                 printf("FAIL\n");
394                 flint_printf("Check aliasing both args\ni = %wd, j = %wd\n", i ,j);
395                 flint_abort();
396             }
397         }
398 
399         fmpq_mpoly_clear(f, ctx);
400         fmpq_mpoly_clear(g, ctx);
401         fmpq_mpoly_clear(h, ctx);
402         fmpq_mpoly_ctx_clear(ctx);
403     }
404 
405     FLINT_TEST_CLEANUP(state);
406 
407     flint_printf("PASS\n");
408     return 0;
409 }
410