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