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 "ulong_extras.h"
13 #include "padic.h"
14 
15 /*
16     Set-up.  Currently we only test the logarithm for positive values of N.
17     This is important as for negative N, exp(0) is 1, which is 0 mod p^N,
18     and then log(0) does not converge.
19  */
__rand_prec(flint_rand_t state,slong i)20 static slong __rand_prec(flint_rand_t state, slong i)
21 {
22     slong N;
23 
24     N = n_randint(state, PADIC_TEST_PREC_MAX) + 1;
25 
26     return N;
27 }
28 
29 int
main(void)30 main(void)
31 {
32     int i, result;
33     FLINT_TEST_INIT(state);
34 
35     flint_printf("log_rectangular... ");
36     fflush(stdout);
37 
38 
39 
40 /** p == 2 *******************************************************************/
41 
42     /* Check aliasing: a = log(a) */
43     for (i = 0; i < 100 * flint_test_multiplier(); i++)
44     {
45         fmpz_t p = {WORD(2)};
46         slong N;
47         padic_ctx_t ctx;
48 
49         padic_t a, b;
50         int ans1, ans2;
51 
52         N = __rand_prec(state, i);
53         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
54 
55         padic_init2(a, N);
56         padic_init2(b, N);
57 
58         padic_randtest(a, state, ctx);
59 
60         padic_one(b);
61         padic_add(a, a, b, ctx);
62 
63         ans1 = padic_log_rectangular(b, a, ctx);
64         ans2 = padic_log_rectangular(a, a, ctx);
65 
66         result = (ans1 == ans2) && (!ans1 || padic_equal(a, b));
67         if (!result)
68         {
69             flint_printf("FAIL (aliasing):\n\n");
70             flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
71             flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
72             abort();
73         }
74 
75         padic_clear(a);
76         padic_clear(b);
77 
78         padic_ctx_clear(ctx);
79     }
80 
81     /* Check: log(a) + log(b) == log(a * b) */
82     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
83     {
84         fmpz_t p = {WORD(2)};
85         slong N;
86         padic_ctx_t ctx;
87 
88         padic_t a, b, c, d, e, f, g;
89         int ans1, ans2, ans3;
90 
91         N = __rand_prec(state, i);
92         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
93 
94         padic_init2(a, N);
95         padic_init2(b, N);
96         padic_init2(c, N);
97         padic_init2(d, N);
98         padic_init2(e, N);
99         padic_init2(f, N);
100         padic_init2(g, N);
101 
102         padic_randtest(a, state, ctx);
103         padic_randtest(b, state, ctx);
104 
105         padic_one(c);
106         padic_add(a, a, c, ctx);
107         padic_add(b, b, c, ctx);
108 
109         padic_mul(c, a, b, ctx);
110 
111         ans1 = padic_log_rectangular(d, a, ctx);
112         ans2 = padic_log_rectangular(e, b, ctx);
113         padic_add(f, d, e, ctx);
114 
115         ans3 = padic_log_rectangular(g, c, ctx);
116 
117         result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g)));
118         if (!result)
119         {
120             flint_printf("FAIL (functional equation):\n\n");
121             flint_printf("a                   = "), padic_print(a, ctx), flint_printf("\n");
122             flint_printf("b                   = "), padic_print(b, ctx), flint_printf("\n");
123             flint_printf("c = a * b           = "), padic_print(c, ctx), flint_printf("\n");
124             flint_printf("d = log(a)          = "), padic_print(d, ctx), flint_printf("\n");
125             flint_printf("e = log(b)          = "), padic_print(e, ctx), flint_printf("\n");
126             flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n");
127             flint_printf("g = log(a * b)      = "), padic_print(g, ctx), flint_printf("\n");
128             abort();
129         }
130 
131         padic_clear(a);
132         padic_clear(b);
133         padic_clear(c);
134         padic_clear(d);
135         padic_clear(e);
136         padic_clear(f);
137         padic_clear(g);
138 
139         padic_ctx_clear(ctx);
140     }
141 
142     /* Check: log(exp(x)) == x */
143     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
144     {
145         fmpz_t p = {WORD(2)};
146         slong N;
147         padic_ctx_t ctx;
148 
149         padic_t a, b, c;
150         int ans1, ans2;
151 
152         N = __rand_prec(state, i);
153         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
154 
155         padic_init2(a, N);
156         padic_init2(b, N);
157         padic_init2(c, N);
158 
159         padic_randtest(a, state, ctx);
160 
161         ans1 = padic_exp(b, a, ctx);
162         if (ans1)
163             ans2 = padic_log_rectangular(c, b, ctx);
164 
165         result = !ans1 || (ans1 == ans2 && padic_equal(a, c));
166         if (!result)
167         {
168             flint_printf("FAIL (log(exp(x)) == x):\n\n");
169             flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
170             flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
171             flint_printf("c = "), padic_print(c, ctx), flint_printf("\n");
172             flint_printf("ans1 = %d\n", ans1);
173             flint_printf("ans2 = %d\n", ans2);
174             abort();
175         }
176 
177         padic_clear(a);
178         padic_clear(b);
179         padic_clear(c);
180 
181         padic_ctx_clear(ctx);
182     }
183 
184 /** p > 2 ********************************************************************/
185 
186     /* Check aliasing: a = log(a) */
187     for (i = 0; i < 100 * flint_test_multiplier(); i++)
188     {
189         fmpz_t p;
190         slong N;
191         padic_ctx_t ctx;
192 
193         padic_t a, b;
194         int ans1, ans2;
195 
196         fmpz_init_set_ui(p, n_randtest_prime(state, 0));
197         N = __rand_prec(state, i);
198         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
199 
200         padic_init2(a, N);
201         padic_init2(b, N);
202 
203         padic_randtest(a, state, ctx);
204 
205         padic_one(b);
206         padic_add(a, a, b, ctx);
207 
208         ans1 = padic_log_rectangular(b, a, ctx);
209         ans2 = padic_log_rectangular(a, a, ctx);
210 
211         result = (ans1 == ans2) && (!ans1 || padic_equal(a, b));
212         if (!result)
213         {
214             flint_printf("FAIL (aliasing):\n\n");
215             flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
216             flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
217             abort();
218         }
219 
220         padic_clear(a);
221         padic_clear(b);
222 
223         fmpz_clear(p);
224         padic_ctx_clear(ctx);
225     }
226 
227     /* Check: log(a) + log(b) == log(a * b) */
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         padic_t a, b, c, d, e, f, g;
235         int ans1, ans2, ans3;
236 
237         fmpz_init_set_ui(p, n_randtest_prime(state, 0));
238         N = __rand_prec(state, i);
239         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
240 
241         padic_init2(a, N);
242         padic_init2(b, N);
243         padic_init2(c, N);
244         padic_init2(d, N);
245         padic_init2(e, N);
246         padic_init2(f, N);
247         padic_init2(g, N);
248 
249         padic_randtest(a, state, ctx);
250         padic_randtest(b, state, ctx);
251 
252         padic_one(c);
253         padic_add(a, a, c, ctx);
254 
255         padic_one(c);
256         padic_add(b, b, c, ctx);
257 
258         padic_mul(c, a, b, ctx);
259 
260         ans1 = padic_log_rectangular(d, a, ctx);
261         ans2 = padic_log_rectangular(e, b, ctx);
262         padic_add(f, d, e, ctx);
263 
264         ans3 = padic_log_rectangular(g, c, ctx);
265 
266         result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g)));
267         if (!result)
268         {
269             flint_printf("FAIL (functional equation):\n\n");
270             flint_printf("a                   = "), padic_print(a, ctx), flint_printf("\n");
271             flint_printf("b                   = "), padic_print(b, ctx), flint_printf("\n");
272             flint_printf("c = a * b           = "), padic_print(c, ctx), flint_printf("\n");
273             flint_printf("d = log(a)          = "), padic_print(d, ctx), flint_printf("\n");
274             flint_printf("e = log(b)          = "), padic_print(e, ctx), flint_printf("\n");
275             flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n");
276             flint_printf("g = log(a * b)      = "), padic_print(g, ctx), flint_printf("\n");
277             flint_printf("ans1 = %d\n", ans1);
278             flint_printf("ans2 = %d\n", ans2);
279             flint_printf("ans3 = %d\n", ans3);
280             abort();
281         }
282 
283         padic_clear(a);
284         padic_clear(b);
285         padic_clear(c);
286         padic_clear(d);
287         padic_clear(e);
288         padic_clear(f);
289         padic_clear(g);
290 
291         fmpz_clear(p);
292         padic_ctx_clear(ctx);
293     }
294 
295     /* Check: log(exp(x)) == x */
296     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
297     {
298         fmpz_t p;
299         slong N;
300         padic_ctx_t ctx;
301 
302         padic_t a, b, c;
303         int ans1, ans2;
304 
305 /*      fmpz_init_set_ui(p, n_randtest_prime(state, 0)); */
306         fmpz_init_set_ui(p, n_randprime(state, 5, 1));
307         N = __rand_prec(state, i);
308         padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
309 
310         padic_init2(a, N);
311         padic_init2(b, N);
312         padic_init2(c, N);
313 
314         padic_randtest(a, state, ctx);
315 
316         ans1 = padic_exp(b, a, ctx);
317         if (ans1)
318             ans2 = padic_log_rectangular(c, b, ctx);
319 
320         result = !ans1 || (ans1 == ans2 && padic_equal(a, c));
321         if (!result)
322         {
323             flint_printf("FAIL (log(exp(x)) == x):\n\n");
324             flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
325             flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
326             flint_printf("c = "), padic_print(c, ctx), flint_printf("\n");
327             flint_printf("ans1 = %d\n", ans1);
328             flint_printf("ans2 = %d\n", ans2);
329             abort();
330         }
331 
332         padic_clear(a);
333         padic_clear(b);
334         padic_clear(c);
335 
336         fmpz_clear(p);
337         padic_ctx_clear(ctx);
338     }
339 
340     FLINT_TEST_CLEANUP(state);
341 
342     flint_printf("PASS\n");
343     return EXIT_SUCCESS;
344 }
345 
346