use of org.matheclipse.core.interfaces.IEvaluator in project symja_android_library by axkr.
the class BuiltInSymbol method evaluate.
/** {@inheritDoc} */
@Override
public IExpr evaluate(EvalEngine engine) {
if (hasLocalVariableStack()) {
return IExpr.ofNullable(get());
}
IExpr result;
if ((result = evalDownRule(engine, this)).isPresent()) {
return result;
}
final IEvaluator module = getEvaluator();
if (module instanceof ISymbolEvaluator) {
IExpr temp;
if (engine.isNumericMode()) {
if (engine.isApfloat()) {
temp = ((ISymbolEvaluator) module).apfloatEval(this, engine);
} else {
temp = ((ISymbolEvaluator) module).numericEval(this);
}
} else {
temp = ((ISymbolEvaluator) module).evaluate(this);
}
return temp;
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IEvaluator 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.IEvaluator in project symja_android_library by axkr.
the class EvalEngine method evalASTBuiltinFunction.
/**
* @param symbol
* @param ast
* @return <code>F.NIL</code> if no evaluation happened
*/
private IExpr evalASTBuiltinFunction(final ISymbol symbol, IAST ast) {
final int attributes = symbol.getAttributes();
if (fEvalLHSMode) {
if ((ISymbol.HOLDALL & attributes) == ISymbol.HOLDALL) {
// (i.e. Sin, Cos,...)
if (!(symbol.equals(S.Set) || symbol.equals(S.SetDelayed) || symbol.equals(S.UpSet) || symbol.equals(S.UpSetDelayed))) {
return F.NIL;
}
} else {
if ((ISymbol.NUMERICFUNCTION & attributes) != ISymbol.NUMERICFUNCTION) {
return F.NIL;
}
}
}
if (!symbol.equals(S.Integrate)) {
IExpr result;
if ((result = symbol.evalDownRule(this, ast)).isPresent()) {
return result;
}
}
if (symbol.isBuiltInSymbol()) {
final IEvaluator evaluator = ((IBuiltInSymbol) symbol).getEvaluator();
if (evaluator instanceof IFunctionEvaluator) {
if (ast.isEvalFlagOn(IAST.BUILT_IN_EVALED) && isSymbolicMode(attributes)) {
return F.NIL;
}
// evaluate a built-in function.
final IFunctionEvaluator functionEvaluator = (IFunctionEvaluator) evaluator;
OptionsResult opres = checkBuiltinArguments(ast, functionEvaluator);
if (opres == null) {
return F.NIL;
}
ast = opres.result;
try {
if (evaluator instanceof AbstractFunctionOptionEvaluator) {
AbstractFunctionOptionEvaluator optionsEvaluator = (AbstractFunctionOptionEvaluator) evaluator;
IExpr result = optionsEvaluator.evaluate(ast, opres.argSize, opres.options, this);
if (result.isPresent()) {
return result;
}
} else {
IExpr result = fNumericMode ? functionEvaluator.numericEval(ast, this) : functionEvaluator.evaluate(ast, this);
if (result.isPresent()) {
return result;
}
}
} catch (ValidateException ve) {
return IOFunctions.printMessage(ast.topHead(), ve, this);
} catch (FlowControlException e) {
throw e;
} catch (SymjaMathException ve) {
LOGGER.log(getLogLevel(), ast.topHead(), ve);
return F.NIL;
}
// cannot generally set the result as evaluated in built-in function. Especially problems in
// `togetherMode`
// if (isSymbolicMode(attributes) && !isTogetherMode()) {
// ast.addEvalFlags(IAST.BUILT_IN_EVALED);
// }
}
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IEvaluator in project symja_android_library by axkr.
the class Assumptions method addDistribution.
/**
* Add a distribution.
*
* @param element a <code>Distributed(x, <distribution>)</code> expression
* @param assumptions
* @return
*/
private static boolean addDistribution(IAST element, Assumptions assumptions) {
if (element.arg2().isAST()) {
IAST dist = (IAST) element.arg2();
ISymbol head = (ISymbol) dist.head();
if (head instanceof IBuiltInSymbol) {
IEvaluator evaluator = ((IBuiltInSymbol) head).getEvaluator();
if (evaluator instanceof IDistribution) {
IExpr arg1 = element.arg1();
if (arg1.isAST(S.Alternatives)) {
((IAST) arg1).forEach(x -> assumptions.distributionsMap.put(x, dist));
} else {
assumptions.distributionsMap.put(arg1, dist);
}
return true;
}
}
}
return false;
}
use of org.matheclipse.core.interfaces.IEvaluator in project symja_android_library by axkr.
the class EvalComplex method evalAST.
public static double[] evalAST(final DoubleStack stack, final int top, final IAST ast) {
final int newTop = top;
final ISymbol symbol = (ISymbol) ast.get(0);
if (symbol.isBuiltInSymbol()) {
final IEvaluator module = ((IBuiltInSymbol) symbol).getEvaluator();
if (module instanceof INumericComplex) {
// fast evaluation path
stack.ensureCapacity(top + ast.size() * 2);
for (int i = 1; i < ast.size(); i++) {
final double[] result = eval(stack, newTop, ast.get(i));
stack.push(result[0]);
stack.push(result[1]);
}
return ((INumericComplex) module).evalComplex(stack, ast.argSize());
}
}
// slow evaluation path
final IExpr result = F.evaln(ast);
if (result instanceof ComplexNum) {
final double[] res = new double[2];
res[0] = ((ComplexNum) result).getRealPart();
res[1] = ((ComplexNum) result).getImaginaryPart();
return res;
}
if (result instanceof Num) {
final double[] res = new double[2];
res[0] = ((Num) result).doubleValue();
res[1] = 0.0;
return res;
}
throw new UnsupportedOperationException();
}
Aggregations