Search in sources :

Example 1 with FunctionNode

use of org.matheclipse.parser.client.ast.FunctionNode in project symja_android_library by axkr.

the class DoubleEvaluator method getDerivativeResult.

private ASTNode getDerivativeResult(ASTNode arg1Derived, FunctionNode fun) {
    if (!arg1Derived.equals(new DoubleNode(1.0))) {
        FunctionNode res = new FunctionNode(fASTFactory.createSymbol("Times"));
        res.add(arg1Derived);
        res.add(fun);
        return res;
    }
    return fun;
}
Also used : FunctionNode(org.matheclipse.parser.client.ast.FunctionNode)

Example 2 with FunctionNode

use of org.matheclipse.parser.client.ast.FunctionNode 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());
}
Also used : SymbolNode(org.matheclipse.parser.client.ast.SymbolNode) ArithmeticMathException(org.matheclipse.parser.client.math.ArithmeticMathException) NumberNode(org.matheclipse.parser.client.ast.NumberNode) FunctionNode(org.matheclipse.parser.client.ast.FunctionNode) ASTNode(org.matheclipse.parser.client.ast.ASTNode)

Example 3 with FunctionNode

use of org.matheclipse.parser.client.ast.FunctionNode 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;
}
Also used : SymbolNode(org.matheclipse.parser.client.ast.SymbolNode) ASTNode(org.matheclipse.parser.client.ast.ASTNode) FunctionNode(org.matheclipse.parser.client.ast.FunctionNode)

Example 4 with FunctionNode

use of org.matheclipse.parser.client.ast.FunctionNode in project symja_android_library by axkr.

the class Parser method getFunctionArguments.

/**
	 * Get a function f[...][...]
	 * 
	 */
FunctionNode getFunctionArguments(final ASTNode head) throws SyntaxError {
    final FunctionNode function = fFactory.createAST(head);
    fRecursionDepth++;
    try {
        getNextToken();
        if (fToken == TT_ARGUMENTS_CLOSE) {
            getNextToken();
            if (fToken == TT_ARGUMENTS_OPEN) {
                return getFunctionArguments(function);
            }
            return function;
        }
        getArguments(function);
    } finally {
        fRecursionDepth--;
    }
    if (fToken == TT_ARGUMENTS_CLOSE) {
        getNextToken();
        if (fToken == TT_ARGUMENTS_OPEN) {
            return getFunctionArguments(function);
        }
        return function;
    }
    throwSyntaxError("']' expected.");
    return null;
}
Also used : FunctionNode(org.matheclipse.parser.client.ast.FunctionNode)

Example 5 with FunctionNode

use of org.matheclipse.parser.client.ast.FunctionNode in project symja_android_library by axkr.

the class Parser method getList.

/**
	 * Get a list {...}
	 * 
	 */
private ASTNode getList() throws SyntaxError {
    final FunctionNode function = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.List));
    getNextToken();
    if (fToken == TT_LIST_CLOSE) {
        getNextToken();
        return function;
    }
    fRecursionDepth++;
    try {
        getArguments(function);
    } finally {
        fRecursionDepth--;
    }
    if (fToken == TT_LIST_CLOSE) {
        getNextToken();
        return function;
    }
    throwSyntaxError("'}' expected.");
    return null;
}
Also used : FunctionNode(org.matheclipse.parser.client.ast.FunctionNode)

Aggregations

FunctionNode (org.matheclipse.parser.client.ast.FunctionNode)18 ASTNode (org.matheclipse.parser.client.ast.ASTNode)8 SymbolNode (org.matheclipse.parser.client.ast.SymbolNode)6 NumberNode (org.matheclipse.parser.client.ast.NumberNode)3 IAST (org.matheclipse.core.interfaces.IAST)2 IExpr (org.matheclipse.core.interfaces.IExpr)2 Parser (org.matheclipse.parser.client.Parser)2 IntegerNode (org.matheclipse.parser.client.ast.IntegerNode)2 ArithmeticMathException (org.matheclipse.parser.client.math.ArithmeticMathException)2 PrefixOperator (org.matheclipse.parser.client.operator.PrefixOperator)2 Apfloat (org.apfloat.Apfloat)1 Apint (org.apfloat.Apint)1 AST2Expr (org.matheclipse.core.convert.AST2Expr)1 WrongArgumentType (org.matheclipse.core.eval.exception.WrongArgumentType)1 IInteger (org.matheclipse.core.interfaces.IInteger)1 INumber (org.matheclipse.core.interfaces.INumber)1 ISignedNumber (org.matheclipse.core.interfaces.ISignedNumber)1 ISymbol (org.matheclipse.core.interfaces.ISymbol)1 FloatNode (org.matheclipse.parser.client.ast.FloatNode)1 FractionNode (org.matheclipse.parser.client.ast.FractionNode)1