Search in sources :

Example 1 with BinaryEval

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);
    }
}
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)

Example 2 with BinaryEval

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