home *** CD-ROM | disk | FTP | other *** search
/ Troubleshooting Netware Systems / CSTRIAL0196.BIN / attach / pcc / v08n03 / math.exe / PARSER21.ZIP / FORMULC.DOC < prev    next >
Text File  |  1994-08-23  |  11KB  |  251 lines

  1. /*  FORMULC.DOC as of 8/21/94 (v2.1) */
  2. /*  Copyright (c) 1994 Harald Helfgott (E-MAIL: seiere@uwyo.edu) */
  3. /*  This file must be distributed with its corresponding
  4.     README.DOC. You should read it, for you will find my regular
  5.     address and the copyright and availability information there.   */
  6.  
  7.           Overview of the FORMULC 2.0 functions
  8.           -------- -- --- ------- --- ---------
  9.  
  10.  
  11.      The FORMULC set of functions is written in ANSI C. It has
  12. been tested in a 386SX running GNU CC (DJGPP 1.11), in another
  13. 386SX running Turbo C++ v3.0 and in a VAX/VMS, but it will probably
  14. run in any machine with an ANSI C compiler. The functions enable
  15. the user of a C program to enter mathematical functions and to 
  16. evaluate them very rapidly. This project was undertaken for the
  17. Finite Elements Laboratory of the School of Mathematics in the
  18. Universidad Mayor de San Marcos, Lima, Peru.
  19.  
  20.      Any programmer who handles mathematical problems must
  21. sometimes require the users of his or her programs to enter a
  22. mathematical function by the keyboard. Embedding the function in
  23. the program is time-consuming and not user friendly. Consequently,
  24. there is a large number of programs in C and Pascal that parse
  25. strings representing mathematical formulas. In fact, most good
  26. Pascal and C books have a more or less inchoate parser. However,
  27. all the formula interpreters I have seen are extremely slow.
  28.  
  29.      On May 1993, a mathematics professor in Lima, Peru asked me
  30. whether I could write a quick formula interpreter. His program
  31. needed to compute a formula entered by the user hundreds of
  32. thousands of times. I decided, therefore, to write a two-stage
  33. interpreter. First, a string containing a mathematical function is
  34. translated into another string in a postfix format. Every formula
  35. goes through this stage once. Then, the string in postfix format is
  36. interpreted whenever one wants to evaluate the mathematical
  37. function. Since this string's structure makes the use of a stack
  38. rapid, lacks white space and has additional characters to ensure
  39. that the computer understands the formula swiftly, interpretation
  40. is little time consuming. Although extra space is needed for the
  41. intermediate string, the velocity of the two-stage method
  42. compensates the space overhead.
  43.  
  44.      The FORMULC routines are easy to use. They are all in one
  45. file, FORMULC.C; one only needs to type
  46.          #include "formula.h"
  47.      and to link FORMULC with one's program to use the functions.
  48. There are no initialization routines. There are utilities that
  49. describe and extend the types of expressions that the formula
  50. interpreter can understand. Moreover, I expect the program to be
  51. error free and resistant to the human fallibility of the users.
  52.  
  53.  
  54.      Please read TIME.DOC to know about the velocity of my formula
  55. interpreter. My address, the instructions for reporting bugs, the
  56. statement of what you are allowed to do with the program and the
  57. registration information are in README.DOC.
  58.  
  59.  
  60.      Description of the functions
  61.      ----------- -- --- ---------
  62.  
  63. unsigned char *translate(char *source, char *args, int *length,
  64.                            int *error);
  65.  
  66.  Examples:
  67.      f = translate("x^2 + sin(3*x) + 0.1", "x", plength, perror);
  68.  
  69.      f = translate("1E+5 * x/x \n", "x", plength, perror);
  70.  
  71.      gets(gsource);
  72.      g=translate(gsource, "xyz", plength, perror);
  73.          /* g is a function of x, y and z */
  74.  
  75.      This function transforms a legible mathematical function in
  76. string source[] into a coded function which is returned. The
  77. arguments of source are in string arg[]; they must be lower-case
  78. letters. If source uses an  undeclared argument, translate stops
  79. coding and returns the index of the  argument in *error. In fact,
  80. if any error occurs, *error contains an approximation of the index
  81. of the character in source[] that causes the error, *length acquires
  82. the value 0 and translate returns NULL. However, if source[] contains
  83. a valid mathematical function, the transformation occurs, *length
  84. contains the length of function[] (not including the final \0) and
  85. *error contains -1.
  86.  
  87.      The result string is dynamically allocated. It is likely to be
  88. far larger than source[]. If it does not fit in memory, or if any other
  89. out-of-memory error occurs, translate returns NULL, but *error contains
  90. -1. The result string can always be deallocated using free().
  91.  
  92.           source[]                |   Length of function[]
  93.                       |   (VMS 5.5 CC)
  94.                       |
  95.                   "4", "4.0" or "4.0E-3"  |     9 chars
  96.                   "x"                     |     2 chars
  97.             "(x+3)^2"                     |     22 chars
  98.             "(x+3)*(x+3)"                 |     25 chars
  99.             "atan2(x^2,sqrt(x)-x))"       |     21 chars
  100.             "acos(cos(x)-x)"              |     9 chars
  101.  
  102.  
  103.        The syntax of source is the following one (in Extended
  104. Backus-Naur Form):
  105.  
  106.      source = expression "\0"
  107.      expression = [-] summand {("+" | "-") summand}
  108.      summand = factor {("*" | "/") factor}
  109.         /*Please, don't forget "*" ! */
  110.      factor = base {"^" base}
  111.      base = "(" expression ")" | function "(" expression ")" |
  112.                       number | parameter
  113.      function = a string in the function table
  114.      parameter = a lower-case letter mentioned by arg[]
  115.      number = any nonnegative number  /* the sign is considered in
  116.                                     the definition of expression */
  117.                              /* please write 3.5E-3, not 3.5e-3 */
  118.  
  119.      This description of the syntax mimics the algorithm in
  120. translate(...). It must be noticed that -3+5*6 and 3+5*(-6) are
  121. allowed, but 3+5*-6 and 3+-5*6  are not. Moreover, following standard
  122. C notation, -x^2 and -6^2 mean (-x)^2 and (-6)^2, the unary minus
  123. operator having higher precedence than the power operator.
  124.  
  125.      White space is ignored. Moreover, translate(...) is not case-
  126. sensitive.
  127.  
  128.      translate(...) works recursively. First, it locates the
  129. operator with  the lowest order of precedence. Then, it calls
  130. itself to translate each operand. Thereafter, it adds the operator
  131. at the end and stops. If both operands are constants, translate
  132. executes fval to evaluate the expression at "compile time". (Beware
  133. of overflows! They can be perceived by the standard methods.) If
  134. there is no operator, translate(...) checks whether its input is
  135. a variable or a constant. If the input is invalid, translate(...)
  136. points out the error. Otherwise, *error contains -1.
  137.  
  138.      The coded function in string function uses postfix notation.
  139. The syntax is the following one:
  140.  
  141. coded function = ce "\0"
  142. ce = ("" | ce | (ce ce) | (ce ce ce) ) operator |
  143.                                       parameter | number
  144. parameter = "V" lower-case letter
  145. number = "D" any real number in double format
  146. operator = "^" | "+" | "*" | "-" | "/" | "M"  /*i.e. unary minus */
  147.  
  148.                                        | function
  149. /*each operand has a characteristic number of operands
  150.                     (i.e. ce's) */
  151.  
  152. function = "F" index of a function in the table (one char)
  153.       /* Be careful! The index may be represented as \0 */
  154.       /* Trust only the result of translate when finding */
  155.       /*  out the length of the coded function.         */
  156.       /* Since there can be more than 128 functions, */
  157.       /* please declare function[] as an array of unsigned */
  158.       /* char                                              */
  159.    No blanks exist.
  160.      The standard functions are exp(), ln(x), sin(), cos(), tan(),
  161. asin(), acos(), atan(), abs(), pi() (without parameters inside the
  162. brackets)  and sqrt(). One can add new functions by using fnew(..);
  163. the name of each function obeys C regulations but can be as long as
  164. needed. If a new function  is used, fnew(..) must be called in the
  165. same run as translate(..); one must  not call fnew, translate a
  166. function, store the coded function and call a  program that uses
  167. fnew(..) and loads the coded function. Moreover, no random-number
  168. generator should be added with fnew.
  169.  
  170. double fval(unsigned char *function, char *args, ...);
  171.  Examples:
  172.  
  173.      translate(f,"x^2+sin(cos(x))","x");
  174.      result=fval(f,"x",3.0);  /* 3.0, not 3 */
  175.      /* returns 3^2+sin(cos(3)) */
  176.  
  177.  
  178.      translate(g,"n*m","nm");
  179.      for(p=0; p<100; p++)
  180.       for(q=0; q<1000; q++)
  181.        a[p][q]=fval(g,"nm",(double) p,(double) q);
  182.                          /* the arguments must always be double */
  183.  
  184.   fval(...) calculates the value of a coded mathematical function
  185. in string function[] when the arguments, whose names are in string
  186. args[], are given. If there are not enough parameters or if the
  187. parameters don't belong to the function, the result is undefined.
  188. If there are any mathematical errors such as trying to obtain the
  189. square root of -5, errno is EDOM (domain error) or ERANGE (range
  190. error), the results are Infinity and Not-A-Number, or the program
  191. stops, depending on the compiler and how you use it.
  192.  
  193. double f_x_val(unsigned char *function, double x);    
  194.  
  195.  Examples:
  196.       result=f_x_val(f,3);   /* calculates f(3) if f is a function
  197.                                                             of x */
  198.  
  199.      A shorthand version of fval(..) for functions of x. It is
  200. about as rapid as fval(..) .
  201.  
  202. int fnew(char *name, void *f, int n_pars);
  203.  
  204.   Examples:
  205.  
  206.      fnew("sinh",(void *) sinh,1);   /* sinh has been declared as
  207.                                             double sinh(double); */
  208.                                     /* The (void *) cast is necessary
  209.                                         only if you use C++ */
  210.      fnew("logb",(void *)logb,2);   /* logb has been declared as
  211.                                    double logb(double, double); */
  212.  
  213.     fnew(...) adds a user-defined C function with double parameters
  214. to the  library of FORMULA. The C function can have from 0 to 3
  215. parameters. fnew(...)  returns 0 if the library is full (255
  216. functions) or if other error occurs.  Otherwise, it returns 1.
  217.  
  218.     Please, do not call any function 'E' !
  219.  
  220. int read_table(int i, char *name, int *n_of_pars);
  221.  
  222.   Example:
  223.      i=0;
  224.      while(read_table(i++, name, &n_pars)
  225.          printf("%s %d",name,n_pars);
  226.  
  227.     read_table copies the name and the number of parameters of
  228. function #i onto name[] and *n_of_pars. If function #i does not
  229. exist, read_table returns 0. Otherwise, it returns a positive
  230. number.
  231. int where_table(char *name);
  232.  
  233.  Example:
  234.      if(where_table("sinh") == -1)
  235.       printf("Hyperbolic sine not defined.");
  236.  
  237.    If there is a mathematical function called name[],
  238. where_table(..) returns  its index in the table of functions.
  239. Otherwise, where_table(..) returns -1.  Use fnew(..) to define
  240. mathematical functions which are not in FORMULA's  standard
  241. library.
  242.  
  243. int fdel(char *name);
  244.  
  245.  Example:
  246.     if(where_table("sinh" != -1)
  247.      fdel("sinh");
  248.  
  249.    If there is a mathematical function called name[], fdel deletes
  250. it. If fdel is succesful, it returns a non-negative number;
  251. otherwise, it returns -1.