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 <http://www.gnu.org/licenses/>.
10 */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include "nmod_mpoly.h"
15 
nmod_mpoly_pow_naive(nmod_mpoly_t res,nmod_mpoly_t f,slong n,nmod_mpoly_ctx_t ctx)16 void nmod_mpoly_pow_naive(nmod_mpoly_t res, nmod_mpoly_t f,
17                                                  slong n, nmod_mpoly_ctx_t ctx)
18 {
19    if (n == 0)
20       nmod_mpoly_set_ui(res, 1, ctx);
21    else if (f->length == 0)
22       nmod_mpoly_zero(res, ctx);
23    else if (n == 1)
24       nmod_mpoly_set(res, f, ctx);
25    else
26    {
27       slong i;
28       nmod_mpoly_t pow;
29 
30       nmod_mpoly_init(pow, ctx);
31       nmod_mpoly_set(pow, f, ctx);
32 
33       for (i = 1; i < n - 1; i++)
34          nmod_mpoly_mul_johnson(pow, pow, f, ctx);
35 
36       nmod_mpoly_mul_johnson(res, pow, f, ctx);
37 
38       nmod_mpoly_clear(pow, ctx);
39    }
40 }
41 
42 int
main(void)43 main(void)
44 {
45     int i, j;
46     FLINT_TEST_INIT(state);
47 
48     flint_printf("pow_ui....");
49     fflush(stdout);
50 
51     for (i = 0; i < 50 * flint_test_multiplier(); i++)
52     {
53         nmod_mpoly_ctx_t ctx;
54         nmod_mpoly_t f, g, h;
55         ulong pow_bound;
56         slong len, len1, len2;
57         flint_bitcnt_t exp_bits, exp_bits1, exp_bits2;
58         mp_limb_t modulus;
59 
60         modulus = n_randbits(state, n_randint(state, FLINT_BITS));
61         modulus = FLINT_MAX(UWORD(2), modulus);
62 
63         nmod_mpoly_ctx_init_rand(ctx, state, 10, modulus);
64 
65         nmod_mpoly_init(f, ctx);
66         nmod_mpoly_init(g, ctx);
67         nmod_mpoly_init(h, ctx);
68 
69         len = n_randint(state, 10);
70         len1 = n_randint(state, 10);
71         len2 = n_randint(state, 10);
72 
73         exp_bits = n_randint(state, 7) + 2;
74         exp_bits1 = n_randint(state, 7) + 2;
75         exp_bits2 = n_randint(state, 7) + 2;
76 
77         if (n_is_prime(ctx->ffinfo->mod.n)) {
78             pow_bound = 60000/(len1+1)/(FLINT_BIT_COUNT(modulus)+10);
79         } else {
80             pow_bound = 400/(len1+1);
81         }
82         pow_bound = pow_bound/ctx->minfo->nvars;
83         pow_bound = pow_bound/ctx->minfo->nvars;
84         pow_bound = pow_bound/ctx->minfo->nvars;
85         pow_bound = FLINT_MAX(pow_bound, UWORD(4));
86 
87         for (j = 0; j < 10; j++)
88         {
89             slong pow;
90 
91             pow = n_randint(state, pow_bound);
92 
93             nmod_mpoly_randtest_bits(f, state, len1, exp_bits1, ctx);
94             nmod_mpoly_randtest_bits(g, state, len2, exp_bits2, ctx);
95             nmod_mpoly_randtest_bits(h, state, len, exp_bits, ctx);
96 
97             if (!nmod_mpoly_pow_ui(g, f, pow, ctx))
98             {
99                 printf("FAIL\n");
100                 flint_printf("Check pow_ui success\ni = %wd, j = %wd\n", i, j);
101                 flint_abort();
102             }
103             nmod_mpoly_assert_canonical(g, ctx);
104             nmod_mpoly_pow_rmul(h, f, pow, ctx);
105             nmod_mpoly_assert_canonical(h, ctx);
106 
107             if (!nmod_mpoly_equal(g, h, ctx))
108             {
109                 printf("FAIL\n");
110                 flint_printf("Check pow_ui against pow_naive\ni = %wd, j = %wd\n", i, j);
111                 flint_abort();
112             }
113 
114             if (!nmod_mpoly_pow_ui(f, f, pow, ctx))
115             {
116                 printf("FAIL\n");
117                 flint_printf("Check pow_ui success\ni = %wd, j = %wd\n", i, j);
118                 flint_abort();
119             }
120             nmod_mpoly_assert_canonical(f, ctx);
121 
122             if (!nmod_mpoly_equal(g, f, ctx))
123             {
124                 printf("FAIL\n");
125                 flint_printf("Check aliasing\ni = %wd, j = %wd\n", i, j);
126                 flint_abort();
127             }
128         }
129 
130         nmod_mpoly_clear(f, ctx);
131         nmod_mpoly_clear(g, ctx);
132         nmod_mpoly_clear(h, ctx);
133         nmod_mpoly_ctx_clear(ctx);
134     }
135 
136     FLINT_TEST_CLEANUP(state);
137 
138     flint_printf("PASS\n");
139     return 0;
140 }
141 
142