use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class ASTRealVector method setAtCopy.
@Override
public IASTMutable setAtCopy(int i, IExpr expr) {
if (expr instanceof Num) {
IASTMutable ast = copy();
ast.set(i, expr);
return ast;
}
IASTAppendable ast = copyAppendable();
ast.set(i, expr);
return ast;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class EvalEngine method threadASTListArgs.
/**
* Thread through all lists in the arguments of the IAST (i.e. the ast's head has the attribute
* <code>ISymbol.LISTABLE</code>) example: <code>Sin[{2,x,Pi}] ==> {Sin[2],Sin[x],Sin[Pi]}</code>
*
* @param ast
* @param commandHead TODO
* @param messageShortcut TODO
* @return the resulting ast with the <code>argHead</code> threaded into each ast argument or
* <code>F.NIL</code>
*/
public IASTMutable threadASTListArgs(final IAST ast, ISymbol commandHead, String messageShortcut) {
ISymbol[] head = new ISymbol[] { null };
int[] listLength = new int[] { -1 };
if (ast.exists(x -> {
if (x.isList()) {
if (head[0] == null) {
head[0] = S.List;
}
if (listLength[0] < 0) {
listLength[0] = ((IAST) x).argSize();
} else {
if (listLength[0] != ((IAST) x).argSize()) {
// tdlen: Objects of unequal length in `1` cannot be combined.
IOFunctions.printMessage(commandHead, messageShortcut, F.list(ast), EvalEngine.get());
// ast.addEvalFlags(IAST.IS_LISTABLE_THREADED);
return true;
}
}
} else if (x.isSparseArray()) {
if (head[0] == null) {
head[0] = S.SparseArray;
}
ISparseArray sp = (ISparseArray) x;
int[] dimensions = sp.getDimension();
if (dimensions.length > 0) {
if (listLength[0] < 0) {
listLength[0] = dimensions[0];
} else {
if (listLength[0] != dimensions[0]) {
// Objects of unequal length in `1` cannot be combined.
IOFunctions.printMessage(S.Thread, "tdlen", F.list(ast), EvalEngine.get());
// ast.addEvalFlags(IAST.IS_LISTABLE_THREADED);
return true;
}
}
}
}
return false;
})) {
return F.NIL;
}
if (listLength[0] != -1) {
IASTMutable result = EvalAttributes.threadList(ast, head[0], ast.head(), listLength[0]);
result.addEvalFlags(IAST.IS_LISTABLE_THREADED);
return result;
}
ast.addEvalFlags(IAST.IS_LISTABLE_THREADED);
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class EvalEngine method evalArgs.
/**
* Evaluate the arguments of the given ast, taking the attributes <code>
* HoldFirst, NHoldFirst, HoldRest, NHoldRest, NumericFunction</code> into account.
*
* @param ast
* @param attributes
* @return <code>F.NIL</code> is no evaluation was possible
*/
public IASTMutable evalArgs(final IAST ast, final int attributes) {
final int astSize = ast.size();
if (astSize > 1) {
boolean numericMode = fNumericMode;
boolean localNumericMode = fNumericMode;
final boolean isNumericFunction = (ISymbol.NUMERICFUNCTION & attributes) == ISymbol.NUMERICFUNCTION;
boolean isNumericArgument = ast.isNumericArgument();
if (!fNumericMode) {
if (isNumericFunction && isNumericArgument) {
localNumericMode = true;
}
}
IASTMutable[] rlist = new IASTMutable[1];
rlist[0] = F.NIL;
IExpr x = ast.arg1();
if ((ISymbol.HOLDFIRST & attributes) == ISymbol.NOATTRIBUTE) {
// the HoldFirst attribute is disabled
try {
if (!x.isAST(S.Unevaluated)) {
selectNumericMode(attributes, ISymbol.NHOLDFIRST, localNumericMode);
evalArg(rlist, ast, x, 1, isNumericFunction);
if (astSize == 2 && rlist[0].isPresent()) {
return rlist[0];
}
}
} finally {
if ((ISymbol.NHOLDFIRST & attributes) == ISymbol.NHOLDFIRST) {
fNumericMode = numericMode;
}
}
} else {
// the HoldFirst attribute is set here
if (!ast.isHoldAllCompleteAST()) {
try {
if (x.isAST(S.Evaluate)) {
selectNumericMode(attributes, ISymbol.NHOLDFIRST, localNumericMode);
evalArg(rlist, ast, x, 1, isNumericFunction);
if (astSize == 2 && rlist[0].isPresent()) {
return rlist[0];
}
}
} finally {
if ((ISymbol.NHOLDFIRST & attributes) == ISymbol.NHOLDFIRST) {
fNumericMode = numericMode;
}
}
}
}
if (astSize > 2) {
if ((ISymbol.HOLDREST & attributes) == ISymbol.NOATTRIBUTE) {
// the HoldRest attribute is disabled
numericMode = fNumericMode;
try {
selectNumericMode(attributes, ISymbol.NHOLDREST, localNumericMode);
ast.forEach(2, astSize, (arg, i) -> {
if (!arg.isUnevaluated()) {
evalArg(rlist, ast, arg, i, isNumericFunction);
}
});
} finally {
if ((ISymbol.NHOLDREST & attributes) == ISymbol.NHOLDREST) {
fNumericMode = numericMode;
}
}
} else {
// the HoldRest attribute is set here
if (!ast.isHoldAllCompleteAST()) {
numericMode = fNumericMode;
try {
selectNumericMode(attributes, ISymbol.NHOLDREST, localNumericMode);
ast.forEach(2, astSize, (arg, i) -> {
if (arg.isAST(S.Evaluate)) {
evalArg(rlist, ast, arg, i, isNumericFunction);
}
});
} finally {
if ((ISymbol.NHOLDREST & attributes) == ISymbol.NHOLDREST) {
fNumericMode = numericMode;
}
}
}
}
}
if (!isNumericArgument && ast.isNumericArgument()) {
// one of the arguments is a numeric value
if (!rlist[0].isPresent()) {
return evalArgs(ast, attributes);
}
}
return rlist[0];
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class EvalEngine method evalSetAttributesRecursive.
private IExpr evalSetAttributesRecursive(IAST ast, boolean noEvaluation, boolean evalNumericFunction, int level) {
// final ISymbol symbol = ast.topHead();
IExpr head = ast.head();
if (!(head instanceof IPatternObject) && !noEvaluation) {
IExpr headResult = head.evaluate(this);
if (headResult.isPresent()) {
ast = ast.apply(headResult);
head = headResult;
}
}
ISymbol symbol = head.topHead();
if (head.isSymbol()) {
symbol = (ISymbol) head;
}
if (symbol.isBuiltInSymbol()) {
// call so that attributes may be set in
// AbstractFunctionEvaluator#setUp() method
((IBuiltInSymbol) symbol).getEvaluator();
}
int headID = ast.headID();
if (headID >= 0) {
if (headID == ID.Blank || headID == ID.BlankSequence || headID == ID.BlankNullSequence || headID == ID.Pattern || headID == ID.Optional || headID == ID.OptionsPattern || headID == ID.Repeated || headID == ID.RepeatedNull) {
return ((IFunctionEvaluator) ((IBuiltInSymbol) ast.head()).getEvaluator()).evaluate(ast, this);
}
}
final int attributes = symbol.getAttributes();
IASTMutable resultList = F.NIL;
if ((ISymbol.HOLDALL & attributes) != ISymbol.HOLDALL) {
final int astSize = ast.size();
if ((ISymbol.HOLDFIRST & attributes) == ISymbol.NOATTRIBUTE) {
// the HoldFirst attribute isn't set here
if (astSize > 1) {
IExpr expr = ast.arg1();
if (expr.isAST()) {
resultList = evalSetAttributeArg(ast, 1, (IAST) expr, resultList, noEvaluation, level);
} else if (!(expr instanceof IPatternObject) && !noEvaluation) {
IExpr temp = expr.evaluate(this);
if (temp.isPresent()) {
resultList = ast.setAtCopy(1, temp);
}
}
}
}
if (astSize > 2) {
if ((ISymbol.HOLDREST & attributes) == ISymbol.NOATTRIBUTE) {
// the HoldRest attribute isn't set here
for (int i = 2; i < astSize; i++) {
IExpr expr = ast.get(i);
if (expr.isAST()) {
resultList = evalSetAttributeArg(ast, i, (IAST) expr, resultList, noEvaluation, level);
} else if (!(expr instanceof IPatternObject) && !noEvaluation) {
IExpr temp = expr.evaluate(this);
if (temp.isPresent()) {
if (resultList.isPresent()) {
resultList.set(i, temp);
} else {
resultList = ast.setAtCopy(i, temp);
}
}
}
}
}
}
if (evalNumericFunction && ((ISymbol.HOLDALL & attributes) == ISymbol.NOATTRIBUTE)) {
IAST f = resultList.orElse(ast);
if (f.isNumericFunction(true)) {
IExpr temp = evalLoop(f);
if (temp.isPresent()) {
return temp;
}
}
}
}
if (resultList.isPresent()) {
if (resultList.size() > 2) {
if (ISymbol.hasFlatAttribute(attributes)) {
// associative
IASTAppendable result;
if ((result = EvalAttributes.flattenDeep(resultList)).isPresent()) {
return evalSetOrderless(result, attributes, noEvaluation, level);
}
}
IExpr expr = evalSetOrderless(resultList, attributes, noEvaluation, level);
if (expr.isPresent()) {
return expr;
}
}
return resultList;
}
if ((ast.getEvalFlags() & IAST.IS_FLATTENED_OR_SORTED_MASK) != 0x0000) {
// already flattened or sorted
return ast;
}
if (ISymbol.hasFlatAttribute(attributes)) {
// associative
IASTAppendable result;
if ((result = EvalAttributes.flattenDeep(ast)).isPresent()) {
return evalSetOrderless(result, attributes, noEvaluation, level);
}
}
return evalSetOrderless(ast, attributes, noEvaluation, level);
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class AbstractFunctionEvaluator method getPeriodicParts.
/**
* Try to split a periodic part from the expression: <code>
* expr == part.arg1() + part.arg2() * period</code>
*
* @param expr
* @param period
* @return <code>F.NIL</code> if no periodicity was found or the rest at argument 1 and the factor
* of the period at argument 2
*/
public static IAST getPeriodicParts(final IExpr expr, final IExpr period) {
// IExpr[] result = new IExpr[2];
// result[0] = F.C0;
// result[1] = F.C1;
IASTMutable result = F.binaryAST2(S.List, F.C0, F.C1);
if (expr.equals(period)) {
return result;
}
if (expr.isAST()) {
IAST ast = (IAST) expr;
if (ast.isTimes()) {
for (int i = 1; i < ast.size(); i++) {
if (ast.get(i).equals(period)) {
result.set(2, ast.splice(i).oneIdentity1());
return result;
}
}
return F.NIL;
}
if (ast.isPlus()) {
for (int i = 1; i < ast.size(); i++) {
IAST temp = getPeriodicParts(ast.get(i), period);
if (temp.isPresent() && temp.arg1().isZero()) {
result.set(1, ast.splice(i).oneIdentity0());
result.set(2, temp.arg2());
return result;
}
}
}
}
return F.NIL;
}
Aggregations