comparison src/fftw-3.3.8/kernel/primes.c @ 82:d0c2a83c1364

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