int mpz_perfect_power_p (mpz_srcptr u) { unsigned long int prime; unsigned long int n, n2; int i; unsigned long int rem; mpz_t u2, q; int exact; mp_size_t uns; mp_size_t usize = SIZ (u); TMP_DECL; if (mpz_cmpabs_ui (u, 1) <= 0) return 1; /* -1, 0, and +1 are perfect powers */ n2 = mpz_scan1 (u, 0); if (n2 == 1) return 0; /* 2 divides exactly once. */ TMP_MARK; uns = ABS (usize) - n2 / BITS_PER_MP_LIMB; MPZ_TMP_INIT (q, uns); MPZ_TMP_INIT (u2, uns); mpz_tdiv_q_2exp (u2, u, n2); mpz_abs (u2, u2); if (mpz_cmp_ui (u2, 1) == 0) { TMP_FREE; /* factoring completed; consistent power */ return ! (usize < 0 && POW2P(n2)); } if (isprime (n2)) goto n2prime; for (i = 1; primes[i] != 0; i++) { prime = primes[i]; if (mpz_cmp_ui (u2, prime) < 0) break; if (mpz_divisible_ui_p (u2, prime)) /* divisible by this prime? */ { rem = mpz_tdiv_q_ui (q, u2, prime * prime); if (rem != 0) { TMP_FREE; return 0; /* prime divides exactly once, reject */ } mpz_swap (q, u2); for (n = 2;;) { rem = mpz_tdiv_q_ui (q, u2, prime); if (rem != 0) break; mpz_swap (q, u2); n++; } n2 = gcd (n2, n); if (n2 == 1) { TMP_FREE; return 0; /* we have multiplicity 1 of some factor */ } if (mpz_cmp_ui (u2, 1) == 0) { TMP_FREE; /* factoring completed; consistent power */ return ! (usize < 0 && POW2P(n2)); } /* As soon as n2 becomes a prime number, stop factoring. Either we have u=x^n2 or u is not a perfect power. */ if (isprime (n2)) goto n2prime; } } if (n2 == 0) { /* We found no factors above; have to check all values of n. */ unsigned long int nth; for (nth = usize < 0 ? 3 : 2;; nth++) { if (! isprime (nth)) continue; #if 0 exact = mpz_padic_root (q, u2, nth, PTH); if (exact) #endif exact = mpz_root (q, u2, nth); if (exact) { TMP_FREE; return 1; } if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0) { TMP_FREE; return 0; } } } else { unsigned long int nth; if (usize < 0 && POW2P(n2)) { TMP_FREE; return 0; } /* We found some factors above. We just need to consider values of n that divides n2. */ for (nth = 2; nth <= n2; nth++) { if (! isprime (nth)) continue; if (n2 % nth != 0) continue; #if 0 exact = mpz_padic_root (q, u2, nth, PTH); if (exact) #endif exact = mpz_root (q, u2, nth); if (exact) { if (! (usize < 0 && POW2P(nth))) { TMP_FREE; return 1; } } if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0) { TMP_FREE; return 0; } } TMP_FREE; return 0; } n2prime: if (usize < 0 && POW2P(n2)) { TMP_FREE; return 0; } exact = mpz_root (NULL, u2, n2); TMP_FREE; return exact; }
/* TRUE if radix-r is ugly for size n */ int X(ct_uglyp)(INT min_n, INT v, INT n, INT r) { return (n <= min_n) || (POW2P(n) && (v * (n / r)) <= 4); }
/* TRUE if radix-r is ugly for size n */ int fftwf_ct_uglyp(INT min_n, INT v, INT n, INT r) { return (n <= min_n) || (POW2P(n) && (v * (n / r)) <= 4); }