package org.matheclipse.core.eval.interfaces;
import org.matheclipse.core.basic.Config;
import org.matheclipse.core.convert.AST2Expr;
import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IComplex;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.INumber;
import org.matheclipse.core.interfaces.ISymbol;
import org.matheclipse.core.patternmatching.PatternMatcherAndInvoker;
import org.matheclipse.parser.client.Parser;
import org.matheclipse.parser.client.SyntaxError;
import org.matheclipse.parser.client.ast.ASTNode;
/**
* Abstract interface for built-in Symja functions. The numericEval() method delegates to the evaluate()
*
*/
public abstract class AbstractFunctionEvaluator implements IFunctionEvaluator {
/** {@inheritDoc} */
@Override
public IExpr numericEval(final IAST ast) {
return evaluate(ast);
}
/**
* Get the predefined rules for this function symbol. If no rules are available return null.
*
* @return
*/
// public String[] getRules() {
// return null;
// }
public IAST getRuleAST() {
return null;
}
/**
* Evaluate built-in rules and define Attributes for a function.
*
*/
@Override
public void setUp(final ISymbol symbol) throws SyntaxError {
IAST ruleList;
final EvalEngine engine = EvalEngine.get();
if ((ruleList = getRuleAST()) != null) {
engine.addRules(ruleList);
}
// String[] rules;
// if ((rules = getRules()) != null) {
// final Parser parser = new Parser();
//
// boolean oldPackageMode = engine.isPackageMode();
// boolean oldTraceMode = engine.isTraceMode();
// try {
// engine.setPackageMode(true);
// engine.setTraceMode(false);
// // if (session != null) {
// // parser.setFactory(ExpressionFactory.get());
// // }
// if (Config.DEBUG) {
// try {
// setUpRules(rules, parser, engine);
// } catch (final Throwable th) {
// th.printStackTrace();
// }
// } else {
// setUpRules(rules, parser, engine);
// }
// } finally {
// engine.setPackageMode(oldPackageMode);
// engine.setTraceMode(oldTraceMode);
// }
// }
F.SYMBOL_OBSERVER.createPredefinedSymbol(symbol.toString());
}
private void setUpRules(final String[] rules, final Parser parser, final EvalEngine engine) {
for (int i = 0; i < rules.length; i++) {
final ASTNode parsedAST = parser.parse(rules[i]);
final IExpr obj = AST2Expr.CONST.convert(parsedAST);
// engine.init();
engine.evaluate(obj);
}
}
/** {@inheritDoc} */
@Override
abstract public IExpr evaluate(final IAST ast);
/**
* Create a rule which invokes the method name in this class instance.
*
* @param symbol
* @param patternString
* @param methodName
*/
public void createRuleFromMethod(ISymbol symbol, String patternString, String methodName) {
PatternMatcherAndInvoker pm = new PatternMatcherAndInvoker(patternString, this, methodName);
symbol.putDownRule(pm);
}
/**
* Check if the expression is canonical negative.
*
* @return true if the first argument is canonical negative
*/
public static boolean isNegativeExpression(final IExpr expr) {
if (expr.isNumber()) {
if (((INumber) expr).complexSign() < 0) {
return true;
}
} else if (expr.isTimes()) {
IAST times = (IAST) expr;
if (times.arg1().isNumber()) {
if (((INumber) times.arg1()).complexSign() < 0) {
return true;
}
}
} else if (expr.isPlus()) {
IAST plus = (IAST) expr;
if (plus.arg1().isNumber()) {
if (((INumber) plus.arg1()).complexSign() < 0) {
return true;
}
// } else {
// IAST times = null;
// for (int i = 1; i < plus.size(); i++) {
// if (plus.get(i).isAST()) {
// if (times != null) {
// return false;
// }
// if (plus.get(i).isTimes()) {
// times = (IAST) plus.get(i);
// if (times.arg1().isNumber()) {
// if (((INumber) times.arg1()).complexSign() < 0) {
// continue;
// }
// }
// }
// return false;
// }
// }
// return true;
}
}
return false;
}
/**
* Check if expr is a pure imaginary number without a real part.
*
* @param expr
* @return null, if expr is not prue imaginary number.
*/
public static IExpr getPureImaginaryPart(final IExpr expr) {
if (expr.isComplex() && ((IComplex) expr).getRe().isZero()) {
IComplex compl = (IComplex) expr;
return compl.getIm();
}
if (expr.isTimes()) {
IAST times = ((IAST) expr);
IExpr arg1 = times.arg1();
if (arg1.isComplex() && ((IComplex) arg1).getRe().isZero()) {
times = times.clone();
times.set(1, ((IComplex) arg1).getIm());
return times;
}
}
return null;
}
public static IExpr[] getPeriodicParts(final IExpr expr) {
if (expr.isPlus()) {
IAST plus = (IAST) expr;
for (int i = 0; i < plus.size(); i++) {
if (plus.get(i).isTimes()) {
IAST times = (IAST) plus.get(i);
if (times.size() == 3 && times.arg2().equals(F.Pi)) {
if (times.arg1().isRational()) {
IExpr[] result = new IExpr[2];
IAST cloned = plus.clone();
cloned.remove(i);
result[0] = cloned;
result[1] = times.arg1();
return result;
}
}
}
}
}
return null;
}
}
Ads help maintain this website.