use of org.matheclipse.core.interfaces.ISparseArray in project symja_android_library by axkr.
the class EvalEngine method evalASTArg1.
/**
* Evaluate an AST with only one argument (i.e. <code>head[arg1]</code>). The evaluation steps are
* controlled by the header attributes.
*
* @param ast
* @return
*/
private IExpr evalASTArg1(final IAST ast) {
// special case ast.isAST1()
// head == ast[0] --- arg1 == ast[1]
IExpr result = ast.head().evaluateHead(ast, this);
if (result.isPresent()) {
return result;
}
final ISymbol symbol = ast.topHead();
final int attributes = symbol.getAttributes();
if ((attributes & ISymbol.SEQUENCEHOLD) != ISymbol.SEQUENCEHOLD) {
if ((result = F.flattenSequence(ast)).isPresent()) {
return result;
}
}
if ((result = evalArgs(ast, attributes)).isPresent()) {
return result;
}
final IExpr arg1 = ast.arg1();
if (ISymbol.hasFlatAttribute(attributes)) {
if (arg1.head().equals(symbol)) {
// associative
return arg1;
}
if (arg1.isUnevaluated() && arg1.first().head().equals(symbol) && arg1.first().isAST()) {
IAST unevaluated = (IAST) arg1.first();
return unevaluated.map(symbol, x -> F.Unevaluated(x));
}
}
if ((ISymbol.LISTABLE & attributes) == ISymbol.LISTABLE) {
if (symbol.isBuiltInSymbol()) {
if (arg1.isRealVector() && ((IAST) arg1).size() > 1) {
final IEvaluator module = ((IBuiltInSymbol) symbol).getEvaluator();
if (module instanceof DoubleUnaryOperator) {
DoubleUnaryOperator oper = (DoubleUnaryOperator) module;
return ASTRealVector.map((IAST) arg1, oper);
}
} else if (arg1.isRealMatrix()) {
final IEvaluator module = ((IBuiltInSymbol) symbol).getEvaluator();
if (module instanceof DoubleUnaryOperator) {
DoubleUnaryOperator oper = (DoubleUnaryOperator) module;
return ASTRealMatrix.map((IAST) arg1, oper);
}
}
if (arg1.isList()) {
// thread over the list
return EvalAttributes.threadList(ast, S.List, ast.head(), ((IAST) arg1).argSize());
} else if (arg1.isAssociation()) {
// thread over the association
return ((IAssociation) arg1).mapThread(ast, 1);
} else if (arg1.isSparseArray()) {
return ((ISparseArray) arg1).mapThread(ast, 1);
} else if (arg1.isConditionalExpression()) {
IExpr temp = ast.extractConditionalExpression(true);
if (temp.isPresent()) {
return temp;
}
}
}
}
if ((ISymbol.NUMERICFUNCTION & attributes) == ISymbol.NUMERICFUNCTION) {
if (ast.arg1().isIndeterminate()) {
return S.Indeterminate;
}
}
if (!(arg1 instanceof IPatternObject) && arg1.isPresent()) {
ISymbol lhsSymbol = arg1.isSymbol() ? (ISymbol) arg1 : arg1.topHead();
return lhsSymbol.evalUpRules(ast, this);
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.ISparseArray 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.ISparseArray in project symja_android_library by axkr.
the class LinearAlgebra method dimensions.
/**
* Return the <a href=
* "https://github.com/axkr/symja_android_library/blob/master/symja_android_library/doc/functions/Dimensions.md">Dimensions</a>
* of an <code>expr</code>. All (sub-)expressions in the dimension must have the same
* <code>header</code>.
*
* @param expr
* @param header the header, which all sub-expressions of the detected dimension must contain
* @param maxLevel the maximum level (depth) of analyzing for the dimension
* @param throwIllegalArgumentException
* @return a list of size <code>0</code> if no dimensions are found
*/
public static IntArrayList dimensions(IExpr expr, IExpr header, int maxLevel, boolean throwIllegalArgumentException) {
if (expr.isAST()) {
return dimensionsRecursive((IAST) expr, header, maxLevel, throwIllegalArgumentException, new IntArrayList());
}
if (expr.isSparseArray()) {
int[] dims = ((ISparseArray) expr).getDimension();
if (dims.length > maxLevel) {
IntArrayList list = new IntArrayList(maxLevel);
if (throwIllegalArgumentException) {
throw new IllegalArgumentException();
}
for (int i = 0; i < maxLevel; i++) {
list.add(dims[i]);
}
return list;
}
IntArrayList list = new IntArrayList(dims.length);
for (int i = 0; i < dims.length; i++) {
list.add(dims[i]);
}
return list;
}
return new IntArrayList();
}
use of org.matheclipse.core.interfaces.ISparseArray in project symja_android_library by axkr.
the class SerializableTest method testSparseArray.
public void testSparseArray() {
ISparseArray sparse = F.sparseArray(F.List(F.Rule(F.List(1, 2, 3), F.b), F.Rule(F.List(1, 4, 5), F.a)));
equalsCopy(sparse);
}
use of org.matheclipse.core.interfaces.ISparseArray in project symja_android_library by axkr.
the class EvalAttributes method threadList.
/**
* Thread through all (sub-)lists in the arguments of the IAST (i.e. typically the ASTs head has
* the attribute ISymbol.LISTABLE) example: <code>Sin[{2,x,Pi}] ==> {Sin[2],Sin[x],Sin[Pi]}</code>
*
* @param ast
* @param listHead the lists head (typically <code>F.List</code>)
* @param argHead the arguments head (typically <code>ast.head()</code>)
* @param listLength the length of the list
* @return the resulting ast with the <code>argHead</code> threaded into each ast argument.
*/
public static IASTMutable threadList(final IAST ast, final IExpr listHead, final IExpr argHead, final int listLength) {
if (listLength == 0) {
return F.headAST0(listHead);
}
IASTMutable result = F.NIL;
final int listSize = ast.size();
for (int j = 1; j < listLength + 1; j++) {
final IASTMutable subResult = F.astMutable(argHead, listSize - 1);
for (int i = 1; i < listSize; i++) {
if (//
listHead == S.List && (ast.get(i).isList() || ast.get(i).isSparseArray())) {
if (ast.get(i).isList()) {
final IAST arg = (IAST) ast.get(i);
subResult.set(i, arg.get(j));
} else if (ast.get(i).isSparseArray()) {
final ISparseArray arg = (ISparseArray) ast.get(i);
subResult.set(i, arg.get(j));
// subResult.set(i, Programming.sparsePart(arg, F.Part(arg, F.ZZ(j)), 2,
// EvalEngine.get()));
}
} else if (listHead == S.SparseArray) {
if (ast.get(i).isList()) {
final IAST arg = (IAST) ast.get(i);
if (j >= arg.size()) {
return F.NIL;
}
subResult.set(i, arg.get(j));
} else if (ast.get(i).isSparseArray()) {
final ISparseArray arg = (ISparseArray) ast.get(i);
if (j >= arg.size()) {
return F.NIL;
}
subResult.set(i, arg.get(j));
} else {
subResult.set(i, ast.get(i));
}
} else if (ast.get(i).isAST(listHead)) {
final IAST arg = (IAST) ast.get(i);
subResult.set(i, arg.get(j));
} else {
subResult.set(i, ast.get(i));
}
}
if (!result.isPresent()) {
IExpr head = listHead == S.SparseArray ? S.List : listHead;
switch(listLength) {
case 1:
result = F.unaryAST1(head, F.Slot1);
break;
case 2:
result = F.binaryAST2(head, F.Slot1, F.Slot2);
break;
case 3:
result = F.ternaryAST3(head, F.Slot1, F.Slot2, F.Slot3);
break;
default:
result = F.astMutable(head, listLength);
}
}
result.set(j, subResult);
}
if (listHead == S.SparseArray) {
return F.unaryAST1(S.SparseArray, result);
}
return result;
}
Aggregations