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_satoh... ");
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_satoh(b, a, ctx);
64 ans2 = padic_log_satoh(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 < 100 * 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_satoh(d, a, ctx);
112 ans2 = padic_log_satoh(e, b, ctx);
113 padic_add(f, d, e, ctx);
114
115 ans3 = padic_log_satoh(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 < 100 * 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_satoh(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_satoh(b, a, ctx);
209 ans2 = padic_log_satoh(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 < 100 * 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_randprime(state, 5, 1));
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_satoh(d, a, ctx);
261 ans2 = padic_log_satoh(e, b, ctx);
262 padic_add(f, d, e, ctx);
263
264 ans3 = padic_log_satoh(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 < 100 * 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_randprime(state, 5, 1));
306 N = __rand_prec(state, i);
307 padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);
308
309 padic_init2(a, N);
310 padic_init2(b, N);
311 padic_init2(c, N);
312
313 padic_randtest(a, state, ctx);
314
315 ans1 = padic_exp(b, a, ctx);
316 if (ans1)
317 ans2 = padic_log_satoh(c, b, ctx);
318
319 result = !ans1 || (ans1 == ans2 && padic_equal(a, c));
320 if (!result)
321 {
322 flint_printf("FAIL (log(exp(x)) == x):\n\n");
323 flint_printf("a = "), padic_print(a, ctx), flint_printf("\n");
324 flint_printf("b = "), padic_print(b, ctx), flint_printf("\n");
325 flint_printf("c = "), padic_print(c, ctx), flint_printf("\n");
326 flint_printf("ans1 = %d\n", ans1);
327 flint_printf("ans2 = %d\n", ans2);
328 abort();
329 }
330
331 padic_clear(a);
332 padic_clear(b);
333 padic_clear(c);
334
335 fmpz_clear(p);
336 padic_ctx_clear(ctx);
337 }
338
339 FLINT_TEST_CLEANUP(state);
340
341 flint_printf("PASS\n");
342 return EXIT_SUCCESS;
343 }
344
345