Search in sources :

Example 1 with PartialFractionIntegrateGenerator

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);
    }
}
Also used : ISymbol(org.matheclipse.core.interfaces.ISymbol) PartialFractionIntegrateGenerator(org.matheclipse.core.polynomials.PartialFractionIntegrateGenerator) IExpr(org.matheclipse.core.interfaces.IExpr) IAST(org.matheclipse.core.interfaces.IAST) BinaryEval(org.matheclipse.core.generic.BinaryEval)

Aggregations

BinaryEval (org.matheclipse.core.generic.BinaryEval)1 IAST (org.matheclipse.core.interfaces.IAST)1 IExpr (org.matheclipse.core.interfaces.IExpr)1 ISymbol (org.matheclipse.core.interfaces.ISymbol)1 PartialFractionIntegrateGenerator (org.matheclipse.core.polynomials.PartialFractionIntegrateGenerator)1