File Coverage

util.h
Criterion Covered Total %
statement 17 17 100.0
branch 8 12 66.6
condition n/a
subroutine n/a
pod n/a
total 25 29 86.2


line stmt bran cond sub pod time code
1             #ifndef MPU_UTIL_H
2             #define MPU_UTIL_H
3              
4             #include "ptypes.h"
5              
6             extern int _numcmp(const void *a, const void *b); /* qsort numerical sorting */
7              
8             extern int _XS_get_verbose(void);
9             extern void _XS_set_verbose(int v);
10             extern int _XS_get_callgmp(void);
11             extern void _XS_set_callgmp(int v);
12             /* Disable all manual seeding */
13             extern int _XS_get_secure(void);
14             extern void _XS_set_secure(void);
15              
16             extern int is_prime(UV x);
17             extern UV next_prime(UV x);
18             extern UV prev_prime(UV x);
19              
20             extern void print_primes(UV low, UV high, int fd);
21              
22             extern int powerof(UV n);
23             extern int is_power(UV n, UV a);
24             extern UV rootof(UV n, UV k);
25             extern int primepower(UV n, UV* prime);
26             extern UV valuation(UV n, UV k);
27             extern UV logint(UV n, UV b);
28             extern UV mpu_popcount_string(const char* ptr, uint32_t len);
29              
30             extern signed char* range_moebius(UV low, UV high);
31             extern UV* range_totient(UV low, UV high);
32             extern IV mertens(UV n);
33             extern NV chebyshev_psi(UV n);
34             extern NV chebyshev_theta(UV n);
35              
36             extern NV Ei(NV x);
37             extern NV Li(NV x);
38             extern long double ld_riemann_zeta(long double x);
39             extern long double RiemannR(long double x);
40             extern NV lambertw(NV k);
41             extern UV inverse_li(UV x);
42             extern UV inverse_R(UV x);
43              
44             extern int kronecker_uu(UV a, UV b);
45             extern int kronecker_su(IV a, UV b);
46             extern int kronecker_ss(IV a, IV b);
47              
48             extern UV factorial(UV n);
49             extern UV binomial(UV n, UV k);
50             extern IV gcdext(IV a, IV b, IV* u, IV* v, IV* s, IV* t); /* Ext Euclidean */
51             extern UV modinverse(UV a, UV p); /* Returns 1/a mod p */
52             extern UV divmod(UV a, UV b, UV n); /* Returns a/b mod n */
53             extern int sqrtmod(UV* s, UV a, UV p); /* sqrt(a) mod p */
54             extern int sqrtmod_composite(UV* s, UV a,UV n);/* sqrt(a) mod n */
55             extern UV chinese(UV* a, UV* n, UV num, int *status); /* Chinese Remainder */
56              
57             extern UV totient(UV n);
58             extern int moebius(UV n);
59             extern UV exp_mangoldt(UV n);
60             extern UV carmichael_lambda(UV n);
61             extern UV jordan_totient(UV k, UV n);
62             extern UV znprimroot(UV n);
63             extern UV znorder(UV a, UV n);
64             extern int is_primitive_root(UV a, UV n, int nprime);
65             extern UV factorialmod(UV n, UV m);
66             #define is_square_free(n) (moebius(n) != 0)
67             extern int is_fundamental(UV n, int neg);
68             extern int is_totient(UV n);
69             extern int is_semiprime(UV n);
70             extern int is_carmichael(UV n);
71             extern UV is_quasi_carmichael(UV n); /* Returns number of bases */
72             extern UV pillai_v(UV n); /* v: v! % n == n-1 && n % v != 1 */
73              
74             extern UV inverse_totient_count(UV n);
75             extern UV* inverse_totient_list(UV *ntotients, UV n);
76              
77             extern UV stirling3(UV n, UV m);
78             extern IV stirling2(UV n, UV m);
79             extern IV stirling1(UV n, UV m);
80              
81             extern IV hclassno(UV n);
82             extern IV ramanujan_tau(UV n);
83              
84             extern char* pidigits(int digits);
85              
86             extern int strnum_minmax(int min, char* a, STRLEN alen, char* b, STRLEN blen);
87              
88             extern int from_digit_string(UV* n, const char* s, int base);
89             extern int from_digit_to_UV(UV* rn, UV* r, int len, int base);
90             extern int from_digit_to_str(char** rstr, UV* r, int len, int base);
91             extern int to_digit_array(int* bits, UV n, int base, int length);
92             extern int to_digit_string(char *s, UV n, int base, int length);
93             extern int to_string_128(char s[40], IV hi, UV lo);
94              
95             extern int is_catalan_pseudoprime(UV n);
96              
97             extern UV polygonal_root(UV n, UV k, int* overflow);
98              
99             extern int num_to_perm(UV rank, int n, int *vec);
100             extern int perm_to_num(int n, int *vec, UV *rank);
101             extern void randperm(void* ctx, UV n, UV k, UV *S);
102              
103             extern UV random_factored_integer(void* ctx, UV n, int *nf, UV *factors);
104              
105             extern UV gcdz(UV x, UV y);
106              
107             #if defined(FUNC_isqrt) || defined(FUNC_is_perfect_square)
108             #include
109 847           static UV isqrt(UV n) {
110             UV root;
111             #if BITS_PER_WORD == 32
112             if (n >= UVCONST(4294836225)) return UVCONST(65535);
113             #else
114 847 50         if (n >= UVCONST(18446744065119617025)) return UVCONST(4294967295);
115             #endif
116 847           root = (UV) sqrt((double)n);
117 847 50         while (root*root > n) root--;
118 847 50         while ((root+1)*(root+1) <= n) root++;
119 847           return root;
120             }
121             #endif
122              
123             #if defined(FUNC_icbrt) || defined(FUNC_is_perfect_cube)
124 847           static UV icbrt(UV n) {
125 847           UV b, root = 0;
126             #if BITS_PER_WORD == 32
127             int s = 30;
128             if (n >= UVCONST(4291015625)) return UVCONST(1625);
129             #else
130 847           int s = 63;
131 847 50         if (n >= UVCONST(18446724184312856125)) return UVCONST(2642245);
132             #endif
133 19481 100         for ( ; s >= 0; s -= 3) {
134 18634           root += root;
135 18634           b = 3*root*(root+1)+1;
136 18634 100         if ((n >> s) >= b) {
137 4421           n -= b << s;
138 4421           root++;
139             }
140             }
141 847           return root;
142             }
143             #endif
144              
145             #if defined(FUNC_ipow)
146             static UV ipow(UV n, UV k) {
147             UV p = 1;
148             while (k) {
149             if (k & 1) p *= n;
150             k >>= 1;
151             if (k) n *= n;
152             }
153             return p;
154             }
155             #endif
156              
157             #if defined(FUNC_gcd_ui) || defined(FUNC_lcm_ui)
158             /* If we have a very fast ctz, then use the fast FLINT version of gcd */
159             #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
160             #define gcd_ui(x,y) gcdz(x,y)
161             #else
162             static UV gcd_ui(UV x, UV y) {
163             UV t;
164             if (y < x) { t = x; x = y; y = t; }
165             while (y > 0) {
166             t = y; y = x % y; x = t; /* y1 <- x0 % y0 ; x1 <- y0 */
167             }
168             return x;
169             }
170             #endif
171             #endif
172              
173             #ifdef FUNC_lcm_ui
174             static UV lcm_ui(UV x, UV y) {
175             /* Can overflow if lcm(x,y) > 2^64 (e.g. two primes each > 2^32) */
176             return x * (y / gcd_ui(x,y));
177             }
178             #endif
179              
180             #ifdef FUNC_is_perfect_square
181             /* See: http://mersenneforum.org/showpost.php?p=110896 */
182             static int is_perfect_square(UV n)
183             {
184             /* Step 1, reduce to 18% of inputs */
185             uint32_t m = n & 127;
186             if ((m*0x8bc40d7d) & (m*0xa1e2f5d1) & 0x14020a) return 0;
187             /* Step 2, reduce to 7% of inputs (mod 99 reduces to 4% but slower) */
188             m = n %240; if ((m*0xfa445556) & (m*0x8021feb1) & 0x614aaa0f) return 0;
189             /* m = n % 99; if ((m*0x5411171d) & (m*0xe41dd1c7) & 0x80028a80) return 0; */
190             /* Step 3, do the square root instead of any more rejections */
191             m = isqrt(n);
192             return (UV)m*(UV)m == n;
193             }
194             #endif
195              
196             #ifdef FUNC_is_perfect_cube
197             static int is_perfect_cube(UV n)
198             {
199             UV m;
200             if ((n & 3) == 2) return 0;
201             /* m = n & 511; if ((m*5016427) & (m*95638165) & 438) return 0; */
202             m = n % 117; if ((m*833230740) & (m*120676722) & 813764715) return 0;
203             m = n % 133; if ((m*76846229) & (m*305817297) & 306336544) return 0;
204             m = icbrt(n);
205             return m*m*m == n;
206             }
207             #endif
208              
209             #ifdef FUNC_is_perfect_fifth
210             static int is_perfect_fifth(UV n)
211             {
212             UV m;
213             if ((n & 3) == 2) return 0;
214             m = n % 88; if ((m*85413603) & (m*76260301) & 26476550) return 0;
215             m = n % 31; if ((m*80682551) & (m*73523539) & 45414528) return 0;
216             m = n % 41; if ((m*92806493) & (m*130690042) & 35668129) return 0;
217             /* m = n % 25; if ((m*109794298) & (m*105535723) & 16097553) return 0; */
218             m = rootof(n, 5);
219             return m*m*m*m*m == n;
220             }
221             #endif
222              
223             #ifdef FUNC_is_perfect_seventh
224             static int is_perfect_seventh(UV n)
225             {
226             UV m;
227             /* if ((n & 3) == 2) return 0; */
228             m = n & 511; if ((m*97259473) & (m*51311663) & 894) return 0;
229             m = n % 49; if ((m*109645301) & (m*76482737) & 593520192) return 0;
230             m = n % 71; if ((m*71818386) & (m*38821587) & 35299393) return 0;
231             /* m = n % 43; if ((m*101368253) & (m*814158665) & 142131408) return 0; */
232             /* m = n % 29; if ((m*81935611) & (m*84736134) & 37831965) return 0; */
233             /* m = n % 116; if ((m*348163737) & (m*1539055705) & 2735997248) return 0; */
234             m = rootof(n, 7);
235             return m*m*m*m*m*m*m == n;
236             }
237             #endif
238              
239             #if defined(FUNC_clz) || defined(FUNC_ctz) || defined(FUNC_log2floor)
240             /* log2floor(n) gives the location of the first set bit (starting from left)
241             * ctz(n) gives the number of times n is divisible by 2
242             * clz(n) gives the number of zeros on the left */
243             #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
244             #if BITS_PER_WORD == 64
245             #define ctz(n) ((n) ? __builtin_ctzll(n) : 64)
246             #define clz(n) ((n) ? __builtin_clzll(n) : 64)
247             #define log2floor(n) ((n) ? 63-__builtin_clzll(n) : 0)
248             #else
249             #define ctz(n) ((n) ? __builtin_ctzl(n) : 32)
250             #define clz(n) ((n) ? __builtin_clzl(n) : 32)
251             #define log2floor(n) ((n) ? 31-__builtin_clzl(n) : 0)
252             #endif
253              
254             /* For MSC, we need to use _BitScanForward and _BitScanReverse. The way to
255             * get to them has changed, so we're going to only use them on new systems.
256             * The performance of these functions are not super critical.
257             * What is: popcnt, mulmod, and muladd.
258             */
259             #elif defined (_MSC_VER) && _MSC_VER >= 1400 && !defined(__clang__) && !defined(_WIN32_WCE)
260             #include
261             #ifdef FUNC_ctz
262             static int ctz(UV n) {
263             UV tz = 0;
264             #if BITS_PER_WORD == 64
265             if (_BitScanForward64(&tz, n)) return tz; else return 64;
266             #else
267             if (_BitScanForward(&tz, n)) return tz; else return 32;
268             #endif
269             }
270             #endif
271             #if defined(FUNC_clz) || defined(FUNC_log2floor)
272             static int log2floor(UV n) {
273             UV lz = 0;
274             #if BITS_PER_WORD == 64
275             if (_BitScanReverse64(&lz, n)) return lz; else return 0;
276             #else
277             if (_BitScanReverse(&lz, n)) return lz; else return 0;
278             #endif
279             }
280             #endif
281             #elif BITS_PER_WORD == 64
282             static const unsigned char _debruijn64[64] = {
283             63, 0,58, 1,59,47,53, 2, 60,39,48,27,54,33,42, 3, 61,51,37,40,49,18,28,20,
284             55,30,34,11,43,14,22, 4, 62,57,46,52,38,26,32,41, 50,36,17,19,29,10,13,21,
285             56,45,25,31,35,16, 9,12, 44,24,15, 8,23, 7, 6, 5 };
286             #ifdef FUNC_ctz
287             static unsigned int ctz(UV n) {
288             return n ? _debruijn64[((n & -n)*UVCONST(0x07EDD5E59A4E28C2)) >> 58] : 64;
289             }
290             #endif
291             #if defined(FUNC_clz) || defined(FUNC_log2floor)
292             static unsigned int log2floor(UV n) {
293             if (n == 0) return 0;
294             n |= n >> 1; n |= n >> 2; n |= n >> 4;
295             n |= n >> 8; n |= n >> 16; n |= n >> 32;
296             return _debruijn64[((n-(n>>1))*UVCONST(0x07EDD5E59A4E28C2)) >> 58];
297             }
298             #endif
299             #else
300             #ifdef FUNC_ctz
301             static const unsigned char _trail_debruijn32[32] = {
302             0, 1,28, 2,29,14,24, 3,30,22,20,15,25,17, 4, 8,
303             31,27,13,23,21,19,16, 7,26,12,18, 6,11, 5,10, 9 };
304             static unsigned int ctz(UV n) {
305             return n ? _trail_debruijn32[((n & -n) * UVCONST(0x077CB531)) >> 27] : 32;
306             }
307             #endif
308             #if defined(FUNC_clz) || defined(FUNC_log2floor)
309             static const unsigned char _lead_debruijn32[32] = {
310             0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
311             8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
312             static unsigned int log2floor(UV n) {
313             if (n == 0) return 0;
314             n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16;
315             return _lead_debruijn32[(n * UVCONST(0x07C4ACDD)) >> 27];
316             }
317             #endif
318             #endif
319             #if defined(FUNC_clz) && !defined(clz)
320             #define clz(n) ( (n) ? BITS_PER_WORD-1-log2floor(n) : BITS_PER_WORD )
321             #endif
322             #endif /* End of log2floor, clz, and ctz */
323              
324             #ifdef FUNC_popcnt
325             /* GCC 3.4 - 4.1 has broken 64-bit popcount.
326             * GCC 4.2+ can generate awful code when it doesn't have asm (GCC bug 36041).
327             * When the asm is present (e.g. compile with -march=native on a platform that
328             * has them, like Nahelem+), then it is almost as fast as manually written asm. */
329             #if BITS_PER_WORD == 64
330             #if defined(__POPCNT__) && defined(__GNUC__) && (__GNUC__> 4 || (__GNUC__== 4 && __GNUC_MINOR__> 1))
331             #define popcnt(b) __builtin_popcountll(b)
332             #else
333             static UV popcnt(UV b) {
334             b -= (b >> 1) & 0x5555555555555555;
335             b = (b & 0x3333333333333333) + ((b >> 2) & 0x3333333333333333);
336             b = (b + (b >> 4)) & 0x0f0f0f0f0f0f0f0f;
337             return (b * 0x0101010101010101) >> 56;
338             }
339             #endif
340             #else
341             static UV popcnt(UV b) {
342             b -= (b >> 1) & 0x55555555;
343             b = (b & 0x33333333) + ((b >> 2) & 0x33333333);
344             b = (b + (b >> 4)) & 0x0f0f0f0f;
345             return (b * 0x01010101) >> 24;
346             }
347             #endif
348             #endif
349              
350             #endif