use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class Product method evaluateProduct.
private IExpr evaluateProduct(final IAST preevaledProduct, IExpr arg1, EvalEngine engine) {
if (preevaledProduct.size() > 2) {
IAST list;
if (preevaledProduct.last().isList()) {
list = (IAST) preevaledProduct.last();
} else {
list = F.list(preevaledProduct.last());
}
if (list.isAST1()) {
// indefinite product case
IExpr variable = list.arg1();
if (preevaledProduct.arg1().isFree(variable) && variable.isVariable()) {
return indefiniteProduct(preevaledProduct, variable);
}
}
}
IExpr temp = F.NIL;
if (preevaledProduct.size() == 3) {
IExpr result = matcher1().apply(preevaledProduct);
if (result.isPresent()) {
return result;
}
}
try {
temp = evaluateTableThrow(preevaledProduct, Times(), Times(), engine);
if (temp.isPresent()) {
return temp;
}
} catch (final ValidateException ve) {
return IOFunctions.printMessage(S.Product, ve, engine);
}
if (arg1.isPower()) {
IExpr exponent = arg1.exponent();
boolean flag = true;
// Prod( i^a, {i,from,to},... )
for (int i = 2; i < preevaledProduct.size(); i++) {
IIterator<IExpr> iterator;
if (preevaledProduct.get(i).isList()) {
iterator = Iterator.create((IAST) preevaledProduct.get(i), i, engine);
} else {
iterator = Iterator.create(F.list(preevaledProduct.get(i)), i, engine);
}
if (iterator.isValidVariable() && exponent.isFree(iterator.getVariable())) {
continue;
}
flag = false;
break;
}
if (flag) {
IASTMutable prod = preevaledProduct.copy();
prod.set(1, arg1.base());
return F.Power(prod, exponent);
}
}
IExpr argN = preevaledProduct.last();
if (preevaledProduct.size() >= 3 && argN.isList()) {
try {
if (arg1.isZero()) {
// Product(0, {k, n, m})
return F.C0;
}
IIterator<IExpr> iterator = Iterator.create((IAST) argN, preevaledProduct.argSize(), engine);
if (iterator.isValidVariable() && iterator.getUpperLimit().isInfinity()) {
if (arg1.isOne()) {
// Product(1, {k, a, Infinity})
return F.C1;
}
if (arg1.isPositiveResult() && arg1.isIntegerResult()) {
// Product(n, {k, a, Infinity}) ;n is positive integer
return F.CInfinity;
}
}
if (iterator.isValidVariable() && !iterator.isNumericFunction()) {
if (iterator.getUpperLimit().isSymbol() && iterator.getStep().isOne()) {
final ISymbol var = iterator.getVariable();
final IExpr from = iterator.getLowerLimit();
final ISymbol to = (ISymbol) iterator.getUpperLimit();
if (arg1.isPower()) {
IExpr base = arg1.base();
if (base.isFree(var)) {
if (iterator.getLowerLimit().isOne()) {
IExpr exponent = arg1.exponent();
if (exponent.equals(var)) {
// Prod( a^i, ..., {i,from,to} )
if (preevaledProduct.isAST2()) {
return F.Power(base, Times(C1D2, to, Plus(C1, to)));
}
IASTAppendable result = preevaledProduct.removeAtClone(preevaledProduct.argSize());
// result.remove(ast.argSize());
result.set(1, F.Power(base, Times(C1D2, to, Plus(C1, to))));
return result;
}
}
}
}
if (arg1.isFree(var)) {
if (preevaledProduct.isAST2()) {
if (from.isOne()) {
return F.Power(preevaledProduct.arg1(), to);
}
if (from.isZero()) {
return F.Power(preevaledProduct.arg1(), Plus(to, C1));
}
if (from.isSymbol()) {
// 2^(1-from+to)
return F.Power(arg1, F.Plus(F.C1, from.negate(), to));
}
} else {
IASTAppendable result = preevaledProduct.removeAtClone(preevaledProduct.argSize());
// result.remove(ast.argSize());
if (from.isOne()) {
result.set(1, F.Power(preevaledProduct.arg1(), to));
return result;
}
if (from.isZero()) {
result.set(1, F.Power(preevaledProduct.arg1(), Plus(to, C1)));
return result;
}
if (from.isSymbol()) {
// 2^(1-from+to)
result.set(1, F.Power(arg1, F.Plus(F.C1, from.negate(), to)));
return result;
}
}
}
}
}
temp = F.NIL;
IAST resultList = Times();
temp = evaluateLast(preevaledProduct.arg1(), iterator, resultList, F.C1);
if (!temp.isPresent() || temp.equals(resultList)) {
return F.NIL;
}
} catch (final ValidateException ve) {
return IOFunctions.printMessage(S.Product, ve, engine);
} catch (RecursionLimitExceeded rle) {
// Recursion depth of `1` exceeded during evaluation of `2`.
int recursionLimit = engine.getRecursionLimit();
IOFunctions.printMessage(S.Product, "reclim2", F.list(recursionLimit < 0 ? F.CInfinity : F.ZZ(recursionLimit), preevaledProduct), engine);
return F.NIL;
}
if (preevaledProduct.isAST2()) {
return temp;
} else {
IASTAppendable result = preevaledProduct.removeAtClone(preevaledProduct.argSize());
result.set(1, temp);
return result;
}
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class Reduce method evaluate.
@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
IAST vars;
ISymbol domain = S.Reals;
if (ast.isAST2() || ast.isAST3()) {
if (ast.arg2().isList()) {
vars = (IAST) ast.arg2();
} else {
vars = F.list(ast.arg2());
}
} else {
VariablesSet eVar = new VariablesSet(ast.arg1());
vars = eVar.getVarList();
}
if (!vars.isList1()) {
// only univariate expressions allowed atm
return F.NIL;
}
if (ast.isAST3()) {
if (ast.arg3().isSymbol()) {
domain = (ISymbol) ast.arg3();
} else {
return F.NIL;
}
}
if (domain != S.Reals) {
return F.NIL;
}
try {
IExpr expr = ast.arg1();
if (ast.arg1().isList()) {
expr = ((IAST) expr).setAtCopy(0, S.And);
} else if (!expr.isBooleanFunction()) {
if (!expr.isComparatorFunction()) {
expr = F.And(expr);
}
}
IExpr variable = vars.get(1);
IExpr logicalExpand = S.LogicalExpand.of(engine, expr);
if (logicalExpand.isTrue() || logicalExpand.isFalse()) {
return logicalExpand;
}
if (!logicalExpand.isBooleanFunction()) {
logicalExpand = F.And(logicalExpand);
}
if (logicalExpand.isAST(S.And)) {
IAST andAST = (IAST) logicalExpand;
IASTMutable andResult = andAST.copy();
for (int i = 1; i < andAST.size(); i++) {
IExpr arg = andAST.get(i);
if (arg.isEqual()) {
IExpr roots = S.Roots.ofNIL(engine, arg, variable);
if (roots.isPresent()) {
andResult.set(i, roots);
}
}
}
logicalExpand = S.LogicalExpand.of(engine, andResult);
if (logicalExpand.isTrue() || logicalExpand.isFalse()) {
return logicalExpand;
}
}
ReduceComparison rc = new ReduceComparison(variable);
// may throw ArgumentTypeException
IExpr reduced = rc.evaluate(logicalExpand);
return reduced.orElse(logicalExpand);
} catch (RuntimeException rex) {
rex.printStackTrace();
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class FindInstance method evaluate.
/**
* Try to find at least one solution for a set of equations (i.e. <code>Equal[...]</code>
* expressions).
*/
@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
IAST vars = Validate.checkIsVariableOrVariableList(ast, 2, ast.topHead(), engine);
if (!vars.isPresent()) {
return F.NIL;
}
try {
boolean formula = false;
int maxChoices = 1;
if (ast.argSize() >= 4) {
maxChoices = ast.arg4().toIntDefault();
if (maxChoices < 0) {
maxChoices = 1;
}
} else if (ast.argSize() >= 3) {
maxChoices = ast.arg3().toIntDefault();
if (maxChoices < 0) {
maxChoices = 1;
}
}
try {
if (ast.arg1().isBooleanFormula()) {
formula = ast.arg1().isBooleanFormula();
if (ast.isAST2()) {
return BooleanFunctions.solveInstances(ast.arg1(), vars, maxChoices);
}
}
} catch (RuntimeException rex) {
}
if (ast.argSize() >= 3) {
if (ast.arg3().equals(S.Booleans) || formula) {
return BooleanFunctions.solveInstances(ast.arg1(), vars, maxChoices);
} else if (ast.arg3().equals(S.Integers)) {
return Solve.solveIntegers(ast, vars, vars, maxChoices, engine);
}
LOGGER.log(engine.getLogLevel(), "{}: Booleans domain expected at position 3 instead of {}", ast.topHead(), ast.arg3());
return F.NIL;
}
IASTMutable termsEqualZeroList = Validate.checkEquations(ast, 1);
return solveEquations(termsEqualZeroList, F.List(), vars, maxChoices, engine);
} catch (final ValidateException ve) {
return IOFunctions.printMessage(ast.topHead(), ve, engine);
} catch (RuntimeException rex) {
LOGGER.debug("FindInstance.evaluate() failed", rex);
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class AbstractFunctionEvaluator method getNormalizedNegativeExpression.
/**
* Check if the expression is canonical negative.
*
* @param expression
* @param checkTimesPlus check <code>Times(...)</code> and <code>Plus(...)</code> expressions
* @return the negated negative expression or <code>F.NIL</code> if a negative expression couldn't
* be extracted.
*/
public static IExpr getNormalizedNegativeExpression(final IExpr expression, boolean checkTimesPlus) {
IASTMutable result = F.NIL;
if (expression.isNumber()) {
if (((INumber) expression).complexSign() < 0) {
return ((INumber) expression).negate();
}
return F.NIL;
} else if (expression.isAST()) {
if (checkTimesPlus && expression.isTimes()) {
IAST timesAST = ((IAST) expression);
IExpr arg1 = timesAST.arg1();
// see github #110: checking for arg1.isNegative() will trigger infinite recursion!
if (arg1.isNumber()) {
if (((INumber) arg1).complexSign() < 0) {
IExpr negNum = ((INumber) arg1).negate();
if (negNum.isOne()) {
return timesAST.rest().oneIdentity1();
}
return timesAST.setAtCopy(1, negNum);
}
} else if (arg1.isNegativeInfinity()) {
return timesAST.setAtCopy(1, F.CInfinity);
}
} else if (checkTimesPlus && expression.isPlus()) {
IAST plusAST = ((IAST) expression);
IExpr arg1 = plusAST.arg1();
if (arg1.isNumber()) {
if (((INumber) arg1).complexSign() < 0) {
result = plusAST.copy();
result.set(1, arg1.negate());
for (int i = 2; i < plusAST.size(); i++) {
result.set(i, plusAST.get(i).negate());
}
return result;
}
} else if (arg1.isNegativeInfinity()) {
result = plusAST.copy();
result.set(1, F.CInfinity);
for (int i = 2; i < plusAST.size(); i++) {
result.set(i, plusAST.get(i).negate());
}
return result;
} else if (arg1.isTimes()) {
IExpr arg1Negated = getNormalizedNegativeExpression(arg1, checkTimesPlus);
if (arg1Negated.isPresent()) {
// int positiveElementsCounter = 0;
result = plusAST.copy();
result.set(1, arg1Negated);
for (int i = 2; i < plusAST.size(); i++) {
IExpr temp = plusAST.get(i);
// if (!temp.isTimes() && !temp.isPower()) {
// return F.NIL;
// }
// arg1Negated = getNormalizedNegativeExpression(temp, checkTimesPlus);
// if (arg1Negated.isPresent()) {
// result.set(i, arg1Negated);
// } else {
// positiveElementsCounter++;
// if (positiveElementsCounter * 2 > plusAST.argSize()) {
// number of positive elements is greater
// than number of negative elements
// return F.NIL;
// }
result.set(i, temp.negate());
// }
}
return result;
}
}
// } else if (expression.isNegativeInfinity()) {
// return F.CInfinity;
} else if (expression.isDirectedInfinity() && expression.isAST1()) {
IExpr arg1 = expression.first();
if (arg1.isMinusOne()) {
return F.CInfinity;
}
if (arg1.isNegativeImaginaryUnit()) {
return F.DirectedInfinity(F.CI);
}
}
}
// }
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class SolveUtils method filterSolveLists.
/**
* <code>result[0]</code> is the list of expressions <code>== 0</code> . <code>result[1]</code>are
* the <code>Unequal, Less, LessEqual, Greater, GreaterEqual</code> expressions. If <code>
* result[2].isPresent()</code> return the entry as solution.
*
* @param list
* @param solution
* @param isNumeric set isNumeric[0] = true, if an expression must be rationalized
* @return
*/
public static IASTMutable[] filterSolveLists(IAST list, IASTMutable solution, boolean[] isNumeric) {
// if numeric is true we use NSolve instead of SOlve
boolean numeric = isNumeric[0];
IASTMutable[] result = new IASTMutable[3];
IASTAppendable termsEqualZero = F.ListAlloc(list.size());
IASTAppendable inequalityTerms = F.ListAlloc(list.size());
result[0] = termsEqualZero;
result[1] = inequalityTerms;
result[2] = F.NIL;
int i = 1;
while (i < list.size()) {
IExpr arg = list.get(i);
if (arg.isTrue()) {
} else if (arg.isFalse()) {
// no solution possible
result[2] = F.ListAlloc();
return result;
} else if (arg.isEqual()) {
// arg must be Equal(_, 0)
IExpr arg1 = arg.first();
if (numeric) {
// NSolve
termsEqualZero.append(arg1);
} else {
// Solve
IExpr temp = NumberTheory.rationalize(arg1, false);
if (temp.isPresent()) {
isNumeric[0] = true;
termsEqualZero.append(temp);
} else {
termsEqualZero.append(arg1);
}
}
} else {
inequalityTerms.append(arg);
}
i++;
}
EvalAttributes.sort(result[0]);
EvalAttributes.sort(result[1]);
if (result[0].isEmpty() && result[1].isEmpty()) {
if (solution.isPresent()) {
result[2] = solution;
} else {
result[2] = F.unary(S.List, F.List());
}
return result;
}
return result;
}
Aggregations