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 f1f48ea4ca..83041b2dda 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
@@ -2120,12 +2120,55 @@ public void setUp(final ISymbol newSymbol) {
@Override
public IExpr e1ObjArg(final IExpr o) {
+ IExpr temp = functionExpandLogArg(o);
+ if (temp.isPresent()) {
+ return temp;
+ }
if (o.equals(F.C0) || o.equals(F.CD0)) {
return F.C0;
}
return F.NIL;
}
+ private static IExpr functionExpandLogArg(final IExpr o) {
+ if (o.isTimes() && o.first().isFraction() && o.argSize() == 3) {
+ // ProductLog(Rational(k_,n_)*b_^Rational(c_,n_)*Log(b_)) :=
+ // Module( {a, v},
+ // a = N( (n*ProductLog((b^(c/n)*k*Log(b))/n))/Log(b) );
+ // v = Rationalize(a);
+ // v*Log(b)/n
+ // /; IntegerQ(v) && v >= 1 && PossibleZeroQ( (((-b^(c/n))*k + b^(v/n)*v)*Log(b))/n ))
+ IAST times = (IAST) o;
+ if (times.arg2().isPower() && times.arg3().isLog()) {
+ IAST power = (IAST) times.arg2();
+ if (power.base().isInteger() && power.base().equals(times.arg3().first())
+ && power.exponent().isFraction()) {
+ IInteger b = (IInteger) times.arg3().first();
+ IFraction arg1 = (IFraction) times.arg1();
+ IInteger k = arg1.numerator();
+ IInteger n = arg1.denominator();
+ IFraction powExponent = (IFraction) power.exponent();
+ if (n.equals(powExponent.denominator())) {
+ EvalEngine engine = EvalEngine.get();
+ IExpr a = engine
+ .evalNumericFunction(F.Times(n, F.ProductLog(F.Times(arg1, F.Power(b, powExponent), F.Log(b))),
+ F.Power(F.Log(b), F.CN1)));
+ IExpr v = engine.evaluate(F.Rationalize(a));
+ if (v.isInteger() && ((IInteger) v).isGE(F.C1)) {
+ IFraction resultFactor = F.QQ((IInteger) v, n);
+ IExpr isZero = engine.evaluate(F.Plus(F.Times(k.negate(), F.Power(b, powExponent)),
+ F.Times(v, F.Power(b, resultFactor))));
+ if (isZero.isZero()) {
+ return engine.evaluate(F.Times(resultFactor, F.Log(b)));
+ }
+ }
+ }
+ }
+ }
+ }
+ return F.NIL;
+ }
+
@Override
public IExpr e2ObjArg(IExpr k, IExpr z) {
int ki = Integer.MIN_VALUE;
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/EvalEngine.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/EvalEngine.java
index a06c749eea..3701127c85 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/EvalEngine.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/EvalEngine.java
@@ -787,8 +787,8 @@ private IAST endTrace() {
*
* @param result0 store the result of the evaluation in the i-th argument of the ast in
* result0[0]
. result0[0]
should be F.NIL
if no evaluation
- * occured.
- * @param ast the original ast
for whixh the arguments should be evaluated
+ * occurred.
+ * @param ast the original ast
for which the arguments should be evaluated
* @param arg the i-th argument of ast
* @param i arg
is the i-th argument of ast
* @param isNumericFunction if true
the NumericFunction
attribute is set
@@ -1671,14 +1671,14 @@ public final int evalInt(final IExpr expr) throws ArgumentTypeException {
result = expr.toIntDefault();
}
if (expr.isNumericFunction(true)) {
- IExpr numericResult = evalN(expr);
+ IExpr numericResult = evalNumericFunction(expr);
if (numericResult.isReal()) {
result = numericResult.toIntDefault();
}
} else {
IExpr temp = evaluateNIL(expr);
if (temp.isNumericFunction(true)) {
- IExpr numericResult = evalN(temp);
+ IExpr numericResult = evalNumericFunction(temp);
if (numericResult.isReal()) {
result = numericResult.toIntDefault();
}
@@ -2093,6 +2093,26 @@ private void printOnOffTrace(IExpr unevaledExpr, IExpr evaledExpr) {
}
}
+ public final IExpr evalNumericFunction(final IExpr expr) {
+ if (expr.isNumericFunction(true)) {
+ final boolean oldNumericMode = isNumericMode();
+ final long oldDigitPrecision = getNumericPrecision();
+ final int oldSignificantFigures = getSignificantFigures();
+ try {
+ setNumericMode(true, oldDigitPrecision, oldSignificantFigures);
+ IExpr temp = evalWithoutNumericReset(expr);
+ if (temp.isListOrAssociation() || temp.isRuleAST()) {
+ return ((IAST) temp).mapThread(arg -> evalNumericFunction(arg));
+ }
+ return temp;
+ } finally {
+ setNumericMode(oldNumericMode);
+ setNumericPrecision(oldDigitPrecision);
+ }
+ }
+ return expr;
+ }
+
/**
* Evaluates expr
numerically.
*
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/ProductLogRules.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/ProductLogRules.java
index 514dcd0fda..1f06a56f6c 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/ProductLogRules.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/rules/ProductLogRules.java
@@ -13,7 +13,7 @@ public class ProductLogRules {
*
RULES