use of org.matheclipse.parser.client.ast.SymbolNode in project symja_android_library by axkr.
the class Parser method getFactor.
private ASTNode getFactor() throws SyntaxError {
ASTNode temp;
if (fToken == TT_PRECEDENCE_OPEN) {
fRecursionDepth++;
try {
getNextToken();
temp = parseExpression();
if (fToken != TT_PRECEDENCE_CLOSE) {
throwSyntaxError("\')\' expected.");
}
} finally {
fRecursionDepth--;
}
getNextToken();
if (fToken == TT_PRECEDENCE_OPEN) {
return getTimes(temp);
}
if (fToken == TT_ARGUMENTS_OPEN) {
return getFunctionArguments(temp);
}
return temp;
} else if (fToken == TT_LIST_OPEN) {
return getList();
} else if (fToken == TT_IDENTIFIER) {
final SymbolNode symbol = getSymbol();
if (fToken == TT_BLANK) {
// read '_'
if (isWhitespace()) {
temp = fFactory.createPattern(symbol, null);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(symbol, check);
} else {
temp = fFactory.createPattern(symbol, null);
}
}
} else if (fToken == TT_BLANK_BLANK) {
// read '__'
if (isWhitespace()) {
temp = fFactory.createPattern2(symbol, null);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern2(symbol, check);
} else {
temp = fFactory.createPattern2(symbol, null);
}
}
} else if (fToken == TT_BLANK_BLANK_BLANK) {
// read '___'
if (isWhitespace()) {
temp = fFactory.createPattern3(symbol, null);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern3(symbol, check);
} else {
temp = fFactory.createPattern3(symbol, null);
}
}
} else if (fToken == TT_BLANK_OPTIONAL) {
// read '_.'
if (isWhitespace()) {
temp = fFactory.createPattern(symbol, null, true);
getNextToken();
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(symbol, check, true);
} else {
temp = fFactory.createPattern(symbol, null, true);
}
}
} else if (fToken == TT_BLANK_COLON) {
// read '_:'
getNextToken();
ASTNode defaultValue = parseExpression();
temp = fFactory.createPattern(symbol, null, defaultValue);
} else {
temp = symbol;
}
return parseArguments(temp);
} else if (fToken == TT_BLANK) {
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern(null, null);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(null, check);
} else {
temp = fFactory.createPattern(null, null);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_BLANK) {
// read '__'
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern2(null, null);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern2(null, check);
} else {
temp = fFactory.createPattern2(null, null);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_BLANK_BLANK) {
// read '___'
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern3(null, null);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern3(null, check);
} else {
temp = fFactory.createPattern3(null, null);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_OPTIONAL) {
// read '_.'
if (isWhitespace()) {
getNextToken();
temp = fFactory.createPattern(null, null, true);
} else {
getNextToken();
if (fToken == TT_IDENTIFIER) {
final ASTNode check = getSymbol();
temp = fFactory.createPattern(null, check, true);
} else {
temp = fFactory.createPattern(null, null, true);
}
}
return parseArguments(temp);
} else if (fToken == TT_BLANK_COLON) {
// read '_:'
getNextToken();
ASTNode defaultValue = parseExpression();
temp = fFactory.createPattern(null, null, defaultValue);
return parseArguments(temp);
} else if (fToken == TT_DIGIT) {
return getNumber(false);
} else if (fToken == TT_STRING) {
return getString();
} else if (fToken == TT_PERCENT) {
final FunctionNode out = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Out));
int countPercent = 1;
getNextToken();
if (fToken == TT_DIGIT) {
countPercent = getIntegerNumber();
out.add(fFactory.createInteger(countPercent));
return out;
}
while (fToken == TT_PERCENT) {
countPercent++;
getNextToken();
}
out.add(fFactory.createInteger(-countPercent));
return parseArguments(out);
} else if (fToken == TT_SLOT) {
getNextToken();
final FunctionNode slot = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Slot));
if (fToken == TT_DIGIT) {
slot.add(getNumber(false));
} else {
slot.add(fFactory.createInteger(1));
}
return parseArguments(slot);
} else if (fToken == TT_SLOTSEQUENCE) {
getNextToken();
final FunctionNode slotSequencce = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.SlotSequence));
if (fToken == TT_DIGIT) {
slotSequencce.add(getNumber(false));
} else {
slotSequencce.add(fFactory.createInteger(1));
}
return parseArguments(slotSequencce);
}
switch(fToken) {
case TT_PRECEDENCE_CLOSE:
throwSyntaxError("Too much closing ) in factor.");
break;
case TT_LIST_CLOSE:
throwSyntaxError("Too much closing } in factor.");
break;
case TT_ARGUMENTS_CLOSE:
throwSyntaxError("Too much closing ] in factor.");
break;
}
throwSyntaxError("Error in factor at character: '" + fCurrentChar + "' (" + fToken + ")");
return null;
}
use of org.matheclipse.parser.client.ast.SymbolNode in project symja_android_library by axkr.
the class AST2Expr method convertNode.
/**
* Converts a parsed ASTNode expression into a Symja IExpr expression
*
* @param node the parsed ASTNode
* @return the Symja expression
*/
private IExpr convertNode(ASTNode node) {
if (node == null) {
return null;
}
if (node instanceof FunctionNode) {
final FunctionNode functionNode = (FunctionNode) node;
int size = functionNode.size();
IASTMutable ast;
switch(size) {
case 1:
ast = F.headAST0(convertNode(functionNode.get(0)));
break;
case 2:
ast = F.unaryAST1(convertNode(functionNode.get(0)), convertNode(functionNode.get(1)));
break;
case 3:
ast = F.binaryAST2(convertNode(functionNode.get(0)), convertNode(functionNode.get(1)), convertNode(functionNode.get(2)));
break;
case 4:
ast = F.ternaryAST3(convertNode(functionNode.get(0)), convertNode(functionNode.get(1)), convertNode(functionNode.get(2)), convertNode(functionNode.get(3)));
break;
default:
IASTAppendable appendableAST = F.ast(convertNode(functionNode.get(0)), functionNode.size());
for (int i = 1; i < functionNode.size(); i++) {
appendableAST.append(convertNode(functionNode.get(i)));
}
ast = appendableAST;
}
int functionID = ast.headID();
if (functionID > ID.UNKNOWN) {
IExpr temp = evaluateOnInput(functionID, ast, functionNode);
if (temp.isPresent()) {
return temp;
}
}
return ast;
}
if (node instanceof SymbolNode) {
String nodeStr = node.getString();
return convertSymbol(nodeStr);
}
// PatternNode
if (node instanceof Pattern3Node) {
final Pattern3Node p3n = (Pattern3Node) node;
SymbolNode sn = p3n.getSymbol();
return F.$ps((ISymbol) convertNode(sn), convertNode(p3n.getConstraint()), p3n.isDefault(), true);
}
if (node instanceof Pattern2Node) {
final Pattern2Node p2n = (Pattern2Node) node;
SymbolNode sn = p2n.getSymbol();
return F.$ps((ISymbol) convertNode(sn), convertNode(p2n.getConstraint()), p2n.isDefault(), false);
}
if (node instanceof PatternNode) {
final PatternNode pn = (PatternNode) node;
SymbolNode sn = pn.getSymbol();
if (sn == null) {
return F.$b(convertNode(pn.getConstraint()), pn.isDefault());
}
ASTNode defaultValue = pn.getDefaultValue();
if (defaultValue != null) {
return F.Optional(F.$p((ISymbol) convertNode(pn.getSymbol()), convertNode(pn.getConstraint())), convertNode(defaultValue));
}
return F.$p((ISymbol) convertNode(pn.getSymbol()), convertNode(pn.getConstraint()), pn.isDefault());
}
if (node instanceof IntegerNode) {
final IntegerNode integerNode = (IntegerNode) node;
final String iStr = integerNode.getString();
if (iStr != null) {
return F.ZZ(iStr, integerNode.getNumberFormat());
}
return F.ZZ(integerNode.getIntValue());
}
if (node instanceof FractionNode) {
FractionNode fr = (FractionNode) node;
IInteger numerator = (IInteger) convertNode(fr.getNumerator());
IInteger denominator = (IInteger) convertNode(fr.getDenominator());
if (denominator.isZero()) {
return F.Rational(fr.isSign() ? numerator.negate() : numerator, denominator);
}
if (denominator.isOne()) {
return fr.isSign() ? numerator.negate() : numerator;
}
// return F.Rational(fr.isSign() ? numerator.negate() : numerator, denominator);
return F.fraction(fr.isSign() ? numerator.negate() : numerator, denominator);
}
if (node instanceof StringNode) {
return F.$str(node.getString());
}
if (node instanceof FloatNode) {
String nStr = node.getString();
String floatStr = nStr;
int index = nStr.indexOf("*^");
int exponent = 1;
if (index > 0) {
floatStr = nStr.substring(0, index);
exponent = Integer.parseInt(nStr.substring(index + 2));
}
if (EvalEngine.isApfloat(fPrecision)) {
Apfloat apfloatValue = new Apfloat(floatStr, fPrecision);
if (exponent != 1) {
// value * 10 ^ exponent
return F.num(apfloatValue.multiply(ApfloatMath.pow(new Apint(10), new Apint(exponent))));
}
return F.num(apfloatValue);
}
double doubleValue = Double.parseDouble(floatStr);
if (exponent != 1) {
// value * 10 ^ exponent
return F.num(doubleValue * Math.pow(10, exponent));
}
return F.num(doubleValue);
}
if (node instanceof DoubleNode) {
return F.num(((DoubleNode) node).doubleValue());
}
return F.symbol(node.toString());
}
use of org.matheclipse.parser.client.ast.SymbolNode in project symja_android_library by axkr.
the class DoubleEvaluator method derivative.
/**
* TODO: add more derivation rules
*
* @param node
* @param var
* @return
*/
public ASTNode derivative(final ASTNode node, SymbolNode var) {
if (node.isFree(var)) {
return new DoubleNode(0.0);
}
if (node instanceof FunctionNode) {
FunctionNode f = (FunctionNode) node;
if (f.size() > 1 && f.getNode(0) instanceof SymbolNode) {
SymbolNode head = (SymbolNode) f.getNode(0);
if (f.size() == 2) {
ASTNode arg1Derived = derivative(f.getNode(1), var);
if (isSymbol(head, "Exp")) {
FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Exp"));
fun.add(f.getNode(1));
return getDerivativeResult(arg1Derived, fun);
}
if (isSymbol(head, "Cos")) {
FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Times"));
fun.add(new DoubleNode(-1.0));
fun.add(new FunctionNode(fASTFactory.createSymbol("Cos"), f.getNode(1)));
return getDerivativeResult(arg1Derived, fun);
}
if (isSymbol(head, "Sin")) {
FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Cos"));
fun.add(f.getNode(1));
return getDerivativeResult(arg1Derived, fun);
}
} else if (f.size() == 3 && isSymbol(head, "Power")) {
if (f.get(2).isFree(var)) {
// derive x^r
ASTNode arg1Derived = derivative(f.getNode(1), var);
// (r-1)
FunctionNode exponent = fASTFactory.createFunction(fASTFactory.createSymbol("Plus"), new DoubleNode(-1.0), f.get(2));
// r*x^(r-1)
FunctionNode fun = fASTFactory.createFunction(fASTFactory.createSymbol("Times"), f.get(2), fASTFactory.createFunction(fASTFactory.createSymbol("Power"), f.get(1), exponent));
return getDerivativeResult(arg1Derived, fun);
}
if (f.get(1).isFree(var)) {
// derive a^x
ASTNode arg2Derived = derivative(f.getNode(2), var);
// log(a) * a^x
FunctionNode fun = fASTFactory.createFunction(fASTFactory.createSymbol("Times"), fASTFactory.createFunction(fASTFactory.createSymbol("Log"), f.get(1)), f);
return getDerivativeResult(arg2Derived, fun);
}
} else {
if (isSymbol(head, "Plus")) {
FunctionNode result = new FunctionNode(f.getNode(0));
for (int i = 1; i < f.size(); i++) {
ASTNode deriv = derivative(f.getNode(i), var);
if (!deriv.equals(new DoubleNode(0.0))) {
result.add(deriv);
}
}
return result;
}
if (isSymbol(head, "Times")) {
FunctionNode plusResult = new FunctionNode(fASTFactory.createSymbol("Plus"));
for (int i = 1; i < f.size(); i++) {
FunctionNode timesResult = new FunctionNode(f.getNode(0));
boolean valid = true;
for (int j = 1; j < f.size(); j++) {
if (j == i) {
ASTNode deriv = derivative(f.getNode(j), var);
if (deriv.equals(new DoubleNode(0.0))) {
valid = false;
} else {
timesResult.add(deriv);
}
} else {
timesResult.add(f.getNode(j));
}
}
if (valid) {
plusResult.add(timesResult);
}
}
return plusResult;
}
}
}
return new FunctionNode(new SymbolNode("D"), node, var);
// return evaluateFunction((FunctionNode) node);
}
if (node instanceof SymbolNode) {
if (isSymbol((SymbolNode) node, var)) {
return new DoubleNode(1.0);
}
IDoubleValue v = fVariableMap.get(node.toString());
if (v != null) {
return new DoubleNode(0.0);
}
Double dbl = SYMBOL_DOUBLE_MAP.get(node.toString());
if (dbl != null) {
return new DoubleNode(0.0);
}
return new DoubleNode(0.0);
} else if (node instanceof NumberNode) {
return new DoubleNode(0.0);
}
throw new ArithmeticMathException("EvalDouble#evaluate(ASTNode) not possible for: " + node.toString());
}
use of org.matheclipse.parser.client.ast.SymbolNode in project symja_android_library by axkr.
the class DoubleEvaluator method optimizeFunction.
/**
* Optimize an already parsed in <code>functionNode</code> into an <code>ASTNode</code>.
*
* @param functionNode
* @return
*/
public ASTNode optimizeFunction(final FunctionNode functionNode) {
if (functionNode.size() > 0) {
boolean doubleOnly = true;
ASTNode node;
for (int i = 1; i < functionNode.size(); i++) {
node = functionNode.getNode(i);
if (node instanceof NumberNode) {
functionNode.set(i, new DoubleNode(((NumberNode) functionNode.getNode(i)).doubleValue()));
} else if (functionNode.getNode(i) instanceof FunctionNode) {
ASTNode optNode = optimizeFunction((FunctionNode) functionNode.getNode(i));
if (!(optNode instanceof DoubleNode)) {
doubleOnly = false;
}
functionNode.set(i, optNode);
} else if (node instanceof SymbolNode) {
Double dbl = SYMBOL_DOUBLE_MAP.get(node.toString());
if (dbl != null) {
functionNode.set(i, new DoubleNode(dbl));
} else {
doubleOnly = false;
}
} else {
doubleOnly = false;
}
}
if (doubleOnly) {
try {
return new DoubleNode(evaluateFunction(functionNode));
} catch (Exception e) {
}
}
}
return functionNode;
}
use of org.matheclipse.parser.client.ast.SymbolNode in project symja_android_library by axkr.
the class Parser method getTimesImplicit.
private ASTNode getTimesImplicit(ASTNode temp) throws SyntaxError {
FunctionNode func = fFactory.createAST(new SymbolNode("Times"));
func.add(temp);
do {
getNextToken();
temp = parseExpression();
func.add(temp);
if (fToken != TT_PRECEDENCE_CLOSE) {
throwSyntaxError("\')\' expected.");
}
getNextToken();
} while (fToken == TT_PRECEDENCE_OPEN);
return func;
}
Aggregations