| Jeroen Demeyer on Wed, 24 Sep 2014 12:37:57 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Re: ispseudoprimepower() |
On 2014-09-09 21:33, Jeroen Demeyer wrote:
In attachment a patch implementing the libpari function ispseudoprimepower(). If you think this patch is a good idea, I can add the corresponding GP function and documentation.Sage currently has such a function but implemented not as efficiently as isprimepower(). You can imagine such a function being used to implement the construction of finite fields (In Sage, the constructor takes the order q as parameter) I could easily implement this in PARI if you want...
diff --git a/src/basemath/arith1.c b/src/basemath/arith1.c
index 5ba04a1..f7cb5df 100644
--- a/src/basemath/arith1.c
+++ b/src/basemath/arith1.c
@@ -1471,13 +1471,15 @@ Z_ispow2(GEN n)
return !(u & (u-1)); /* faster than hamming_word(u) == 1 */
}
-long
-isprimepower(GEN n, GEN *pt)
+/* Like isprimepower(), but handle only the cases where n fits in a
+ * long or where a tiny prime divides n.
+ * Return -1 if we couldn't yet determine whether n is a prime power. */
+static long
+isprimepower_small(GEN n, GEN* pt)
{
pari_sp av = avma;
long i, v;
- if (typ(n) != t_INT) pari_err_TYPE("isprimepower", n);
if (signe(n) <= 0) return 0;
if (lgefint(n) == 3)
@@ -1503,6 +1505,19 @@ isprimepower(GEN n, GEN *pt)
return v;
}
}
+ return -1;
+}
+
+long
+isprimepower(GEN n, GEN *pt)
+{
+ pari_sp av = avma;
+ long v;
+
+ if (typ(n) != t_INT) pari_err_TYPE("isprimepower", n);
+
+ if ((v = isprimepower_small(n, pt)) >= 0) return v;
+
/* p | n => p >= 103 */
v = Z_isanypower_nosmalldiv(&n); /* expensive */
if (!isprime(n)) { avma = av; return 0; }
@@ -1511,6 +1526,23 @@ isprimepower(GEN n, GEN *pt)
}
long
+ispseudoprimepower(GEN n, GEN *pt)
+{
+ pari_sp av = avma;
+ long v;
+
+ if (typ(n) != t_INT) pari_err_TYPE("ispseudoprimepower", n);
+
+ if ((v = isprimepower_small(n, pt)) >= 0) return v;
+
+ /* p | n => p >= 103 */
+ v = Z_isanypower_nosmalldiv(&n); /* expensive */
+ if (!ispseudoprime(n,0)) { avma = av; return 0; }
+ if (pt) *pt = gerepilecopy(av, n); else avma = av;
+ return v;
+}
+
+long
uisprimepower(ulong n, ulong *pp)
{ /* We must have CUTOFF^11 >= ULONG_MAX and CUTOFF^3 < ULONG_MAX.
* Tests suggest that 200-300 is the best range for 64-bit platforms. */
diff --git a/src/headers/paridecl.h b/src/headers/paridecl.h
index 7e02467..a8ac712 100644
--- a/src/headers/paridecl.h
+++ b/src/headers/paridecl.h
@@ -1369,6 +1369,7 @@ long isfundamental(GEN x);
long ispolygonal(GEN x, GEN S, GEN *N);
long ispower(GEN x, GEN k, GEN *pty);
long isprimepower(GEN x, GEN *pty);
+long ispseudoprimepower(GEN x, GEN *pty);
long issquare(GEN x);
long issquareall(GEN x, GEN *pt);
long krois(GEN x, long y);