Back to July Calendar 

Previous Entry Next Entry→

September 08, 2005

At the risk of doubling the redundancy, I again reiterate: all I want is a working function plotter! And I want to be a good basis for object oriented efficiency, portability and reusability.   I love Noam Chomsky, and someday maybe more grammar school will be needed, but, compared to Shakespeare and Chaucer talk, mathematical expressions are too simple for all that in-depth understanding of parsecs of parsing problems.  I simply want a program which draws the graphic of a user-defined function on screen...and I want it to be a good bottom. 

There should be a text field where the user, prompted by, say, "y = ", will enter a text string such as sqrt(1-x^2)" and the domain (and maybe range) intervals, and a plot will appear: a pretty picture illustrating the functional relation (not my Uncle Bob, then.)  Later, we can think about how to extend this to 3D and thus plot function defined by strings such as "sqrt(1-x^2+y^2)."

Any algorithm must establish the o.o.ops (order of operations) by, say, some list of precedence such as "pretty please my dear aunt sally," or whatever.  How about this?

   ()             expressions in parentheses first
   -x             unary negation
   x^y            exponentiation (x to the power y)
   x*y  x/y  x%y  multiplication, division and modulo, left to right
   x+y  x-y       addition and subtraction, left to right
   x==y  x!=y  x<y  x<=y  x>y  x>=y
                  comparison between x and y (result is either 0 or 1)
   x&y            result is 1 if int(x) and int(y) differ from 0, else 0.
   x|y            result is 1 if int(x) or int(y) differ from 0, else 0.

Which might go be the acronym PUP MuDiM AS Comp And Or, though I've already forgotten what I wrote, so it may not serve well as a mnemonic.

Note that the high precedence of the negation operator means that we can meaningfully evaluate 2*3.

Functions that should be considered as "built in" include

  abs(x)    : Absolute value of x, alternately denoted |A|.
  acos(x)   : Arc-cosine of x. Returns the angle, measured in radians,
              whose cosine is x.
  acosh(x)  : Same as acos() but for hyperbolic cosine.
  asin(x)   : Arc-sine of x. Returns the angle, measured in radians, whose
              sine is A.
  asinh(x)  : Same as asin() but for hyperbolic sine.
  atan(x)   : Arc-tangent of (x). Returns the angle, measured in radians,
              whose tangent is (x).
  atan2(x,y): Arc-tangent of x/y. The two main differences to atan() is
              that it will return the right angle depending on the signs of
              x and y (atan() can only return values betwen -pi/2 and pi/2),
              and that the return value of pi/2 and -pi/2 are possible.
  atanh(x)  : Same as atan() but for hyperbolic tangent.
  ceil(x)   : Ceiling of x. Returns the smallest integer greater than x.
              Rounds up to the next higher integer.
  cos(x)    : Cosine of x. Returns the cosine of the angle x, where x is
              measured in radians.
  cosh(x)   : Same as cos() but for hyperbolic cosine.
  cot(x)    : Cotangent of x (equivalent to 1/tan(x)).
  csc(x)    : Cosecant of x (equivalent to 1/sin(x)).
  eval(...) : This a recursive call to the function to be evaluated. The
              number of parameters must be the same as the number of parameters
              taken by the function. Usually called inside if() to avoid
              infinite recursion.
  exp(x)    : Exponential of x. Returns the value of e raised to the power
              A where e is the base of the natural logarithm, i.e. the
              non-repeating value approximately equal to 2.71828182846.
  floor(x)  : Floor of x. Returns the largest integer less than or equal to
              x. Rounds down to the next lower integer.
  if(x,y,z) : If int(x) differs from 0, the return value of this function is y,
              else z. Only the parameter which needs to be evaluated is
              evaluated, the other parameter is skipped; this makes it safe to
              use eval() in them.
  int(x)    : Rounds x to the closest integer. 0.5 is rounded to 1.
  log(x)    : Natural (base e) logarithm of x.
  log10(x)  : Base 10 logarithm of x.
  max(x,y)  : If x>y, the result is x, else y.
  min(x,y)  : If x<y, the result is x, else y.
  sec(x)    : Secant of x (equivalent to 1/cos(x)).
  sin(x)    : Sine of x. Returns the sine of the angle x, where x is
              measured in radians.
  sinh(x)   : Same as sin() but for hyperbolic sine.
  sqrt(x)   : Postive square root of x. Returns the positive value whose square is x.
  tan(x)    : Tangent of x. Returns the tangent of the angle x, where x
              is measured in radians.
  tanh(x)   : Same as tan() but for hyperbolic tangent.

My current inspiration/information is coming from a Finish(?) web site, which seems to be taken off the web in the few hours since I snagged it.  It is relatively small (though it'll still take a long time to sort through.)  The key to this code seems to be starting by converting to what we would call "Polish" notation, but is perhaps more properly called postfix notation.  A few illustration may convey the idea well:

infix      postfix
2+3        2 3 +
1+2+3      1 2 + 3 +
5*2+8/2    5 2 * 8 2 / +
(5+9)*3    5 9 + 3 *

The idea seems to be to rearrange the operands and operators so that the expression can be evaluated easily from left to right.