use of org.matheclipse.core.polynomials.PartialFractionIntegrateGenerator 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);
}
}
Aggregations