Search in sources :

Example 6 with ISymbol

use of org.matheclipse.core.interfaces.ISymbol in project symja_android_library by axkr.

the class EvalEngine method evalBlock.

/**
	 * Evaluate an expression for the given "local variables list". If evaluation is not possible return the
	 * input object.
	 * 
	 * @param expr
	 *            the expression which should be evaluated
	 * @param localVariablesList
	 *            a list of symbols which should be used as local variables inside the block
	 * @return the evaluated object
	 */
public IExpr evalBlock(final IExpr expr, final IAST localVariablesList) {
    final List<ISymbol> variables = new ArrayList<ISymbol>();
    try {
        // remember which local variables we use:
        ISymbol blockVariableSymbol;
        for (int i = 1; i < localVariablesList.size(); i++) {
            if (localVariablesList.get(i).isSymbol()) {
                blockVariableSymbol = (ISymbol) localVariablesList.get(i);
                blockVariableSymbol.pushLocalVariable();
                variables.add(blockVariableSymbol);
            } else {
                if (localVariablesList.get(i).isAST(F.Set, 3)) {
                    // lhs = rhs
                    final IAST setFun = (IAST) localVariablesList.get(i);
                    if (setFun.arg1().isSymbol()) {
                        blockVariableSymbol = (ISymbol) setFun.arg1();
                        blockVariableSymbol.pushLocalVariable();
                        // this evaluation step may throw an exception
                        IExpr temp = evaluate(setFun.arg2());
                        blockVariableSymbol.set(temp);
                        variables.add(blockVariableSymbol);
                    }
                } else {
                    return expr;
                }
            }
        }
        return evaluate(expr);
    } finally {
        // pop all local variables from local variable stack
        for (int i = 0; i < variables.size(); i++) {
            variables.get(i).popLocalVariable();
        }
    }
}
Also used : ISymbol(org.matheclipse.core.interfaces.ISymbol) ArrayList(java.util.ArrayList) IAST(org.matheclipse.core.interfaces.IAST) IExpr(org.matheclipse.core.interfaces.IExpr)

Example 7 with ISymbol

use of org.matheclipse.core.interfaces.ISymbol in project symja_android_library by axkr.

the class EvalEngine method evalAST.

/**
	 * Evaluate an AST. The evaluation steps are controlled by the header attributes.
	 * 
	 * @param ast
	 * @return <code>F.NIL</code> if no evaluation happened
	 */
public IExpr evalAST(IAST ast) {
    final IExpr head = ast.head();
    if (ast.head().isCoreFunctionSymbol()) {
        // evaluate a core function (without no rule definitions)
        final ICoreFunctionEvaluator coreFunction = (ICoreFunctionEvaluator) ((IBuiltInSymbol) head).getEvaluator();
        return fNumericMode ? coreFunction.numericEval(ast, this) : coreFunction.evaluate(ast, this);
    }
    final ISymbol symbol = ast.topHead();
    IExpr result = evalAttributes(symbol, ast);
    if (result.isPresent()) {
        return result;
    }
    // System.out.println(ast.toString());
    return evalRules(symbol, ast);
}
Also used : ISymbol(org.matheclipse.core.interfaces.ISymbol) IExpr(org.matheclipse.core.interfaces.IExpr) ICoreFunctionEvaluator(org.matheclipse.core.eval.interfaces.ICoreFunctionEvaluator)

Example 8 with ISymbol

use of org.matheclipse.core.interfaces.ISymbol 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 9 with ISymbol

use of org.matheclipse.core.interfaces.ISymbol in project symja_android_library by axkr.

the class Integrate method integrateTimesTrigFunctions.

/**
	 * Try using the <code>TrigReduce</code> function to get a
	 * <code>Plus(...)</code> expression which could be integrated.
	 * 
	 * @param timesAST
	 *            an IAST which is a <code>Times(...)</code> expression
	 * @param arg2
	 *            the symbol to get the indefinite integral for.
	 * @return <code>F.NIL</code> if no trigonometric funtion could be found.
	 */
private IExpr integrateTimesTrigFunctions(final IAST timesAST, ISymbol arg2) {
    Predicate<IExpr> isTrigFunction = Predicates.isAST(new ISymbol[] { F.Cos, F.Sin });
    if (timesAST.isMember(isTrigFunction, false)) {
        // use a symbol which is not in the symbols map
        ISymbol pSymbol = new Symbol("$x$");
        IExpr fx = F.eval(F.TrigReduce(timesAST));
        if (fx.isPlus()) {
            // Collect arguments for x
            // Sin(f_) -> Sin(Collect(f, arg2))
            fx = F.eval(F.ReplaceAll(fx, F.List(F.Rule(F.Sin(F.$p(pSymbol)), F.Sin(F.Collect(pSymbol, arg2))), F.Rule(F.Cos(F.$p(pSymbol)), F.Cos(F.Collect(pSymbol, arg2))))));
            // Integrate[a_+b_+...,x_] -> Integrate[a,x]+Integrate[b,x]+...
            return ((IAST) fx).mapThread(F.Integrate(null, arg2), 1);
        }
    }
    return F.NIL;
}
Also used : ISymbol(org.matheclipse.core.interfaces.ISymbol) Symbol(org.matheclipse.core.expression.Symbol) ISymbol(org.matheclipse.core.interfaces.ISymbol) IExpr(org.matheclipse.core.interfaces.IExpr) IAST(org.matheclipse.core.interfaces.IAST)

Example 10 with ISymbol

use of org.matheclipse.core.interfaces.ISymbol in project symja_android_library by axkr.

the class Limit method timesLimit.

private static IExpr timesLimit(final IAST timesAST, LimitData data) {
    IAST isFreeResult = timesAST.partitionTimes(Predicates.isFree(data.getSymbol()), F.C1, F.C1, F.List);
    if (!isFreeResult.get(1).isOne()) {
        return F.Times(isFreeResult.get(1), data.limit(isFreeResult.get(2)));
    }
    IExpr[] parts = Algebra.fractionalPartsTimesPower(timesAST, false, false, true, true);
    if (parts != null) {
        IExpr numerator = parts[0];
        IExpr denominator = parts[1];
        IExpr limit = data.getLimitValue();
        ISymbol symbol = data.getSymbol();
        if (limit.isInfinity() || limit.isNegativeInfinity()) {
            try {
                ExprPolynomialRing ring = new ExprPolynomialRing(symbol);
                ExprPolynomial denominatorPoly = ring.create(denominator);
                ExprPolynomial numeratorPoly = ring.create(numerator);
                return limitsInfinityOfRationalFunctions(numeratorPoly, denominatorPoly, symbol, limit, data);
            } catch (RuntimeException e) {
                if (Config.DEBUG) {
                    e.printStackTrace();
                }
            }
        }
        IExpr plusResult = Algebra.partialFractionDecompositionRational(new PartialFractionGenerator(), parts, symbol);
        if (plusResult.isPlus()) {
            // if (plusResult.size() > 2) {
            return data.mapLimit((IAST) plusResult);
        // }
        }
        if (denominator.isOne()) {
            if (limit.isInfinity() || limit.isNegativeInfinity()) {
                IExpr temp = substituteInfinity(timesAST, data);
                if (temp.isPresent()) {
                    return temp;
                }
            }
        }
        IExpr temp = numeratorDenominatorLimit(numerator, denominator, data);
        if (temp.isPresent()) {
            return temp;
        }
    }
    return data.mapLimit(timesAST);
}
Also used : ExprPolynomialRing(org.matheclipse.core.polynomials.ExprPolynomialRing) ISymbol(org.matheclipse.core.interfaces.ISymbol) IAST(org.matheclipse.core.interfaces.IAST) IExpr(org.matheclipse.core.interfaces.IExpr) ExprPolynomial(org.matheclipse.core.polynomials.ExprPolynomial) PartialFractionGenerator(org.matheclipse.core.polynomials.PartialFractionGenerator)

Aggregations

ISymbol (org.matheclipse.core.interfaces.ISymbol)117 IExpr (org.matheclipse.core.interfaces.IExpr)79 IAST (org.matheclipse.core.interfaces.IAST)76 IInteger (org.matheclipse.core.interfaces.IInteger)18 WrongArgumentType (org.matheclipse.core.eval.exception.WrongArgumentType)12 INum (org.matheclipse.core.interfaces.INum)10 ISignedNumber (org.matheclipse.core.interfaces.ISignedNumber)10 IFraction (org.matheclipse.core.interfaces.IFraction)9 IBuiltInSymbol (org.matheclipse.core.interfaces.IBuiltInSymbol)8 IComplex (org.matheclipse.core.interfaces.IComplex)7 IComplexNum (org.matheclipse.core.interfaces.IComplexNum)7 ArrayList (java.util.ArrayList)6 IPatternObject (org.matheclipse.core.interfaces.IPatternObject)6 HashSet (java.util.HashSet)5 EvalEngine (org.matheclipse.core.eval.EvalEngine)5 Num (org.matheclipse.core.expression.Num)5 GenPolynomial (edu.jas.poly.GenPolynomial)4 Options (org.matheclipse.core.eval.util.Options)4 ExprPolynomialRing (org.matheclipse.core.polynomials.ExprPolynomialRing)4 ExpVector (edu.jas.poly.ExpVector)3