cannam@95
|
1 /*
|
cannam@95
|
2 * Copyright (c) 2003, 2007-11 Matteo Frigo
|
cannam@95
|
3 * Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology
|
cannam@95
|
4 *
|
cannam@95
|
5 * This program is free software; you can redistribute it and/or modify
|
cannam@95
|
6 * it under the terms of the GNU General Public License as published by
|
cannam@95
|
7 * the Free Software Foundation; either version 2 of the License, or
|
cannam@95
|
8 * (at your option) any later version.
|
cannam@95
|
9 *
|
cannam@95
|
10 * This program is distributed in the hope that it will be useful,
|
cannam@95
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
cannam@95
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
cannam@95
|
13 * GNU General Public License for more details.
|
cannam@95
|
14 *
|
cannam@95
|
15 * You should have received a copy of the GNU General Public License
|
cannam@95
|
16 * along with this program; if not, write to the Free Software
|
cannam@95
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
cannam@95
|
18 *
|
cannam@95
|
19 */
|
cannam@95
|
20
|
cannam@95
|
21
|
cannam@95
|
22 #include "ifftw.h"
|
cannam@95
|
23
|
cannam@95
|
24 /***************************************************************************/
|
cannam@95
|
25
|
cannam@95
|
26 /* Rader's algorithm requires lots of modular arithmetic, and if we
|
cannam@95
|
27 aren't careful we can have errors due to integer overflows. */
|
cannam@95
|
28
|
cannam@95
|
29 /* Compute (x * y) mod p, but watch out for integer overflows; we must
|
cannam@95
|
30 have 0 <= {x, y} < p.
|
cannam@95
|
31
|
cannam@95
|
32 If overflow is common, this routine is somewhat slower than
|
cannam@95
|
33 e.g. using 'long long' arithmetic. However, it has the advantage
|
cannam@95
|
34 of working when INT is 64 bits, and is also faster when overflow is
|
cannam@95
|
35 rare. FFTW calls this via the MULMOD macro, which further
|
cannam@95
|
36 optimizes for the case of small integers.
|
cannam@95
|
37 */
|
cannam@95
|
38
|
cannam@95
|
39 #define ADD_MOD(x, y, p) ((x) >= (p) - (y)) ? ((x) + ((y) - (p))) : ((x) + (y))
|
cannam@95
|
40
|
cannam@95
|
41 INT X(safe_mulmod)(INT x, INT y, INT p)
|
cannam@95
|
42 {
|
cannam@95
|
43 INT r;
|
cannam@95
|
44
|
cannam@95
|
45 if (y > x)
|
cannam@95
|
46 return X(safe_mulmod)(y, x, p);
|
cannam@95
|
47
|
cannam@95
|
48 A(0 <= y && x < p);
|
cannam@95
|
49
|
cannam@95
|
50 r = 0;
|
cannam@95
|
51 while (y) {
|
cannam@95
|
52 r = ADD_MOD(r, x*(y&1), p); y >>= 1;
|
cannam@95
|
53 x = ADD_MOD(x, x, p);
|
cannam@95
|
54 }
|
cannam@95
|
55
|
cannam@95
|
56 return r;
|
cannam@95
|
57 }
|
cannam@95
|
58
|
cannam@95
|
59 /***************************************************************************/
|
cannam@95
|
60
|
cannam@95
|
61 /* Compute n^m mod p, where m >= 0 and p > 0. If we really cared, we
|
cannam@95
|
62 could make this tail-recursive. */
|
cannam@95
|
63
|
cannam@95
|
64 INT X(power_mod)(INT n, INT m, INT p)
|
cannam@95
|
65 {
|
cannam@95
|
66 A(p > 0);
|
cannam@95
|
67 if (m == 0)
|
cannam@95
|
68 return 1;
|
cannam@95
|
69 else if (m % 2 == 0) {
|
cannam@95
|
70 INT x = X(power_mod)(n, m / 2, p);
|
cannam@95
|
71 return MULMOD(x, x, p);
|
cannam@95
|
72 }
|
cannam@95
|
73 else
|
cannam@95
|
74 return MULMOD(n, X(power_mod)(n, m - 1, p), p);
|
cannam@95
|
75 }
|
cannam@95
|
76
|
cannam@95
|
77 /* the following two routines were contributed by Greg Dionne. */
|
cannam@95
|
78 static INT get_prime_factors(INT n, INT *primef)
|
cannam@95
|
79 {
|
cannam@95
|
80 INT i;
|
cannam@95
|
81 INT size = 0;
|
cannam@95
|
82
|
cannam@95
|
83 A(n % 2 == 0); /* this routine is designed only for even n */
|
cannam@95
|
84 primef[size++] = (INT)2;
|
cannam@95
|
85 do
|
cannam@95
|
86 n >>= 1;
|
cannam@95
|
87 while ((n & 1) == 0);
|
cannam@95
|
88
|
cannam@95
|
89 if (n == 1)
|
cannam@95
|
90 return size;
|
cannam@95
|
91
|
cannam@95
|
92 for (i = 3; i * i <= n; i += 2)
|
cannam@95
|
93 if (!(n % i)) {
|
cannam@95
|
94 primef[size++] = i;
|
cannam@95
|
95 do
|
cannam@95
|
96 n /= i;
|
cannam@95
|
97 while (!(n % i));
|
cannam@95
|
98 }
|
cannam@95
|
99 if (n == 1)
|
cannam@95
|
100 return size;
|
cannam@95
|
101 primef[size++] = n;
|
cannam@95
|
102 return size;
|
cannam@95
|
103 }
|
cannam@95
|
104
|
cannam@95
|
105 INT X(find_generator)(INT p)
|
cannam@95
|
106 {
|
cannam@95
|
107 INT n, i, size;
|
cannam@95
|
108 INT primef[16]; /* smallest number = 32589158477190044730 > 2^64 */
|
cannam@95
|
109 INT pm1 = p - 1;
|
cannam@95
|
110
|
cannam@95
|
111 if (p == 2)
|
cannam@95
|
112 return 1;
|
cannam@95
|
113
|
cannam@95
|
114 size = get_prime_factors(pm1, primef);
|
cannam@95
|
115 n = 2;
|
cannam@95
|
116 for (i = 0; i < size; i++)
|
cannam@95
|
117 if (X(power_mod)(n, pm1 / primef[i], p) == 1) {
|
cannam@95
|
118 i = -1;
|
cannam@95
|
119 n++;
|
cannam@95
|
120 }
|
cannam@95
|
121 return n;
|
cannam@95
|
122 }
|
cannam@95
|
123
|
cannam@95
|
124 /* Return first prime divisor of n (It would be at best slightly faster to
|
cannam@95
|
125 search a static table of primes; there are 6542 primes < 2^16.) */
|
cannam@95
|
126 INT X(first_divisor)(INT n)
|
cannam@95
|
127 {
|
cannam@95
|
128 INT i;
|
cannam@95
|
129 if (n <= 1)
|
cannam@95
|
130 return n;
|
cannam@95
|
131 if (n % 2 == 0)
|
cannam@95
|
132 return 2;
|
cannam@95
|
133 for (i = 3; i*i <= n; i += 2)
|
cannam@95
|
134 if (n % i == 0)
|
cannam@95
|
135 return i;
|
cannam@95
|
136 return n;
|
cannam@95
|
137 }
|
cannam@95
|
138
|
cannam@95
|
139 int X(is_prime)(INT n)
|
cannam@95
|
140 {
|
cannam@95
|
141 return(n > 1 && X(first_divisor)(n) == n);
|
cannam@95
|
142 }
|
cannam@95
|
143
|
cannam@95
|
144 INT X(next_prime)(INT n)
|
cannam@95
|
145 {
|
cannam@95
|
146 while (!X(is_prime)(n)) ++n;
|
cannam@95
|
147 return n;
|
cannam@95
|
148 }
|
cannam@95
|
149
|
cannam@95
|
150 int X(factors_into)(INT n, const INT *primes)
|
cannam@95
|
151 {
|
cannam@95
|
152 for (; *primes != 0; ++primes)
|
cannam@95
|
153 while ((n % *primes) == 0)
|
cannam@95
|
154 n /= *primes;
|
cannam@95
|
155 return (n == 1);
|
cannam@95
|
156 }
|
cannam@95
|
157
|
cannam@95
|
158 /* integer square root. Return floor(sqrt(N)) */
|
cannam@95
|
159 INT X(isqrt)(INT n)
|
cannam@95
|
160 {
|
cannam@95
|
161 INT guess, iguess;
|
cannam@95
|
162
|
cannam@95
|
163 A(n >= 0);
|
cannam@95
|
164 if (n == 0) return 0;
|
cannam@95
|
165
|
cannam@95
|
166 guess = n; iguess = 1;
|
cannam@95
|
167
|
cannam@95
|
168 do {
|
cannam@95
|
169 guess = (guess + iguess) / 2;
|
cannam@95
|
170 iguess = n / guess;
|
cannam@95
|
171 } while (guess > iguess);
|
cannam@95
|
172
|
cannam@95
|
173 return guess;
|
cannam@95
|
174 }
|
cannam@95
|
175
|
cannam@95
|
176 static INT isqrt_maybe(INT n)
|
cannam@95
|
177 {
|
cannam@95
|
178 INT guess = X(isqrt)(n);
|
cannam@95
|
179 return guess * guess == n ? guess : 0;
|
cannam@95
|
180 }
|
cannam@95
|
181
|
cannam@95
|
182 #define divides(a, b) (((b) % (a)) == 0)
|
cannam@95
|
183 INT X(choose_radix)(INT r, INT n)
|
cannam@95
|
184 {
|
cannam@95
|
185 if (r > 0) {
|
cannam@95
|
186 if (divides(r, n)) return r;
|
cannam@95
|
187 return 0;
|
cannam@95
|
188 } else if (r == 0) {
|
cannam@95
|
189 return X(first_divisor)(n);
|
cannam@95
|
190 } else {
|
cannam@95
|
191 /* r is negative. If n = (-r) * q^2, take q as the radix */
|
cannam@95
|
192 r = 0 - r;
|
cannam@95
|
193 return (n > r && divides(r, n)) ? isqrt_maybe(n / r) : 0;
|
cannam@95
|
194 }
|
cannam@95
|
195 }
|
cannam@95
|
196
|
cannam@95
|
197 /* return A mod N, works for all A including A < 0 */
|
cannam@95
|
198 INT X(modulo)(INT a, INT n)
|
cannam@95
|
199 {
|
cannam@95
|
200 A(n > 0);
|
cannam@95
|
201 if (a >= 0)
|
cannam@95
|
202 return a % n;
|
cannam@95
|
203 else
|
cannam@95
|
204 return (n - 1) - ((-(a + (INT)1)) % n);
|
cannam@95
|
205 }
|
cannam@95
|
206
|
cannam@95
|
207 /* TRUE if N factors into small primes */
|
cannam@95
|
208 int X(factors_into_small_primes)(INT n)
|
cannam@95
|
209 {
|
cannam@95
|
210 static const INT primes[] = { 2, 3, 5, 0 };
|
cannam@95
|
211 return X(factors_into)(n, primes);
|
cannam@95
|
212 }
|