1 /*
2     Copyright (C) 2010 William Hart
3     Copyright (C) 2011 Fredrik Johansson
4 
5     This file is part of FLINT.
6 
7     FLINT is free software: you can redistribute it and/or modify it under
8     the terms of the GNU Lesser General Public License (LGPL) as published
9     by the Free Software Foundation; either version 2.1 of the License, or
10     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
11 */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <gmp.h>
16 #include "flint.h"
17 #include "nmod_poly.h"
18 #include "ulong_extras.h"
19 
20 int
main(void)21 main(void)
22 {
23     int i, result = 1;
24     FLINT_TEST_INIT(state);
25 
26 
27     flint_printf("exp_series_basecase....");
28     fflush(stdout);
29 
30     /* Check exp(A+B) = exp(A) * exp(B) */
31     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
32     {
33         nmod_poly_t A, B, AB, expA, expB, expAB, S;
34         slong n;
35         mp_limb_t mod;
36 
37         mod = n_randtest_prime(state, 0);
38         n = n_randtest(state) % 100;
39         n = FLINT_MIN(n, mod);
40 
41         nmod_poly_init(A, mod);
42         nmod_poly_init(B, mod);
43         nmod_poly_init(AB, mod);
44         nmod_poly_init(expA, mod);
45         nmod_poly_init(expB, mod);
46         nmod_poly_init(expAB, mod);
47         nmod_poly_init(S, mod);
48 
49         nmod_poly_randtest(A, state, n_randint(state, 100));
50         nmod_poly_set_coeff_ui(A, 0, UWORD(0));
51         nmod_poly_randtest(B, state, n_randint(state, 100));
52         nmod_poly_set_coeff_ui(B, 0, UWORD(0));
53 
54         if (n_randlimb(state) % 100 == 0)
55         {
56             nmod_poly_zero(A);
57             nmod_poly_set_coeff_ui(A, n_randlimb(state) % (n+5), \
58                 n_randtest_not_zero(state) % mod);
59             nmod_poly_set_coeff_ui(A, 0, UWORD(0));
60         }
61 
62         nmod_poly_exp_series_basecase(expA, A, n);
63         nmod_poly_exp_series_basecase(expB, B, n);
64         nmod_poly_add(AB, A, B);
65         nmod_poly_exp_series(expAB, AB, n);
66         nmod_poly_mullow(S, expA, expB, n);
67 
68         result = nmod_poly_equal(S, expAB);
69 
70         if (!result)
71         {
72             flint_printf("FAIL:\n");
73             flint_printf("n = %wd, mod = %wu\n", n, mod);
74             flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n");
75             flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n");
76             flint_printf("exp(A): "); nmod_poly_print(expA), flint_printf("\n\n");
77             flint_printf("exp(B): "); nmod_poly_print(expB), flint_printf("\n\n");
78             flint_printf("exp(A+B):       "); nmod_poly_print(expAB), flint_printf("\n\n");
79             flint_printf("exp(A)*exp(B): "); nmod_poly_print(S), flint_printf("\n\n");
80             abort();
81         }
82 
83         nmod_poly_clear(A);
84         nmod_poly_clear(B);
85         nmod_poly_clear(AB);
86         nmod_poly_clear(expA);
87         nmod_poly_clear(expB);
88         nmod_poly_clear(expAB);
89         nmod_poly_clear(S);
90     }
91 
92     /* Check aliasing */
93     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
94     {
95         nmod_poly_t A, B;
96         slong n;
97         mp_limb_t mod;
98         mod = n_randtest_prime(state, 0);
99         n = n_randtest(state) % 50;
100         n = FLINT_MIN(n, mod);
101 
102         nmod_poly_init(A, mod);
103         nmod_poly_init(B, mod);
104         nmod_poly_randtest(A, state, n_randint(state, 50));
105         nmod_poly_set_coeff_ui(A, 0, UWORD(0));
106 
107         nmod_poly_exp_series_basecase(B, A, n);
108         nmod_poly_exp_series_basecase(A, A, n);
109 
110         result = nmod_poly_equal(A, B);
111         if (!result)
112         {
113             flint_printf("FAIL:\n");
114             nmod_poly_print(A), flint_printf("\n\n");
115             nmod_poly_print(B), flint_printf("\n\n");
116             abort();
117         }
118 
119         nmod_poly_clear(A);
120         nmod_poly_clear(B);
121     }
122 
123     FLINT_TEST_CLEANUP(state);
124 
125     flint_printf("PASS\n");
126     return 0;
127 }
128