File Coverage

util.h
Criterion Covered Total %
statement 16 16 100.0
branch 6 6 100.0
condition n/a
subroutine n/a
pod n/a
total 22 22 100.0


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 _XS_get_verbose(void);
7             extern void _XS_set_verbose(int v);
8             extern int _XS_get_callgmp(void);
9             extern void _XS_set_callgmp(int v);
10             /* Disable all manual seeding */
11             extern bool _XS_get_secure(void);
12             extern void _XS_set_secure(void);
13              
14             extern unsigned long index_in_sorted_uv_array(UV v, UV* L, unsigned long len);
15             extern unsigned long index_in_sorted_iv_array(IV v, IV* L, unsigned long len);
16             #define is_in_sorted_uv_array(v,L,len) (index_in_sorted_uv_array(v,L,len) > 0)
17             #define is_in_sorted_iv_array(v,L,len) (index_in_sorted_iv_array(v,L,len) > 0)
18              
19             extern bool do_arrays_intersect_uv(const UV* A, size_t alen, const UV* B, size_t blen);
20             extern bool do_arrays_intersect_iv(const IV* A, size_t alen, const IV* B, size_t blen);
21              
22             extern bool is_prime(UV x);
23             extern UV next_prime(UV x);
24             extern UV prev_prime(UV x);
25              
26             /* Simple estimate for upper limit: max_nprimes(n) >= prime_count(n) */
27             extern UV max_nprimes(UV n) ISCONSTFUNC;
28              
29             extern void print_primes(UV low, UV high, int fd);
30              
31             /* Returns maximal k for c^k = n for k > 1, n > 1. 0 otherwise. */
32             extern uint32_t powerof_ret(UV n, uint32_t *root);
33             #define powerof(n) powerof_ret(n,0)
34              
35             /* Return true if n = r^k for the given k, sets root if given */
36             extern bool is_power_ret(UV n, uint32_t k, uint32_t *root);
37             #define is_power(n,k) is_power_ret(n,k,0)
38              
39             extern uint32_t icbrt(UV n) ISCONSTFUNC;
40             extern UV rootint(UV n, uint32_t k) ISCONSTFUNC;
41             extern UV ipowsafe(UV n, UV k) ISCONSTFUNC; /* returns UV_MAX if overflows */
42             extern UV lcmsafe(UV x, UV u) ISCONSTFUNC; /* returns 0 if overflows */
43             extern UV valuation(UV n, UV k) ISCONSTFUNC;
44             extern UV valuation_remainder(UV n, UV k, UV *r);
45             extern UV logint(UV n, UV b) ISCONSTFUNC;
46             extern UV mpu_popcount_string(const char* ptr, uint32_t len);
47              
48             extern unsigned char* range_issquarefree(UV lo, UV hi);
49              
50             extern UV powersum(UV n, UV k) ISCONSTFUNC;
51              
52             extern signed char* range_moebius(UV low, UV high);
53             extern signed char* range_liouville(UV low, UV high);
54              
55             extern int liouville(UV n);
56             extern IV mertens(UV n);
57             extern IV sumliouville(UV n);
58              
59             extern int kronecker_uu(UV a, UV b) ISCONSTFUNC;
60             extern int kronecker_su(IV a, UV b) ISCONSTFUNC;
61             extern int kronecker_ss(IV a, IV b) ISCONSTFUNC;
62              
63             extern UV pn_primorial(UV n) ISCONSTFUNC;
64             extern UV primorial(UV n) ISCONSTFUNC;
65             extern UV factorial(UV n) ISCONSTFUNC;
66             extern UV subfactorial(UV n) ISCONSTFUNC;
67             extern UV fubini(UV n) ISCONSTFUNC;
68             extern UV binomial(UV n, UV k) ISCONSTFUNC;
69             extern UV falling_factorial(UV n, UV m) ISCONSTFUNC;
70             extern UV rising_factorial(UV n, UV m) ISCONSTFUNC;
71             extern IV falling_factorial_s(IV n, UV m) ISCONSTFUNC;
72             extern IV rising_factorial_s(IV n, UV m) ISCONSTFUNC;
73             extern IV gcdext(IV a, IV b, IV* u, IV* v, IV* s, IV* t); /* Ext Euclidean */
74             extern UV modinverse(UV a, UV p) ISCONSTFUNC; /* Returns 1/a mod p */
75             extern UV divmod(UV a, UV b, UV n) ISCONSTFUNC;/* Returns a/b mod n */
76             extern UV gcddivmod(UV a, UV b, UV n) ISCONSTFUNC; /* divmod(a/gcd,b/gcd,n) */
77              
78             extern UV pisano_period(UV n);
79              
80             /* 0 overflow, -1 no inverse, 1 ok */
81             /* The a/n arrays will be sorted by descending n. */
82             extern int chinese(UV *r, UV *lcm, UV* a, UV* n, UV num);/* Chinese Remainder */
83              
84             /* Do the inverse for a negative modular power / root. a^-k => (1/a)^k mod n */
85             extern bool prep_pow_inv(UV *a, UV *k, int kstatus, UV n);
86              
87             /* Signed division and remainder. Returns remainder.*/
88             extern IV tdivrem(IV *q, IV *r, IV D, IV d); /* divrem trunc */
89             extern IV fdivrem(IV *q, IV *r, IV D, IV d); /* divrem floor */
90             extern IV cdivrem(IV *q, IV *r, IV D, IV d); /* divrem ceiling */
91             extern IV edivrem(IV *q, IV *r, IV D, IV d); /* divrem Euclidian */
92             extern UV ivmod(IV a, UV n) ISCONSTFUNC; /* Returns a mod n (trunc) */
93              
94             extern UV carmichael_lambda(UV n);
95             extern int moebius(UV n);
96             extern UV exp_mangoldt(UV n);
97             extern UV znprimroot(UV n);
98             extern UV znorder(UV a, UV n);
99             /* nprime says to assume n = p or n = 2p. Skips power and primality tests. */
100             extern bool is_primitive_root(UV a, UV n, bool nprime);
101             extern UV factorialmod(UV n, UV m);
102             extern bool binomialmod(UV *res, UV n, UV k, UV m);
103              
104             extern bool is_square_free(UV n);
105             extern bool is_perfect_number(UV n);
106             extern bool is_fundamental(UV n, bool neg);
107             extern bool is_semiprime(UV n);
108             extern bool is_almost_prime(UV k, UV n);
109             extern bool is_cyclic(UV n);
110             extern bool is_carmichael(UV n);
111             extern UV is_quasi_carmichael(UV n); /* Returns number of bases */
112             extern UV pillai_v(UV n) ISCONSTFUNC; /* v: v! % n == n-1 && n % v != 1 */
113             extern UV qnr(UV n);
114             extern bool is_qr(UV a, UV n); /* kronecker that works for composites */
115             extern bool is_practical(UV n);
116             extern int is_delicate_prime(UV n, uint32_t b);
117             extern int happy_height(UV n, uint32_t base, uint32_t exponent) ISCONSTFUNC;
118              
119             extern bool is_smooth(UV n, UV k);
120             extern bool is_rough(UV n, UV k);
121              
122             extern bool is_sum_of_two_squares(UV n);
123             extern bool is_sum_of_three_squares(UV n);
124             extern bool cornacchia(UV *x, UV *y, UV d, UV p);
125              
126             extern UV debruijn_psi(UV x, UV y);
127             extern UV buchstab_phi(UV x, UV y);
128              
129             extern UV stirling3(UV n, UV m) ISCONSTFUNC;
130             extern IV stirling2(UV n, UV m) ISCONSTFUNC;
131             extern IV stirling1(UV n, UV m) ISCONSTFUNC;
132              
133             extern bool bernfrac(IV *num, UV *den, UV n);
134             extern bool harmfrac(UV *num, UV *den, UV n);
135              
136             extern IV hclassno(UV n);
137             extern IV ramanujan_tau(UV n);
138              
139             extern char* pidigits(uint32_t digits);
140              
141             /* min defines if min or max. Return of 0 means select a, 1 means select b. */
142             extern bool strnum_minmax(bool min, const char* a, STRLEN alen, const char* b, STRLEN blen);
143             extern int strnum_cmp(const char* a, STRLEN alen, const char* b, STRLEN blen);
144              
145             extern bool from_digit_string(UV* n, const char* s, int base);
146             extern bool from_digit_to_UV(UV* rn, const UV* r, int len, int base);
147             extern bool from_digit_to_str(char** rstr, const UV* r, int len, int base);
148             /* These return length */
149             extern int to_digit_array(int* bits, UV n, int base, int length);
150             extern int to_digit_string(char *s, UV n, int base, int length);
151             extern int to_string_128(char s[40], IV hi, UV lo);
152              
153             /* Returns 1 if good, 0 if bad, -1 if non canon, 2 ok but out of range */
154             extern int validate_zeckendorf(const char* str);
155             extern UV from_zeckendorf(const char* str);
156             extern char* to_zeckendorf(UV n);
157              
158             extern bool is_catalan_pseudoprime(UV n);
159              
160             extern UV polygonal_root(UV n, UV k, bool* overflow);
161              
162             extern UV npartitions(UV n);
163             extern UV consecutive_integer_lcm(UV n);
164              
165             extern UV frobenius_number(UV* A, uint32_t alen);
166              
167             extern bool num_to_perm(UV rank, int n, int *vec);
168             extern bool perm_to_num(int n, int *vec, UV *rank);
169             extern void randperm(void* ctx, UV n, UV k, UV *S);
170              
171             extern UV random_factored_integer(void* ctx, UV n, int *nf, UV *factors);
172              
173             extern UV gcdz(UV x, UV y) ISCONSTFUNC;
174              
175              
176             /* Inputs are assumed to be UNSIGNED */
177             /* These could use a static table if that turned out better */
178              
179             #define is_divis_2_3(n) ( (n)%2 == 0 || (n) % 3 == 0 )
180              
181             #if defined(__arm64__)
182             #define is_divis_2_3_5(n) ( (n)%2 == 0 || (0x1669>>((n)%15))&1 )
183             #else
184             #define is_divis_2_3_5(n) ( (n)%2 == 0 || (n) % 3 == 0 || (n) % 5 == 0 )
185             #endif
186             /* 2,3,5 could use the single test: (0x1f75d77d >> (n % 30)) & 1 */
187              
188             #define is_divis_2_3_5_7(n) ( is_divis_2_3_5(n) || (n) % 7 == 0 )
189              
190              
191             /******************************************************************************/
192              
193             #if defined(FUNC_is_perfect_square) && !defined(FUNC_isqrt)
194             #define FUNC_isqrt 1
195             #endif
196             #if defined(FUNC_lcm_ui) && !defined(FUNC_gcd_ui)
197             #define FUNC_gcd_ui 1
198             #endif
199              
200             /******************************************************************************/
201              
202             /* I think uint32_t is a better return type, but we follow GCC's prototype. */
203              
204             #if defined(FUNC_clz) || defined(FUNC_ctz) || defined(FUNC_log2floor)
205             /* log2floor(n) gives the location of the first set bit (starting from left)
206             * ctz(n) gives the number of times n is divisible by 2
207             * clz(n) gives the number of zeros on the left */
208             #if defined(__GNUC__) && 100*__GNUC__ + __GNUC_MINOR >= 304
209             #if BITS_PER_WORD == 64
210             #define ctz(n) ((n) ? __builtin_ctzll(n) : 64)
211             #define clz(n) ((n) ? __builtin_clzll(n) : 64)
212             #define log2floor(n) ((n) ? 63-__builtin_clzll(n) : 0)
213             #else
214             #define ctz(n) ((n) ? __builtin_ctzl(n) : 32)
215             #define clz(n) ((n) ? __builtin_clzl(n) : 32)
216             #define log2floor(n) ((n) ? 31-__builtin_clzl(n) : 0)
217             #endif
218              
219             /* For MSC, we need to use _BitScanForward and _BitScanReverse. The way to
220             * get to them has changed, so we're going to only use them on new systems.
221             * The performance of these functions are not super critical.
222             * What is: popcnt, mulmod, and muladd.
223             */
224             #elif defined (_MSC_VER) && _MSC_VER >= 1400 && !defined(__clang__) && !defined(_WIN32_WCE)
225             #include
226             #ifdef FUNC_ctz
227             static int ctz(UV n) {
228             UV tz = 0;
229             #if BITS_PER_WORD == 64
230             if (_BitScanForward64(&tz, n)) return tz; else return 64;
231             #else
232             if (_BitScanForward(&tz, n)) return tz; else return 32;
233             #endif
234             }
235             #endif
236             #if defined(FUNC_clz) || defined(FUNC_log2floor)
237             static int log2floor(UV n) {
238             UV lz = 0;
239             #if BITS_PER_WORD == 64
240             if (_BitScanReverse64(&lz, n)) return lz; else return 0;
241             #else
242             if (_BitScanReverse(&lz, n)) return lz; else return 0;
243             #endif
244             }
245             #endif
246             #elif BITS_PER_WORD == 64
247             static const unsigned char _debruijn64[64] = {
248             63, 0,58, 1,59,47,53, 2, 60,39,48,27,54,33,42, 3, 61,51,37,40,49,18,28,20,
249             55,30,34,11,43,14,22, 4, 62,57,46,52,38,26,32,41, 50,36,17,19,29,10,13,21,
250             56,45,25,31,35,16, 9,12, 44,24,15, 8,23, 7, 6, 5 };
251             #ifdef FUNC_ctz
252             static int ctz(UV n) {
253             return n ? _debruijn64[((n & -n)*UVCONST(0x07EDD5E59A4E28C2)) >> 58] : 64;
254             }
255             #endif
256             #if defined(FUNC_clz) || defined(FUNC_log2floor)
257             static int log2floor(UV n) {
258             if (n == 0) return 0;
259             n |= n >> 1; n |= n >> 2; n |= n >> 4;
260             n |= n >> 8; n |= n >> 16; n |= n >> 32;
261             return _debruijn64[((n-(n>>1))*UVCONST(0x07EDD5E59A4E28C2)) >> 58];
262             }
263             #endif
264             #else
265             #ifdef FUNC_ctz
266             static const unsigned char _trail_debruijn32[32] = {
267             0, 1,28, 2,29,14,24, 3,30,22,20,15,25,17, 4, 8,
268             31,27,13,23,21,19,16, 7,26,12,18, 6,11, 5,10, 9 };
269             static int ctz(UV n) {
270             return n ? _trail_debruijn32[((n & -n) * UVCONST(0x077CB531)) >> 27] : 32;
271             }
272             #endif
273             #if defined(FUNC_clz) || defined(FUNC_log2floor)
274             static const unsigned char _lead_debruijn32[32] = {
275             0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
276             8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
277             static int log2floor(UV n) {
278             if (n == 0) return 0;
279             n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16;
280             return _lead_debruijn32[(n * UVCONST(0x07C4ACDD)) >> 27];
281             }
282             #endif
283             #endif
284             #if defined(FUNC_clz) && !defined(clz)
285             #define clz(n) ( (n) ? BITS_PER_WORD-1-log2floor(n) : BITS_PER_WORD )
286             #endif
287             #endif /* End of log2floor, clz, and ctz */
288              
289             #ifdef FUNC_popcnt
290             /* GCC 3.4 - 4.1 has broken 64-bit popcount.
291             * GCC 4.2+ can generate awful code when it doesn't have asm (GCC bug 36041).
292             * When the asm is present (e.g. compile with -march=native on a platform that
293             * has them, like Nahelem+), then it is almost as fast as manually written asm. */
294             #if BITS_PER_WORD == 64
295             #if defined(__POPCNT__) && defined(__GNUC__) && 100*__GNUC__ + __GNUC_MINOR >= 402
296             #define popcnt(b) __builtin_popcountll(b)
297             #else
298 11           static int popcnt(UV b) {
299 11           b -= (b >> 1) & 0x5555555555555555;
300 11           b = (b & 0x3333333333333333) + ((b >> 2) & 0x3333333333333333);
301 11           b = (b + (b >> 4)) & 0x0f0f0f0f0f0f0f0f;
302 11           return (b * 0x0101010101010101) >> 56;
303             }
304             #endif
305             #else
306             static int popcnt(UV b) {
307             b -= (b >> 1) & 0x55555555;
308             b = (b & 0x33333333) + ((b >> 2) & 0x33333333);
309             b = (b + (b >> 4)) & 0x0f0f0f0f;
310             return (b * 0x01010101) >> 24;
311             }
312             #endif
313             #endif
314              
315              
316             /******************************************************************************/
317              
318              
319             #if defined(FUNC_ipow)
320 2694           static UV ipow(UV n, UV k) {
321 2694           UV p = 1;
322 8732 100         while (k) {
323 6038 100         if (k & 1) p *= n;
324 6038           k >>= 1;
325 6038 100         if (k) n *= n;
326             }
327 2694           return p;
328             }
329             #endif
330              
331              
332             #if defined(FUNC_gcd_ui)
333             /* If we have a very fast ctz, then use the fast FLINT version of gcd */
334             #if defined(__GNUC__) && 100*__GNUC__ + __GNUC_MINOR >= 304
335             #define gcd_ui(x,y) gcdz(x,y)
336             #else
337             static UV gcd_ui(UV x, UV y) {
338             UV t;
339             if (y > x) { t = x; x = y; y = t; }
340             while (y > 0) {
341             t = y; y = x % y; x = t; /* y1 <- x0 % y0 ; x1 <- y0 */
342             }
343             return x;
344             }
345             #endif
346             #endif
347              
348             #ifdef FUNC_lcm_ui
349             static UV lcm_ui(UV x, UV y) {
350             /* Can overflow if lcm(x,y) > 2^64 (e.g. two primes each > 2^32) */
351             return x * (y / gcd_ui(x,y));
352             }
353             #endif
354              
355              
356             #if defined(FUNC_isqrt)
357             /* Correct for all 64-bit inputs and all FP rounding modes. */
358             #include
359 65447           static uint32_t isqrt(UV n) {
360             /* The small addition means we only need to check for fixing downwards. */
361 65447           IV r = sqrt((double)n) + 1e-6f;
362 65447           IV diff = n - (UV)r*r;
363 65447           return r - (diff < 0);
364             }
365             #endif
366              
367             #ifdef FUNC_is_perfect_square
368             static bool is_perfect_square_ret(UV n, uint32_t *root)
369             {
370             uint32_t r;
371             /* Fast filters reject 95.0% of non-squares */
372             #if BITS_PER_WORD == 64
373             if ((UVCONST(1) << (n&63)) & UVCONST(0xfdfdfdedfdfcfdec)) return 0;
374             /* if ((UVCONST(1) << (n%45)) & UVCONST(0xfffffeeb7df6f9ec)) return 0; */
375             #else
376             /* uint32_t m; */
377             if ((1U << (n&31)) & 0xfdfcfdec) return 0;
378             /* m = n % 105; if ((m*0xd24554cd) & (m*0x0929579a) & 0x38020141) return 0; */
379             #endif
380             r = isqrt(n);
381             if (root != 0) *root = r;
382             return ((UV)r*r == n);
383             }
384             #define is_perfect_square(n) is_perfect_square_ret(n,0)
385             #endif
386              
387             #endif