public int extent(ExpressionProgram prog, int myIndex) { // The ExpressionCommand occurs in the program prog at the index indicated by myIndex. // Return the total number of indices in prog occupied by this command and the commands // that generate data used by this command. In this case, that means the commands that // compute the upper and lower limits of the summatio, plus this Cmd object. int upper = prog.extent(myIndex - 1); // Extent of upper limit expression in prog. int lower = prog.extent(myIndex - 1 - upper); // Extent of lower limit expression in prog. return upper + lower + 1; // Upper + lower limits + this object. }
public void appendOutputString(ExpressionProgram prog, int myIndex, StringBuffer buffer) { // The ExpressionCommand occurs in the program prog at the index indicated by myIndex. // Add a print string representation of the sub-expression represented by this command // (including any previous commands in the program that generate data used by this // command). int upper = prog.extent(myIndex - 1); buffer.append("sum("); buffer.append(sumVar.getName()); buffer.append(", "); prog.appendOutputString(myIndex - 1 - upper, buffer); buffer.append(", "); prog.appendOutputString(myIndex - 1, buffer); buffer.append(", "); buffer.append(sumExpr.toString()); buffer.append(")"); }
/** * When the name of this ParserExtension is encountered by a parser with which the extension is * registered, the parser calls this routine to parse the summation subexpression. The * subexpression has the form (<variable>,<lower-limit>,<upper-limit>,<expression>). This method * is not meant to be called directly */ public void doParse(Parser parser, ParserContext context) { int tok = context.next(); String open = context.tokenString; if (tok == ParserContext.OPCHARS && (open.equals("(") || (open.equals("[") && (context.options & Parser.BRACKETS) != 0) || (open.equals("{") && (context.options & Parser.BRACES) != 0))) { String close = open.equals("(") ? ")" : (open.equals("[") ? "]" : "}"); tok = context.next(); // Must be an identifier. if (tok != ParserContext.IDENTIFIER) throw new ParseError( "Expected the summation variable as the first argument of " + name + ".", context); String varName = context.tokenString; tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(",")) throw new ParseError( "Exprected a comma after the index variable, " + varName + ".", context); parser.parseExpression(context); tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(",")) throw new ParseError( "Exprected a comma after the lower limit expression for " + name + ".", context); parser.parseExpression(context); tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(",")) throw new ParseError( "Exprected a comma after the upper limit expression for " + name + ".", context); Variable v = new Variable(varName); context.mark(); // Temporoarily add the summation variable to the symbol table. context.add(v); ExpressionProgram saveProg = context.prog; context.prog = new ExpressionProgram(); // Compile the expression into a new program. parser.parseExpression(context); tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(close)) throw new ParseError( "Expected a \"" + close + "\" at the end of the paramter list for " + name + ".", context); context.revert(); // Restore the state of the ParserContext. saveProg.addCommandObject(new Cmd(v, context.prog)); context.prog = saveProg; } else throw new ParseError("Parentheses required around parameters of summation.", context); } // end doParse()
public void compileDerivative( ExpressionProgram prog, int myIndex, ExpressionProgram deriv, Variable wrt) { // The ExpressionCommand occurs in the program prog at the index indicated by myIndex. // Add commands to deriv that will evaluate the derivative of this command with respect to // the variable wrt. Note that the "Cmd" object is preceded in the program by commands that // compute the lower and upper limits of the summation. if (!sumExpr.dependsOn(wrt)) deriv.addConstant(0); else { int upper = prog.extent(myIndex - 1); // Size of expression giving the upper limit. prog.copyExpression(myIndex - 1 - upper, deriv); // Copy lower limit exression to deriv. prog.copyExpression(myIndex - 1, deriv); // Copy upper limit expression to deriv. deriv.addCommandObject(new Cmd(sumVar, (ExpressionProgram) sumExpr.derivative(wrt))); } }
public void apply(StackOfDouble stack, Cases cases) { // This routine is called when an ExpressionCommand object is encountered during // the evaluation of an ExpressionProgram. The stack may contain results of // previous commands in the program. In this case, the command is a summation // and the stack contains the upper and lower limits summation limits. double upper = Math.round(stack.pop()) + 0.1; // Get summation limits. double lower = Math.round(stack.pop()); if (Double.isNaN(upper) && Double.isNaN(lower) || upper - lower > 1000000) stack.push(Double.NaN); double sum = 0; for (double x = lower; x <= upper; x++) { // Compute the sum. sumVar.setVal(x); sum += sumExpr.getVal(); } stack.push(sum); // Leave the sum on the stack. }
public boolean dependsOn(Variable x) { // Return true if this command depends on the value of x, false otherwise. // That is, when apply() is called, can the result depend on the value of x? return sumExpr.dependsOn(x); }