use of org.matheclipse.core.generic.BinaryEval in project symja_android_library by axkr.
the class Integrate method evaluate.
@Override
public IExpr evaluate(final IAST holdallAST, EvalEngine engine) {
boolean calledRubi = false;
boolean evaled = false;
IExpr result;
boolean numericMode = engine.isNumericMode();
try {
engine.setNumericMode(false);
if (holdallAST.size() < 3) {
return F.NIL;
}
IExpr arg1 = engine.evaluateNull(holdallAST.arg1());
if (arg1.isPresent()) {
evaled = true;
} else {
arg1 = holdallAST.arg1();
}
if (arg1.isIndeterminate()) {
return F.Indeterminate;
}
if (holdallAST.size() > 3) {
// Integrate[fxy, y], x] ...
return holdallAST.range(2).foldRight(new BinaryEval(F.Integrate, engine), arg1);
}
IExpr arg2 = engine.evaluateNull(holdallAST.arg2());
if (arg2.isPresent()) {
evaled = true;
} else {
arg2 = holdallAST.arg2();
}
if (arg2.isList()) {
IAST xList = (IAST) arg2;
if (xList.isVector() == 3) {
// Integrate[f[x], {x,a,b}]
IAST clone = holdallAST.setAtClone(2, xList.arg1());
IExpr temp = engine.evaluate(clone);
if (temp.isFreeAST(F.Integrate)) {
// F(b)-F(a)
IExpr Fb = engine.evaluate(F.subst(temp, F.Rule(xList.arg1(), xList.arg3())));
IExpr Fa = engine.evaluate(F.subst(temp, F.Rule(xList.arg1(), xList.arg2())));
if (!Fb.isFree(F.DirectedInfinity, true) || !Fb.isFree(F.Indeterminate, true)) {
engine.printMessage("Not integrable: " + temp + " for " + xList.arg1() + " = " + xList.arg3());
return F.NIL;
}
if (!Fa.isFree(F.DirectedInfinity, true) || !Fa.isFree(F.Indeterminate, true)) {
engine.printMessage("Not integrable: " + temp + " for " + xList.arg1() + " = " + xList.arg2());
return F.NIL;
}
return F.Subtract(Fb, Fa);
}
}
}
final IAST ast = holdallAST.setAtClone(1, arg1);
ast.set(2, arg2);
if (ast.arg2().isSymbol()) {
final ISymbol x = (ISymbol) ast.arg2();
if (arg1.isNumber()) {
// Integrate[x_NumberQ,y_Symbol] -> x*y
return Times(arg1, x);
}
if (arg1.isFree(x, true)) {
// Integrate[x_,y_Symbol] -> x*y /; FreeQ[x,y]
return Times(arg1, x);
}
if (arg1.equals(x)) {
// Integrate[x_,x_Symbol] -> x^2 / 2
return Times(F.C1D2, Power(arg1, F.C2));
}
boolean showSteps = false;
if (showSteps) {
System.out.println("\nINTEGRATE: " + arg1.toString());
if (DEBUG_EXPR.contains(arg1)) {
// System.exit(-1);
}
DEBUG_EXPR.add(arg1);
}
if (arg1.isAST()) {
IAST fx = (IAST) arg1;
if (fx.topHead().equals(x)) {
// issue #91
return F.NIL;
}
if (fx.isPower()) {
if (fx.equalsAt(1, x) && fx.isFreeAt(2, x)) {
if (fx.arg2().isMinusOne()) {
// Integrate[ 1 / x_ , x_ ] -> Log[x]
return Log(x);
}
// Integrate[ x_ ^n_ , x_ ] -> x^(n+1)/(n+1) /;
// FreeQ[n, x]
IExpr temp = Plus(F.C1, fx.arg2());
return Divide(Power(x, temp), temp);
}
if (fx.equalsAt(2, x) && fx.isFreeAt(1, x)) {
if (fx.arg1().isE()) {
// E^x
return arg1;
}
// a^x / Log(a)
return F.Divide(fx, F.Log(fx.arg1()));
}
}
if (INT_FUNCTIONS.contains(fx.head())) {
if (fx.isAST1() && x.equals(fx.arg1())) {
IExpr head = fx.head();
IExpr temp = integrate1ArgumentFunctions(head, x);
if (temp.isPresent()) {
return temp;
}
}
result = integrateByRubiRules(ast);
if (result.isPresent()) {
return result;
}
}
IExpr fxExpanded = F.expand(fx, true, false);
if (fxExpanded.isAST()) {
if (fxExpanded.isPlus()) {
if (fxExpanded != fx) {
if (fxExpanded.isPolynomial(x)) {
if (arg1.isTimes()) {
result = integrateByRubiRules(ast);
if (result.isPresent()) {
return result;
}
}
}
}
// Integrate[a,x]+Integrate[b,x]+...
return ((IAST) fxExpanded).mapThread(F.Integrate(null, x), 1);
}
final IAST arg1AST = (IAST) fxExpanded;
if (arg1AST.isAST1() && x.equals(arg1AST.arg1())) {
IExpr head = arg1AST.head();
IExpr temp = integrate1ArgumentFunctions(head, x);
if (temp.isPresent()) {
return temp;
}
}
if (arg1AST.isTimes()) {
// Integrate[a_*y_,x_Symbol] -> a*Integrate[y,x] /;
// FreeQ[a,x]
IAST filterCollector = F.Times();
IAST restCollector = F.Times();
arg1AST.filter(filterCollector, restCollector, new Predicate<IExpr>() {
@Override
public boolean test(IExpr input) {
return input.isFree(x, true);
}
});
if (filterCollector.size() > 1) {
if (restCollector.size() > 1) {
filterCollector.append(F.Integrate(restCollector.getOneIdentity(F.C0), x));
}
return filterCollector;
}
IExpr temp = integrateTimesTrigFunctions(arg1AST, x);
if (temp.isPresent()) {
return temp;
}
}
if (!ast.equalsAt(1, fxExpanded)) {
return integrateByRubiRules(ast);
}
final IExpr header = arg1AST.head();
if (arg1AST.size() >= 3) {
if (header == F.Times || header == F.Power) {
if (!arg1AST.isEvalFlagOn(IAST.IS_DECOMPOSED_PARTIAL_FRACTION) && ast.arg2().isSymbol()) {
IExpr[] parts = Algebra.fractionalParts(arg1, true);
if (parts != null) {
// try Rubi rules first
if (!parts[0].isPolynomial(x) || !parts[1].isPolynomial(x)) {
result = integrateByRubiRules(ast);
if (result.isPresent()) {
return result;
}
calledRubi = true;
}
IExpr apartPlus = Algebra.partialFractionDecompositionRational(new PartialFractionIntegrateGenerator(x), parts, x);
if (apartPlus.isPresent() && !apartPlus.isAST(F.Integrate)) {
if (ast.equals(apartPlus)) {
return returnIntegrate(ast, evaled);
}
return apartPlus;
}
if (parts[0].isPolynomial(x) && parts[1].isPolynomial(x)) {
result = integrateByRubiRules(ast);
if (result.isPresent()) {
return result;
}
calledRubi = true;
}
if (arg1AST.isTimes()) {
result = integratePolynomialByParts(ast, arg1AST, x);
if (result.isPresent()) {
return result;
}
}
}
}
}
}
}
// engine.setIterationLimit(8);
if (!calledRubi) {
return integrateByRubiRules(ast);
}
}
} else {
IExpr fx = engine.evaluate(F.Expand(ast.arg1()));
if (fx.isPlus()) {
// Integrate[a,x]+Integrate[b,x]+...
return ((IAST) fx).mapThread(F.Integrate(null, ast.arg2()), 1);
}
}
return returnIntegrate(ast, evaled);
} finally {
engine.setNumericMode(numericMode);
}
}
use of org.matheclipse.core.generic.BinaryEval in project symja_android_library by axkr.
the class D method evaluate.
@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
if (ast.size() < 3) {
return F.NIL;
}
IExpr fx = ast.arg1();
if (fx.isIndeterminate()) {
return F.Indeterminate;
}
if (ast.size() > 3) {
// reduce arguments by folding D[fxy, x, y] to D[ D[fxy, x], y] ...
return ast.range(2).foldLeft(new BinaryEval(F.D, engine), fx);
}
if (fx.isList()) {
// thread over first list
return ((IAST) fx).mapThread(F.List(), ast, 1);
}
IExpr x = ast.arg2();
if (x.isList()) {
// D[fx_, {...}]
IAST xList = (IAST) x;
if (xList.isAST1() && xList.arg1().isListOfLists()) {
IAST subList = (IAST) xList.arg1();
IAST result = F.ListAlloc(subList.size());
for (int i = 1; i < subList.size(); i++) {
result.append(F.D(fx, F.List(subList.get(i))));
}
return result;
} else if (xList.isAST1() && xList.arg1().isList()) {
IAST subList = (IAST) xList.arg1();
return subList.args().mapLeft(F.List(), new BinaryEval(F.D, engine), fx);
} else if (xList.isAST2() && xList.arg2().isInteger()) {
if (ast.isEvalFlagOn(IAST.IS_DERIVATIVE_EVALED)) {
return F.NIL;
}
int n = Validate.checkIntType(xList, 2, 1);
if (n >= 0) {
if (xList.arg1().isList()) {
x = F.List(xList.arg1());
} else {
x = xList.arg1();
}
for (int i = 0; i < n; i++) {
fx = engine.evaluate(F.D(fx, x));
}
return fx;
}
}
return F.NIL;
}
if (!(x.isList()) && fx.isFree(x, true)) {
return F.C0;
}
if (fx.isNumber()) {
// D[x_NumberQ,y_] -> 0
return F.C0;
}
if (fx.equals(x)) {
// D[x_,x_] -> 1
return F.C1;
}
if (fx.isAST()) {
final IAST listArg1 = (IAST) fx;
final IExpr header = listArg1.head();
if (listArg1.isPlus()) {
// D[a_+b_+c_,x_] -> D[a,x]+D[b,x]+D[c,x]
return listArg1.mapThread(F.D(F.Null, x), 1);
} else if (listArg1.isTimes()) {
return listArg1.args().map(F.Plus(), new BinaryBindIth1st(listArg1, F.D(F.Null, x)));
} else if (listArg1.isPower()) {
// && !listArg1.isFreeAt(1, x) && !listArg1.isFreeAt(2, x)) {
final IExpr f = listArg1.arg1();
final IExpr g = listArg1.arg2();
final IExpr y = ast.arg2();
if (listArg1.isFreeAt(2, x)) {
// g*D(f,y)*f^(g-1)
return F.Times(g, F.D(f, y), F.Power(f, g.dec()));
}
if (listArg1.isFreeAt(1, x)) {
// D(g,y)*Log(f)*f^g
return F.Times(F.D(g, y), F.Log(f), F.Power(f, g));
}
// D[f_^g_,y_]:= f^g*(((g*D[f,y])/f)+Log[f]*D[g,y])
final IAST resultList = F.Times();
resultList.append(F.Power(f, g));
resultList.append(F.Plus(F.Times(g, F.D(f, y), F.Power(f, F.CN1)), F.Times(F.Log(f), F.D(g, y))));
return resultList;
} else if ((header == F.Log) && (listArg1.isAST2())) {
if (listArg1.isFreeAt(1, x)) {
// D[Log[i_FreeQ(x), x_], z_]:= (x*Log[a])^(-1)*D[x,z];
return F.Times(F.Power(F.Times(listArg1.arg2(), F.Log(listArg1.arg1())), F.CN1), F.D(listArg1.arg2(), x));
}
// } else if (header == F.LaplaceTransform && (listArg1.size()
// == 4)) {
// if (listArg1.arg3().equals(x) && listArg1.arg1().isFree(x,
// true)) {
// // D(LaplaceTransform(c,t,s), s) -> -c / s^2
// return F.Times(-1L, listArg1.arg2(), F.Power(x, -2L));
// } else if (listArg1.arg1().equals(x)) {
// // D(LaplaceTransform(c,t,s), c) -> 1/s
// return F.Power(x, -1L);
// } else if (listArg1.arg1().isFree(x, true) &&
// listArg1.arg2().isFree(x, true) && listArg1.arg3().isFree(x,
// true))
// {
// // D(LaplaceTransform(c,t,s), w) -> 0
// return F.C0;
// } else if (listArg1.arg2().equals(x)) {
// // D(LaplaceTransform(c,t,s), t) -> 0
// return F.C0;
// }
} else if (listArg1.isAST1() && ast.isEvalFlagOff(IAST.IS_DERIVATIVE_EVALED)) {
IAST[] derivStruct = listArg1.isDerivativeAST1();
if (derivStruct != null && derivStruct[2] != null) {
IAST headAST = derivStruct[1];
IAST a1Head = derivStruct[0];
if (a1Head.isAST1() && a1Head.arg1().isInteger()) {
try {
int n = ((IInteger) a1Head.arg1()).toInt();
IExpr arg1 = listArg1.arg1();
if (n > 0) {
IAST fDerivParam = Derivative.createDerivative(n + 1, headAST.arg1(), arg1);
if (x.equals(arg1)) {
return fDerivParam;
}
return F.Times(F.D(arg1, x), fDerivParam);
}
} catch (ArithmeticException ae) {
}
}
return F.NIL;
}
return getDerivativeArg1(x, listArg1.arg1(), header, engine);
// } else if (listArg1.isAST2()) {
// return getDerivativeArg2(x, listArg1.arg1(), listArg1.arg2(), header);
} else if (listArg1.isAST() && ast.isEvalFlagOff(IAST.IS_DERIVATIVE_EVALED)) {
return getDerivativeArgN(x, listArg1, header);
}
}
return F.NIL;
}
Aggregations