From 5b8c4bb631764ee7af09115420df2cb41046250d Mon Sep 17 00:00:00 2001 From: axexlck Date: Sat, 9 Nov 2024 16:36:08 +0100 Subject: [PATCH] Improve `LerchPhi` --- .../core/builtin/SpecialFunctions.java | 92 ++++++++++++++++--- .../exception/ASTElementLimitExceeded.java | 5 +- .../exception/BigIntegerLimitExceeded.java | 36 ++++---- .../org/matheclipse/core/expression/F.java | 2 +- .../system/rules/AutomaticRules.java | 1 - .../system/rules/DerivativeRules.java | 10 +- .../system/rules/FunctionExpandRules.java | 3 + .../system/rules/LerchPhiRules.java | 48 ---------- symja_android_library/rules/DerivativeRules.m | 5 +- .../rules/FunctionExpandRules.m | 3 +- symja_android_library/rules/LerchPhiRules.m | 13 --- 11 files changed, 121 insertions(+), 97 deletions(-) delete mode 100644 symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/LerchPhiRules.java delete mode 100644 symja_android_library/rules/LerchPhiRules.m diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/SpecialFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/SpecialFunctions.java index 54b5a1038d..f444693d0a 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/SpecialFunctions.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/SpecialFunctions.java @@ -29,7 +29,6 @@ import org.hipparchus.exception.MathIllegalArgumentException; import org.hipparchus.exception.MathIllegalStateException; import org.matheclipse.core.basic.Config; -import org.matheclipse.core.basic.OperationSystem; import org.matheclipse.core.builtin.functions.BesselJS; import org.matheclipse.core.builtin.functions.GammaJS; import org.matheclipse.core.builtin.functions.ZetaJS; @@ -1489,24 +1488,95 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { IExpr s = ast.arg2(); IExpr a = ast.arg3(); if (s.isZero()) { + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/02/01/0007/ return F.Power(F.Subtract(F.C1, z), F.CN1); } - if (a.isZero()) { - return F.PolyLog(s, z); + if (z.isZero()) { + if (s.isOne() && a.isZero()) { + // LerchPhi(0,1,0) + return F.C0; + } + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/03/01/0002/ + // (a^2)^(-s/2) + return F.Power(F.Power(a, 2), s.isOne() ? F.CN1D2 : F.Times(F.CN1D2, s)); } - if (a.isOne()) { - // PolyLog(s, z)/z - return F.Times(F.PolyLog(s, z), F.Power(z, F.CN1)); + if (z.isMinusOne()) { + if (s.isOne() && a.isZero()) { + // LerchPhi(-1,1,0) + // -Log(2) + return F.Negate(F.Log(F.C2)); + } + if (s.isNumEqualInteger(F.C2) && a.isRationalValue(F.C1D2)) { + // LerchPhi(-1,2,1/2) + // 4*Catalan + return F.Times(F.C4, F.Catalan); + } + if (a.isOne()) { + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/05/01/ + // (1-2^(1-s))*Zeta(s) + return F.Times(F.Subtract(F.C1, F.Power(F.C2, F.Subtract(F.C1, s))), F.Zeta(s)); + } + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/03/01/0001/ + // Zeta(s,a/2)/2^s-Zeta(s,1/2*(1+a))/2^s + return F.Plus(F.Times(F.Power(F.Power(F.C2, s), F.CN1), F.Zeta(s, F.Times(F.C1D2, a))), + F.Times(F.CN1, F.Power(F.Power(F.C2, s), F.CN1), + F.Zeta(s, F.Times(F.C1D2, F.Plus(F.C1, a))))); + } + if (z.isOne()) { + if (s.isOne() && a.isNumber()) { + return F.CInfinity; + } + if (s.isNumEqualInteger(F.C2) && a.isOne()) { + // LerchPhi(1, 2, 1) + // Pi^2/6 + return F.Times(F.QQ(1L, 6L), F.Sqr(F.Pi)); + } + + + if (a.isOne()) { + IExpr re = s.re(); + if (re.isReal() && ((IReal) re).isGT(F.C1)) { + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/05/01/0001/ + return F.Zeta(s); + } + } + } else if (z.isNumEqualInteger(F.C2)) { + if (s.isOne() && a.isZero()) { + // LerchPhi(2, 1, 0) + // -I*Pi + F.Times(F.CNI, F.Pi); + } + } else if (z.equals(F.CC(1, 2, -1, 2))) { + if (s.isNumEqualInteger(F.C2) && a.isOne()) { + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/02/01/0003/ + // LerchPhi(1/2-1/2*I, 2, 1) + // (1+I)*PolyLog(2,1/2-I/2) + return F.Times(F.Plus(F.C1, F.CI), F.PolyLog(F.C2, F.CC(1, 2, -1, 2))); + } + } - if (z.isZero()) { - if (s.isOne()) { - return F.Power(F.Power(a, 2), F.CN1D2); + int n = a.toIntDefault(); + if (n != Integer.MIN_VALUE) { + IExpr polyLog = engine.evaluate(F.PolyLog(s, z)); + if (n <= 0) { + n = -n; + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/01/01/0002/ + // z^n*(PolyLog(s,z)+Sum(1/(z^k*k^s),{k,1,n})) + return F.Times(F.Power(z, n), // + F.Plus(polyLog, // + F.sum(k -> F.Power(F.Times(F.Power(z, k), F.Power(k, s)), F.CN1), 1, n))); + } else { + // https://functions.wolfram.com/ZetaFunctionsandPolylogarithms/LerchPhi/03/01/01/01/0009/ + // (PolyLog(s,z)-Sum(z^k/k^s,{k,1,-1+n}))/z^n + return F.Times(F.Power(z, -n), // + F.Subtract(polyLog, // + F.sum(k -> F.Times(F.Power(F.Power(k, s), F.CN1), F.Power(z, k)), 1, n - 1))); } - // (a^2)^(-s/2) - return F.Power(F.Power(a, F.C2), F.Times(F.CN1D2, s)); } + + return F.NIL; } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/ASTElementLimitExceeded.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/ASTElementLimitExceeded.java index 7997e8d748..5608e8bc4a 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/ASTElementLimitExceeded.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/ASTElementLimitExceeded.java @@ -1,6 +1,6 @@ package org.matheclipse.core.eval.exception; -/** Exception which will be thrown, if the Config.MAX_AST_SIZE limit was exceeded. */ +/** Exception which will be thrown, if the {@link Config#MAX_AST_SIZE} limit was exceeded. */ public class ASTElementLimitExceeded extends LimitException { private static final long serialVersionUID = 8925451277545397036L; @@ -27,7 +27,8 @@ public String getMessage() { } /** - * Throws exception which will be thrown, if the Config.MAX_AST_SIZE limit was exceeded. + * Throws a new ASTElementLimitExceeded exception, if the {@link Config#MAX_AST_SIZE} + * limit was exceeded. * *

* Usage: diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/BigIntegerLimitExceeded.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/BigIntegerLimitExceeded.java index ae9b8a2a1e..e3bde77010 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/BigIntegerLimitExceeded.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/BigIntegerLimitExceeded.java @@ -1,6 +1,8 @@ package org.matheclipse.core.eval.exception; -/** Exception which will be thrown, if the Config.MAX_AST_SIZE limit was exceeded. */ +import org.matheclipse.core.basic.Config; + +/** Exception which will be thrown, if the {@link Config#MAX_BIT_LENGTH} was exceeded. */ public class BigIntegerLimitExceeded extends LimitException { private static final long serialVersionUID = 8925451277545397036L; @@ -11,27 +13,27 @@ public BigIntegerLimitExceeded(final long limit) { fLimit = limit; } - /** - * Set the exceeded limit to (long)rowDimension*(long)columnDimension. - * - * @param rowDimension - * @param columnDimension - */ - public BigIntegerLimitExceeded(int rowDimension, int columnDimension) { - fLimit = rowDimension * (long) columnDimension; - } - @Override public String getMessage() { return "BigInteger bit length " + fLimit + " exceeded"; } + /** + * Throws a new BigIntegerLimitExceeded exception, if the + * {@link Config#MAX_BIT_LENGTH} limit was exceeded. + * + *

+ * Usage: + * + *

+   * if (((IInteger) number).bitLength() > Config.MAX_BIT_LENGTH / 100) {
+   *   BigIntegerLimitExceeded.throwIt(Config.MAX_BIT_LENGTH / 100);
+   * }
+   * 
+ * + * @param limit + */ public static void throwIt(final long limit) { - // HeapContext.enter(); - // try { - throw new BigIntegerLimitExceeded(limit); // .copy()); - // } finally { - // HeapContext.exit(); - // } + throw new BigIntegerLimitExceeded(limit); } } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java index bdb013f8f6..a8570a3ddc 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java @@ -10085,7 +10085,7 @@ public static IExpr intSum(final Function function, final int f number = number.plus((INumber) temp); if (number instanceof IInteger // && ((IInteger) number).bitLength() > Config.MAX_BIT_LENGTH / 100) { - BigIntegerLimitExceeded.throwIt(Config.MAX_BIT_LENGTH / 100); + BigIntegerLimitExceeded.throwIt(((IInteger) number).bitLength()); } } else { numberOfLeaves += temp.leafCount() + 1; diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/AutomaticRules.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/AutomaticRules.java index 7d51e15ff2..35a4a6de0f 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/AutomaticRules.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/AutomaticRules.java @@ -55,7 +55,6 @@ public static void initialize() { rules = LaplaceTransformRules.RULES; rules = LegendrePRules.RULES; rules = LegendreQRules.RULES; - rules = LerchPhiRules.RULES; rules = LimitRules.RULES; rules = LogRules.RULES; rules = MatrixDRules.RULES; diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/DerivativeRules.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/DerivativeRules.java index 4eaf501e24..1a60cfc2ca 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/DerivativeRules.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/DerivativeRules.java @@ -13,7 +13,7 @@ public class DerivativeRules { *
  • index 0 - number of equal rules in RULES
  • * */ - final public static int[] SIZES = { 132, 0 }; + final public static int[] SIZES = { 134, 0 }; final public static IAST RULES = List( IInit(Derivative, SIZES), @@ -439,6 +439,12 @@ public class DerivativeRules { Times(CN1D2,Log(C2Pi)), true), // Zeta'(-1)=1/12-Log(Glaisher) ISet($($(Derivative(C1),Zeta),CN1), - Subtract(QQ(1L,12L),Log(Glaisher)), true) + Subtract(QQ(1L,12L),Log(Glaisher)), true), + // Derivative(1,0,0)[LerchPhi]=(LerchPhi(1,-1+#2,#3)-LerchPhi(#1,#2,#3)*#3)/#1& + ISet($(Derivative(C1,C0,C0),LerchPhi), + Function(Times(Power(Slot1,CN1),Plus(LerchPhi(C1,Plus(CN1,Slot2),Slot(C3)),Times(CN1,LerchPhi(Slot1,Slot2,Slot(C3)),Slot(C3))))), true), + // Derivative(0,0,1)[LerchPhi]=-LerchPhi(#1,1+#2,#3)*#2& + ISet($(Derivative(C0,C0,C1),LerchPhi), + Function(Times(CN1,LerchPhi(Slot1,Plus(C1,Slot2),Slot(C3)),Slot2)), true) ); } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/FunctionExpandRules.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/FunctionExpandRules.java index c3b6139788..83eef826c2 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/FunctionExpandRules.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/FunctionExpandRules.java @@ -264,6 +264,9 @@ public class FunctionExpandRules { // PolyLog(2,1/2*(-1-Sqrt(5)))=(-1)*1/10*Pi^2-ArcCsch(2)^2 Set(PolyLog(C2,Times(C1D2,Subtract(CN1,CSqrt5))), Subtract(Times(QQ(-1L,10L),Sqr(Pi)),Sqr(ArcCsch(C2)))), + // PolyLog(2,1/2-I*1/2)=-I*Catalan+Pi^2/48-(I*1/4*Pi-Log(2)/2)^2/2 + Set(PolyLog(C2,CC(1L,2L,-1L,2L)), + Plus(Times(CNI,Catalan),Times(QQ(1L,48L),Sqr(Pi)),Times(CN1D2,Sqr(Plus(Times(CC(0L,1L,1L,4L),Pi),Times(CN1D2,Log(C2))))))), // Abs(x_)^y_Integer:=x^y/;EvenQ(y)&&x∈Reals SetDelayed(Power(Abs(x_),$p(y, Integer)), Condition(Power(x,y),And(EvenQ(y),Element(x,Reals)))), diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/LerchPhiRules.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/LerchPhiRules.java deleted file mode 100644 index 32301627b3..0000000000 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/LerchPhiRules.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.matheclipse.core.reflection.system.rules; - -import static org.matheclipse.core.expression.F.*; -import org.matheclipse.core.interfaces.IAST; - -/** - *

    Generated by org.matheclipse.core.preprocessor.RulePreprocessor.

    - *

    See GIT repository at: github.com/axkr/symja_android_library under the tools directory.

    - */ -public class LerchPhiRules { - /** - * - */ - final public static int[] SIZES = { 7, 0 }; - - final public static IAST RULES = List( - IInit(LerchPhi, SIZES), - // LerchPhi(-1,1,0)=-Log(2) - ISet(LerchPhi(CN1,C1,C0), - Negate(Log(C2)), true), - // LerchPhi(-1,2,1/2)=4*Catalan - ISet(LerchPhi(CN1,C2,C1D2), - Times(C4,Catalan), true), - // LerchPhi(0,1,0)=0 - ISet(LerchPhi(C0,C1,C0), - C0, true), - // LerchPhi(1,1,0)=Infinity - ISet(LerchPhi(C1,C1,C0), - oo, true), - // LerchPhi(1,2,1)=Pi^2/6 - ISet(LerchPhi(C1,C2,C1), - Times(QQ(1L,6L),Sqr(Pi)), true), - // LerchPhi(2,1,0)=-I*Pi - ISet(LerchPhi(C2,C1,C0), - Times(CNI,Pi), true), - // LerchPhi(1/2-I*1/2,2,1)=(1+I)*PolyLog(2,1/2-I/2) - ISet(LerchPhi(CC(1L,2L,-1L,2L),C2,C1), - Times(CC(1L,1L,1L,1L),PolyLog(C2,CC(1L,2L,-1L,2L))), true), - // LerchPhi(z_,s_,i_Integer):=Module({n=-i},z^n*(PolyLog(s,z)+Sum(1/(z^k*k^s),{k,1,n}))/;i<0) - ISetDelayed(LerchPhi(z_,s_,$p(i, Integer)), - Module(list(Set(n,Negate(i))),Condition(Times(Power(z,n),Plus(PolyLog(s,z),Sum(Power(Times(Power(z,k),Power(k,s)),CN1),list(k,C1,n)))),Less(i,C0)))), - // LerchPhi(z_,s_,n_Integer):=(PolyLog(s,z)-Sum(z^k/k^s,{k,1,-1+n}))/z^n/;n>0 - ISetDelayed(LerchPhi(z_,s_,$p(n, Integer)), - Condition(Times(Power(Power(z,n),CN1),Subtract(PolyLog(s,z),Sum(Times(Power(Power(k,s),CN1),Power(z,k)),list(k,C1,Plus(CN1,n))))),Greater(n,C0))) - ); -} diff --git a/symja_android_library/rules/DerivativeRules.m b/symja_android_library/rules/DerivativeRules.m index 3b92bf0915..777b11920a 100644 --- a/symja_android_library/rules/DerivativeRules.m +++ b/symja_android_library/rules/DerivativeRules.m @@ -167,6 +167,9 @@ Derivative(0,1)[StruveL] = (1/2)*(StruveL(#-1, #2) + StruveL(#+1, #2) + (#2/2)^#/(Sqrt(Pi)*Gamma(#+3/2))) &, Derivative(1)[Zeta][0] = (-1/2)*Log(2*Pi), -Derivative(1)[Zeta][-1] = 1/12-Log(Glaisher) +Derivative(1)[Zeta][-1] = 1/12-Log(Glaisher), + +Derivative(1,0,0)[LerchPhi] = (LerchPhi(1,-1+#2,#3)-LerchPhi(#,#2,#3)*#3)/# &, +Derivative(0,0,1)[LerchPhi] = (-LerchPhi(#, 1 + #2, #3))*#2 & } \ No newline at end of file diff --git a/symja_android_library/rules/FunctionExpandRules.m b/symja_android_library/rules/FunctionExpandRules.m index a892307a7c..d01669515d 100644 --- a/symja_android_library/rules/FunctionExpandRules.m +++ b/symja_android_library/rules/FunctionExpandRules.m @@ -124,7 +124,8 @@ PolyLog(2,(-1+Sqrt(5))/2) = Pi^2/10 - ArcCsch(2)^2, PolyLog(2,(1-Sqrt(5))/2) = -(Pi^2/10) + ArcCsch(2)^2 + (1/2)*(Pi^2/15 - ArcCsch(2)^2) , PolyLog(2,(-1-Sqrt(5))/2) = -(Pi^2/10) - ArcCsch(2)^2, - + PolyLog(2,Complex(1/2,-1/2)) = -I*Catalan+Pi^2/48-(I*1/4*Pi-Log(2)/2)^2/2, + Power(Abs(x_),y_Integer) := x^y /; EvenQ(y) && Element(x,Reals), Power(Abs(x_),y_Integer) := With({a=Quotient(y,2)},(Im(x)^2+Re(x)^2)^a) diff --git a/symja_android_library/rules/LerchPhiRules.m b/symja_android_library/rules/LerchPhiRules.m deleted file mode 100644 index aee3a364c6..0000000000 --- a/symja_android_library/rules/LerchPhiRules.m +++ /dev/null @@ -1,13 +0,0 @@ -{ - LerchPhi(-1, 1, 0) = -Log(2), - LerchPhi(-1, 2, 1/2) = 4*Catalan, - LerchPhi(0, 1, 0) = 0, - LerchPhi(1, 1, 0) = Infinity, - LerchPhi(1, 2, 1) = 1/6*Pi^2, - LerchPhi(2, 1, 0) = -I*Pi, - LerchPhi(1/2-1/2*I, 2, 1) = (1+I)*PolyLog(2,1/2-1/2*I), - LerchPhi(z_, s_, i_Integer) := Module({n=(-i)}, (z^n)*(PolyLog(s, z)+Sum(1/(z^k*k^s), {k, 1, n})) /; i<0 ), - LerchPhi(z_, s_, n_Integer) := (PolyLog(s,z)-Sum(z^k/k^s, {k, 1, n - 1}))/(z^n) /; n>0 - - -} \ No newline at end of file