Skip to content

Commit 639921b

Browse files
committed
Add PrimeZetaP function implementation and integrate into system
1 parent 7aea5fd commit 639921b

8 files changed

Lines changed: 1198 additions & 828 deletions

File tree

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/FunctionDefinitions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ private static void init() {
156156
S.PolynomialReduce
157157
.setEvaluator(new org.matheclipse.core.reflection.system.PolynomialReduce());
158158
S.PowerRange.setEvaluator(new org.matheclipse.core.reflection.system.PowerRange());
159+
S.PrimeZetaP.setEvaluator(new org.matheclipse.core.reflection.system.PrimeZetaP());
159160
S.Product.setEvaluator(new org.matheclipse.core.reflection.system.Product());
160161
S.Ratios.setEvaluator(new org.matheclipse.core.reflection.system.Ratios());
161162
S.Reduce.setEvaluator(new org.matheclipse.core.reflection.system.Reduce());

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/SpecialFunctions.java

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,10 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
15981598
IExpr z = ast.arg1();
15991599
IExpr s = ast.arg2();
16001600
IExpr a = ast.arg3();
1601+
return evaluateSymbolic(z, s, a, engine);
1602+
}
1603+
1604+
private static IExpr evaluateSymbolic(IExpr z, IExpr s, IExpr a, EvalEngine engine) {
16011605
if (s.isZero()) {
16021606
// https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/02/01/0007/
16031607
return F.Power(F.Subtract(F.C1, z), F.CN1);
@@ -1644,7 +1648,6 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
16441648
return F.Times(F.QQ(1L, 6L), F.Sqr(F.Pi));
16451649
}
16461650

1647-
16481651
if (a.isOne()) {
16491652
IExpr re = s.re();
16501653
if (re.isReal() && ((IReal) re).isGT(F.C1)) {
@@ -1665,7 +1668,6 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
16651668
// (1+I)*PolyLog(2,1/2-I/2)
16661669
return F.Times(F.Plus(F.C1, F.CI), F.PolyLog(F.C2, F.CC(1, 2, -1, 2)));
16671670
}
1668-
16691671
}
16701672

16711673
int n = a.toIntDefault();
@@ -1687,9 +1689,70 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
16871689
}
16881690
}
16891691

1692+
return F.NIL;
1693+
}
1694+
1695+
@Override
1696+
public IExpr numericFunction(IAST ast, final EvalEngine engine) {
1697+
if (ast.argSize() == 3) {
1698+
try {
1699+
double z = ast.arg1().evalf();
1700+
double s = ast.arg2().evalf();
1701+
double a = ast.arg3().evalf();
16901702

1703+
// The series expansion only converges for |z| < 1 or (z == 1 and s > 1)
1704+
if (Math.abs(z) < 1.0 || (Math.abs(z - 1.0) < 1e-14 && s > 1.0)) {
1705+
return F.num(lerchPhiNumeric(z, s, a));
1706+
}
1707+
} catch (ValidateException ve) {
1708+
// Fallback if inputs cannot be evaluated to machine-precision doubles
1709+
}
1710+
}
16911711
return F.NIL;
16921712
}
1713+
/**
1714+
* Compute LerchPhi numerically via series: Sum(z^k / (k+a)^s)
1715+
*/
1716+
private double lerchPhiNumeric(double z, double s, double a) {
1717+
// For z = 1, this is the Hurwitz zeta: Sum(1/(k+a)^s)
1718+
// Use Euler-Maclaurin to add tail correction for better convergence
1719+
int nTerms = Math.abs(z - 1.0) < 1e-14 ? 200 : 1000;
1720+
double sum = 0.0;
1721+
double zPow = 1.0; // z^k
1722+
1723+
for (int k = 0; k < nTerms; k++) {
1724+
double denom = Math.pow(k + a, s);
1725+
if (Math.abs(denom) > 1e-300) {
1726+
double term = zPow / denom;
1727+
sum += term;
1728+
if (Math.abs(term) < 1e-15 * Math.abs(sum) && k > 5) {
1729+
return sum;
1730+
}
1731+
}
1732+
zPow *= z;
1733+
if (Math.abs(zPow) < 1e-300) {
1734+
return sum;
1735+
}
1736+
}
1737+
1738+
// For z=1 (Hurwitz zeta), add Euler-Maclaurin tail to extend the partial sum:
1739+
// Sum(f(k), {k, N, Infinity}) ~ Integrate(f(t), {t, N, Infinity}) + f(N)/2 - f'(N)/12 +
1740+
// f'''(N)/720 - ...
1741+
// with f(t) = 1/(t+a)^s.
1742+
if (Math.abs(z - 1.0) < 1e-14 && s > 1.0) {
1743+
double n = nTerms;
1744+
double na = n + a;
1745+
double tail = Math.pow(na, 1.0 - s) / (s - 1.0);
1746+
double f_n = 1.0 / Math.pow(na, s);
1747+
// -f'(N)/12 = s / (12 (N+a)^(s+1))
1748+
double em2 = s / (12.0 * Math.pow(na, s + 1.0));
1749+
// f'''(N)/720 = -s(s+1)(s+2) / (720 (N+a)^(s+3))
1750+
double em3 = -s * (s + 1.0) * (s + 2.0) / (720.0 * Math.pow(na, s + 3.0));
1751+
sum += tail + f_n / 2.0 + em2 + em3;
1752+
}
1753+
1754+
return sum;
1755+
}
16931756

16941757
@Override
16951758
public int[] expectedArgSize(IAST ast) {

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/convert/AST2Expr.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -297,16 +297,16 @@ public class AST2Expr {
297297
"PositiveSemidefiniteMatrixQ", "PossibleZeroQ", "Postfix", "Power", "PowerExpand", "PowerMod",
298298
"PowerRange", "PowersRepresentations", "PrecedenceForm", "Precision", "PreDecrement",
299299
"Prefix", "PreIncrement", "Prepend", "PrependTo", "Prime", "PrimeOmega", "PrimePi",
300-
"PrimePowerQ", "PrimeQ", "PrimitiveRoot", "PrimitiveRootList", "PrincipalComponents", "Print",
301-
"PrintableASCIIQ", "Prism", "Probability", "Product", "ProductLog", "Projection",
302-
"Proportion", "Proportional", "Protect", "PseudoInverse", "Put", "PutAppend", "Pyramid",
303-
"QRDecomposition", "QuadraticIrrationalQ", "Quantile", "Quantity", "QuantityDistribution",
304-
"QuantityMagnitude", "QuantityQ", "QuantityUnit", "QuarticSolve", "Quartiles", "Quiet",
305-
"Quit", "Quotient", "QuotientRemainder", "RadicalBox", "Ramp", "RamseyNumber", "Random",
306-
"RandomChoice", "RandomComplex", "RandomGraph", "RandomInteger", "RandomPermutation",
307-
"RandomPrime", "RandomReal", "RandomSample", "RandomVariate", "Range", "RankedMax",
308-
"RankedMin", "Rational", "Rationalize", "Ratios", "RawBackquote", "RawBoxes", "Re", "Read",
309-
"ReadLine", "ReadList", "ReadString", "RealAbs", "RealDigits", "RealSign",
300+
"PrimePowerQ", "PrimeQ", "PrimeZetaP", "PrimitiveRoot", "PrimitiveRootList",
301+
"PrincipalComponents", "Print", "PrintableASCIIQ", "Prism", "Probability", "Product",
302+
"ProductLog", "Projection", "Proportion", "Proportional", "Protect", "PseudoInverse", "Put",
303+
"PutAppend", "Pyramid", "QRDecomposition", "QuadraticIrrationalQ", "Quantile", "Quantity",
304+
"QuantityDistribution", "QuantityMagnitude", "QuantityQ", "QuantityUnit", "QuarticSolve",
305+
"Quartiles", "Quiet", "Quit", "Quotient", "QuotientRemainder", "RadicalBox", "Ramp",
306+
"RamseyNumber", "Random", "RandomChoice", "RandomComplex", "RandomGraph", "RandomInteger",
307+
"RandomPermutation", "RandomPrime", "RandomReal", "RandomSample", "RandomVariate", "Range",
308+
"RankedMax", "RankedMin", "Rational", "Rationalize", "Ratios", "RawBackquote", "RawBoxes",
309+
"Re", "Read", "ReadLine", "ReadList", "ReadString", "RealAbs", "RealDigits", "RealSign",
310310
"RealValuedNumberQ", "RealValuedNumericQ", "Reap", "Rectangle", "Reduce", "Refine",
311311
"RegularExpression", "ReIm", "ReleaseHold", "Remove", "RemoveDiacritics", "Repeated",
312312
"RepeatedNull", "RepeatedTiming", "Replace", "ReplaceAll", "ReplaceAt", "ReplaceList",

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/EvalEngine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,8 +1974,8 @@ public final Complex evalComplex(IExpr expr, final Function<IExpr, IExpr> functi
19741974
} finally {
19751975
fQuietMode = quietMode;
19761976
}
1977-
throw new ArgumentTypeException(
1978-
"conversion into a machine-size Complex numeric value is not possible!");
1977+
throw new ArgumentTypeException("Expression \"" + Errors.shorten(expr)
1978+
+ "\" cannot be converted to a machine-sized Complex numeric value!");
19791979
}
19801980

19811981
public final Complex[][] evalComplexMatrix(final IExpr expr) {

0 commit comments

Comments
 (0)