/** * Evaluates a PostfixMathCommandI with given arguments. Not used in normal use. * * @param pfmc the command to evaluate. * @param children the parameters to the function. * @return the value of the function * @throws ParseException */ public Object eval(PostfixMathCommandI pfmc, Node children[]) throws ParseException { if (pfmc instanceof SpecialEvaluationI) { ASTFunNode node = new ASTFunNode(ParserTreeConstants.JJTFUNNODE); node.setFunction("TmpFun", pfmc); node.jjtOpen(); for (int i = 0; i < children.length; ++i) { node.jjtAddChild(children[i], i); } node.jjtClose(); return ((SpecialEvaluationI) pfmc).evaluate(node, null, this, new Stack(), this.symTab); } if (pfmc instanceof CallbackEvaluationI) { ASTFunNode node = new ASTFunNode(ParserTreeConstants.JJTFUNNODE); node.setFunction("TmpFun", pfmc); node.jjtOpen(); for (int i = 0; i < children.length; ++i) { node.jjtAddChild(children[i], i); } node.jjtClose(); Object val = ((CallbackEvaluationI) pfmc).evaluate(node, this); return val; } Stack lstack = new Stack(); for (int i = 0; i < children.length; ++i) { if (!(children[i] instanceof ASTConstant)) throw new ParseException("buildConstantNode: arguments must all be constant nodes"); lstack.push(((ASTConstant) children[i]).getValue()); } pfmc.setCurNumberOfParameters(children.length); pfmc.run(lstack); return lstack.pop(); }
/** other functions * */ public Object visit(ASTFunNode node, Object data) throws ParseException { MatrixNodeI mnode = (MatrixNodeI) node; PostfixMathCommandI pfmc = node.getPFMC(); if (pfmc instanceof MatrixSpecialEvaluationI) { MatrixSpecialEvaluationI se = (MatrixSpecialEvaluationI) pfmc; return se.evaluate(mnode, this, mjep); } else if (pfmc instanceof CallbackEvaluationI) { Object val = ((CallbackEvaluationI) pfmc).evaluate(node, this); if (val instanceof MatrixValueI) mnode.getMValue().setEles((MatrixValueI) val); else mnode.getMValue().setEle(0, val); return mnode.getMValue(); } else if (pfmc instanceof SpecialEvaluationI) { throw new ParseException("Encountered an instance of SpecialEvaluationI"); } else if (pfmc instanceof BinaryOperatorI) { BinaryOperatorI bin = (BinaryOperatorI) pfmc; MatrixValueI lhsval = (MatrixValueI) node.jjtGetChild(0).jjtAccept(this, data); MatrixValueI rhsval = (MatrixValueI) node.jjtGetChild(1).jjtAccept(this, data); return bin.calcValue(mnode.getMValue(), lhsval, rhsval); } else if (pfmc instanceof UnaryOperatorI) { UnaryOperatorI uni = (UnaryOperatorI) pfmc; MatrixValueI val = (MatrixValueI) node.jjtGetChild(0).jjtAccept(this, data); return uni.calcValue(mnode.getMValue(), val); } else if (pfmc instanceof NaryOperatorI) { NaryOperatorI uni = (NaryOperatorI) pfmc; MatrixValueI results[] = new MatrixValueI[node.jjtGetNumChildren()]; for (int i = 0; i < results.length; ++i) results[i] = (MatrixValueI) node.jjtGetChild(i).jjtAccept(this, data); return uni.calcValue(mnode.getMValue(), results); } else if (pfmc instanceof Comparative) { Object lhsval = (MatrixValueI) node.jjtGetChild(0).jjtAccept(this, data); Object rhsval = (MatrixValueI) node.jjtGetChild(1).jjtAccept(this, data); stack.push(lhsval); stack.push(rhsval); pfmc.setCurNumberOfParameters(2); pfmc.run(stack); mnode.getMValue().setEle(0, stack.pop()); return mnode.getMValue(); } // not a clever op use old style call // assumes int num = node.jjtGetNumChildren(); for (int i = 0; i < num; ++i) { MatrixValueI vec = (MatrixValueI) node.jjtGetChild(i).jjtAccept(this, data); if (!vec.getDim().equals(Dimensions.ONE)) throw new ParseException("Arguments of " + node.getName() + " must be scalers"); stack.push(vec.getEle(0)); } pfmc.setCurNumberOfParameters(num); pfmc.run(stack); mnode.getMValue().setEle(0, stack.pop()); return mnode.getMValue(); }
/** * Visit a function node. The values of the child nodes are first pushed onto the stack. Then the * function class associated with the node is used to evaluate the function. * * <p>If a function implements SpecialEvaluationI then the evaluate method of PFMC is called. */ public Object visit(ASTFunNode node, Object data) throws ParseException { if (node == null) return null; PostfixMathCommandI pfmc = node.getPFMC(); // check if the function class is set if (pfmc == null) throw new ParseException("No function class associated with " + node.getName()); // Some operators (=) need a special method for evaluation // as the pfmc.run method does not have enough information // in such cases we call the evaluate method which passes // all available info. Note evaluating the children is // the responsibility of the evaluate method. if (pfmc instanceof SpecialEvaluationI) { return ((SpecialEvaluationI) pfmc).evaluate(node, data, this, stack, this.symTab); } if (pfmc instanceof CallbackEvaluationI) { Object val = ((CallbackEvaluationI) pfmc).evaluate(node, this); stack.push(val); return val; } if (debug == true) { System.out.println("Stack size before childrenAccept: " + stack.size()); } // evaluate all children (each leaves their result on the stack) data = node.childrenAccept(this, data); if (debug == true) { System.out.println("Stack size after childrenAccept: " + stack.size()); } if (pfmc.getNumberOfParameters() == -1) { // need to tell the class how many parameters it can take off // the stack because it accepts a variable number of params pfmc.setCurNumberOfParameters(node.jjtGetNumChildren()); } // try to run the function pfmc.run(stack); if (debug == true) { System.out.println("Stack size after run: " + stack.size()); } return data; }
/** Prints all the differentation rules for all functions on specified stream. */ public void printDiffRules(PrintStream out) { out.println("Standard Functions and their derivatives"); for (String key : globalDJep.getFunctionTable().functionNames()) { PostfixMathCommandI value = globalDJep.getFunctionTable().get(key); DiffRulesI rule = (DiffRulesI) diffRules.get(key); if (rule == null) out.print( key + " No diff rules specified (" + value.getNumberOfParameters() + " arguments)."); else out.print(rule.toString()); out.println(); } for (Enumeration en = diffRules.keys(); en.hasMoreElements(); ) { String key = (String) en.nextElement(); DiffRulesI rule = (DiffRulesI) diffRules.get(key); if (!globalDJep.getFunctionTable().contains(key)) { out.print(rule.toString()); out.println("\tnot in JEP function list"); } } }