CS211 Homework 2

 

Watch this space for updates!

 

 

Post-Fix Function Evaluator

 

Concepts you should understand:

 

Multi-dimensional Arrays

            Interfaces

            Inheritance

            Stack

            Postfix Machines (refer to your textbook, section 11.2.1)

 

Input:

 

Input is entirely by command-line arguments. The first argument describes the size (e.g. the length of one side) of a square. The remaining arguments are the postfix commands to a simple post-fix stack machine for evaluating a function. These commands describe a function in x and y in postfix notation.  For example, the function
f(x,y) = x^2 + y^2 + 1 could be represented as:

 

    x x * y y * + 1 +

 

You will need to use java.util.Stack. Each variable or number is simply pushed onto the stack. Each operation takes the top two stack items and replaces them with the result of the operation.  Be careful about the order in which stack items are processed when doing subtraction or division.  For instance you should check your code to make sure that “4 3 –” evaluates as 1 and not –1.

 

For command line parsing: The command line arguments (separated by spaces) are automatically divided into an array of String (i.e., the argument to the main() method) where each element of the array is a String that is either an operation (+,-,*,/) or a number or a variable (x,y). Any token longer than one character should be a number.  The one-character tokens can be easily checked to see what category they're in. Note that the numbers can have decimal points (see the java.lang.Double.valueOf( ) method).  For simplicity, all numbers are assumed to be of type double.

 

Errors:

 

If the input arguments are not in the proper format then you should print an appropriate error message.  To do this, you will need to catch exceptions (e.g., Double.valueOf throws a NumberFormatException). An appropriate error message means your program must be able to tell what kind of error it is. This includes: bad number format, stack has more than one element after evaluating the function, and not enough elements in the stack.  When using numbers of type double, division by zero produces + or – infinity in Java; your program can do the same.

 

Output:

 

If you invoke your program with the following command-line arguments:

3 x 3 + y 1 - * 2 / 10 +

 

then the first 3 should cause your program to create a 3 by 3 matrix.  The remaining commands describe a function that is invoked on each index-pair of the matrix.  The result of the function is stored in the matrix.  In other words, the command-line arguments describe a function f(x,y).  The value of f(i,j) is stored in matrix[i,j].  In the output for the example, the top right of the matrix corresponds to x=2 and y=0 and f(x,y) = 7.5

 

Your output should be:

8.5 8.0 7.5

10.0 10.0 10.0

11.5 12.0 12.5

 

Efficiency:

 

Your code should be efficient.  In particular, your code shouldn’t convert a string (e.g., “1.5234”) into a double each and every time the function is evaluated.

 

Double.valueOf( ) is expensive compared to Double.doubleValue( ).  The first method takes a String and returns the equivalent double.  The second method returns the value of a double stored within a Double.  The class Double is a wrapper class (see page 95 in the text).  It exists as a convenient way to store a double (a primitive type) so that it can be used as an Object.

 

A function is evaluated several times as the matrix of values is filled in.  It’s very inefficient if every number in the postfix definition of the function is converted from a String into a double each and every time the function is evaluated.  It’s more efficient to convert each number just once, when it’s first recognized as a number.  Once it has been converted to a double, it can be “wrapped” (use: “new Double(double);” to create an Object that holds a double), and then stored in, for instance, a Vector (see java.util.Vector) along with the operators.

 

How your program will be graded:

 

We will run your program with our own post-fix commands which will be designed to break your program. This comprises 80% of the assignment grade. Make sure you print your matrix as in the example so we can compare yours to ours. Partial credits will be awarded if the graders can understand your code (e.g. please write comments!!). The other 20% will be your style and efficiency.

 

Code skeleton:

 

import java.util.*;

 

/**

 * Handles functions that take an unspecified number of arguments

 */

interface Function {

 

  /**

   * Returns the number of arguments that this Function takes.

   * @return number of arguments this function uses

   */

  public int argCount();

 

  /**

   * Evaluate the Function.

   * @param args the arguments to the function

   * @return the value of the function evaluated on the given arguments

   * @exception IllegalArgumentException is thrown for wrong number of arguments

   */

  public double evaluate (double[] args);

}

 

/**

 * This interface handles functions that take exactly two arguments.

 */

interface Function2 extends Function {

 

  /**

   * Evaluate the function.

   * @param x the first argument to the function

   * @param y the second argument to the function

   * @return the value of the function evaluated on x and y

   */

  public double evaluate (double x, double y);

}

 

/**

 * This class implements a function in x and y defined by a String array.

 */

class StringFunction implements Function2 {

 

      /**

       * Create a function defined by a String array.

       * @param args the String array; a postfix function in x and y

       */

      public StringFunction (String[] args) {

         // Todo: Initialize a StringFunction and throw exceptions when needed

      }

 

      /**

       * Evaluate the function.

       * @param x the first argument to the function

       * @param y the second argument to the function

       * @return the value of the function evaluated on x and y

       */

      public double evaluate (double x, double y) {  

            // Todo: Evaluate the function using x and y, throwing exceptions when needed

      }

 

      // Todo: You will need at least one other method.

}

 

/**

 * This class takes an array of arguments as Strings from command line and parses

 * them to create a matrix populated with functions on the indices of the matrix.

 */

public class Evaluator {

 

      public static void main (String[] args) {

 

            // Todo: If input is wrong, you need to produce a reasonable error message

 

            // Extract the size of the matrix

            int size = Integer.parseInt(args[0]);

 

            // Todo: You may need to process the arguments first.

            // Todo: Create a StringFunction based on the arguments and evaluate it

            //       to fill in the matrix, and then print out the matrix.

      }

}