rpn Calculator Module

**description:**

Many of the SDDS toolkit programs employ a common Reverse Polish Notation (RPN) calculator module for equation evaluation. This module is based on the

`rpn`programmable calculator program. It is also available in a commandline version called`rpnl`for use in shell scripts. This manual page discusses the programs`rpn`and`rpnl`, and indicates how the`rpn`expression evaluator is used in SDDS tools.**examples:**

Do some floating-point math using shell variables: (Note that the asterisk (for multiplication) is escaped in order to protect it from interpretation by the shell.)`set pi = 3.141592`

set radius = 0.15

set area = `rpnl $pi $radius 2 pow`\`

*``rpn`to do the same calculation:`rpn> 3.141592 sto pi`

rpn> 0.15 sto radius

rpn> radius 2 pow pi *

0.070685820000000

rpn> quit**synopsis:**`rpn [`*filenames*]

rpnl*rpnExpression***Overview of**:`rpn`and`rpnl``rpn`is a program that places the user in a Reverse Polish Notation calculator shell. Commands to`rpn`consist of generally of expressions in terms of built-in functions, user-defined variables, and user-defined functions. Built-in functions include mathematical operations, logic operations, string operations, and file operations. User-defined functions and variables may be defined ``on the fly'' or via files containing`rpn`commands.The command

`rpn`*filename*invokes the`rpn`shell with*filename*as a initial command file. Typically, this file would contain instructions for a computation. Prior to execution of any files named the commandline,`rpn`first executes the instructions in the file named by the environment variable`RPN_DEFNS`, if it is defined. This file can be used to store commonly-used variable and function definitions in order to customize the`rpn`shell. This same file is read by`rpnl`and all of the SDDS toolkit programs that use the`rpn`calculator module. An example of such a file is included with the code.As with any RPN system,

`rpn`uses stacks. Separate stacks are maintained for numerical, logical, string data, and command files.`rpnl`is essentially equivalent to executing`rpn`, typing a single command, then exiting. However,`rpnl`has the advantage that it evaluates the command and prints the result to the screen without any need for user input. Thus, it can be used to provide floating point arithmetic in shell scripts. Because of the wide variety of operations supported by the`rpn`module and the availability of user-defined functions, this is a very powerful feature even for command shells that include floating point arithmetic.Built-in commands may be divided into four broad categories: mathematical operations, logical operations, string operations, and file operations. (There are also a few specialized commands such as creating and listing user-defined functions and variables; these will be addressed in the next section). Any of these commands may be characterized by the number of items it uses from and places on the various stacks.

- Mathematical operations:
- Using
`rpn`variables:

The`sto`(store) function allows both the creation of`rpn`variables and modification of their contents.`rpn`variables hold double-precision values. The variable name may be any string starting with an alphabetic character and containing no whitespace. The name may not be one used for a built-in or user-defined function. There is no limit to the number of variables that may be defined.For example,

`1 sto one`would create a variable called`one`and store the value 1 in it. To recall the value, one simply uses the variable name. E.g., one could enter`3.1415925 sto pi`and later enter`pi`to retrieve the value of . - Basic arithmetic:
`+ - * / sum`

With the exception of

`sum`, these operations all take two values from the numeric stack and push one result onto the numeric stack. For example,`5 2 -`would push 5 onto the stack, push 2 onto the stack, then push the result (3) onto the stack.`sum`is used to sum the top`n`items on the stack, exclusive of the top of the stack, which gives the number of items to sum. For example,`2 4 6 8 4 sum`would put the value`20`on the stack. - Basic scientific functions:
`sin cos acos asin atan atan2 sqrt sqr pow exp ln`

With the exception of

`atan2`and`pow`, these operations all take one item from the numeric stack and push one result onto that stack.`sin`and`cos`are the sine and cosine functions, while`asin`,`acos`, and`atan`are inverse trigonometic functins.`atan2`is the two-argument inverse tangent:`x y atan2`pushes the value with the result being in the interval .`sqrt`returns the positive square-root of nonnegative values.`sqr`returns the square of a value.`pow`returns a general power of a number:`x y pow`pushes onto the stack. Note that if`y`is nonintegral, then`x`must be nonnegative.`exp`and`ln`are the base-e exponential and logarithm functions. - Special functions:
`Jn Yn cei1 cei2 erf erfc gamP gamQ lngam``Jn`and`Yn`are the Bessel functions of integer order of the first and second kind[7]. Both take two items from the stack and place one result on the stack. For example,`x i Jn`would push onto the stack. Note that is singular at x=0.`cei1`and`cei2`are the 1st and 2nd complete elliptic integrals. The argument is the modulus k, as seen in the following equations (the functions K and E are those used by Abramowitz[7]).

`erf`and`erfc`are the error function and complementary error function. By definition, is unity. However, for large x,`x erf 1 -`will return 0 while`x erfc`will return a small, nonzero value. The error function is defined as[7]:

Note that is the area under the normal Gaussian curve between and .`gamP`and`gamQ`are, respectively, the incomplete gamma function and its complement [7]:

These functions take two arguments; the 'a' argument is place on the stack first.`lngam`is the natural log of the gamma function. For integer arguments,`x lngam`is . The gamma function is defined as[7]:

- Numeric stack operations:
`cle n= pop rdn rup stlv swap view ==``cle`clears the entire stack, while`pop`simply removes the top element.`==`duplicates the top item on the stack, while`x n=`duplicates the top x items of the stack (excluding the top itself).`swap`swaps the top two items on the stack.`rdn`(rotate down) and`rup`(rotate down) are stack rotation commands, and are the inverse of one another.`stlv`pushes the stack level (i.e., the number of items on the stack) onto the stack. Finally,`view`prints the entire stack from top to bottom. - Random number generators:
`rnd grnd``rnd`returns a random number from a uniform distribution on .`grnd`returns a random number from a normal Gaussian distribution. - Array operations:
`mal [ ]``mal`is the Memory ALlocation command; it pops a single value from the numeric stack, and returns a ``pointer'' to memory sufficient to store the number of double-precision values specified by that value. This pointer is really just an integer, which can be stored in a variable like any other number. It is used to place values in and retrieve values from the allocated memory.`]`

is the memory store operator. A sequence of the formresults in*value**index**addr*]*value*being stored in the*index*position of address*addr*.*value*,*index*, and*addr*are consumed in this operation. Indices start from 0.Similarly,

value pushes the value in the*index**addr*[*index*position of address*addr*onto the stack.*index*and*addr*are consumed in this operation. - Miscellaneous:
`tsci int``tsci`allows one to toggle display between scientific and variable-format notation. In the former, all numbers are displayed in scientific notation, whereas in the later, only sufficiently large or small numbers are so displayed. (See also the`format`command below.)`int`returns the integer part of the top value on the stack by truncating the noninteger part.

- Using
**Logical operations**:`! && < == > ? $ vlog ||`

- Conditional execution:
`?`The question-mark operator functions to allow program branching. It is meant to remind the user of the C operator for conditional evaluation of expressions. A conditional statement has the form`?`*executeIfTrue*:*executeIfFalse*$

The colon and dollar sign function as delimiters for the conditionally-executed instructions. The`?`operator pops the first value from the logic stack. It branches to the first set of instructions if this value is ``true'', and to the second if it is ``false''. - Comparisons:
`< == >`

These operations compare two values from the numeric stack and push a value onto the logic stack indicating the result. Note that the values from the numeric stack are left intact. That is, these operations push the numeric values back onto the stack after the comparison. - Logic operators:
`&& || !`

These operators consume values from the logic stack and push new results onto that stack.`&&`

returns the logical and of the top two values, while`||`returns the logical or.`!`is the logical negation operator. - Miscellaneous:
`vlog`

This operator allows viewing the logic stack. It lists the values on the stack starting at the top. - Examples:

Suppose that a quantity is tested for its sign. If the sign is negative, then have the conditional return a -1, if the sign is positive then return a +1.Suppose we are running in the rpn shell and that the quantity 4 is initially pushed onto the stack. The command ``

`0 < ? -1 : 1 $`

'' that accomplishes the sign test will be executed as follows.command stack logical stack 0 0 stack empty 4 < 0 false <-- new value 4 ? 1 : -1 $ 1 stack empty 0 4

`0 < pop pop ? -1 : 1 $`

'', where the pop commands would eliminate the 0 and 4 from the stack before the conditional is executed.If the command is executed with rpnl command in a C-shell, then the $ character has to be followed by a blank space to prevent the shell from interperting the $ as part of variable:

C-shell

`>`

rpnl`"4 0 < pop pop ? -1 : 1 $ "`

If the command is executed in a C-shell sddsprocess command to create a new column, then we write:

sddsprocess <infile> <outfile> \ -def=col,NewColumn,"OldColumn 0 < pop pop ? -1 : 1 $ "

If the sddsprocess command is run in a tcl/tk shell, the $ character can be escaped with a backslash as well as with a blank space:

sddsprocess <infile> <outfile> \ "-def=col,NewColumn,OldColumn 0 < pop pop ? -1 : 1 \$"

- Conditional execution:
**String operations**:`"" =str cshs format getformat pops scan sprf vstr xstr`

- Stack operations:
`"" =str pops vstr`

To place a string on the string stack, one simply encloses it in double quotation marks.`=str`duplicates the top of the string stack.`pops`pops the top item off of the string stack.`vstr`prints (views) the string stack, starting at the top. - Format operations:
`format getformat``format`consumes the top item of the string stack, and causes it to be used as the default printf-style format string for printing numbers.`getformat`pushes onto the string stack the default printf-style format string for printing numbers. - Print/scan operations:
`scan sprf``scan`consumes the top item of the string stack and scans it for a number; it pushes the number scanned onto the string stack, pushes the remainder of the string onto the string stack, and pushes true/false onto the logic stack to indicate success/failure.`sprf`consumes the top of the string stack to get a sprintf format string, which it uses to print the top of the numeric stack; the resulting string is pushed onto the string stack. The numeric stack is left unchanged. - Other operations:
`cshs xstr``cshs`executes the top string of the stack in a C-shell subprocess; note that if the command requires terminal input,`rpn`will hang.`xstr`executes the top string of the stack as an rpn command.

- Stack operations:
**File operations**:`@ clos fprf gets open puts`

- Command file input:
`@`

The`@`operator consumes the top item of the string stack, pushing it onto the command file stack. The command file is executed following completion of processing of the current input line. Command file execution may be nested, since the files are on a stack. The name of the command file may have options appended to it in the format. Presently, the only option recognized is 's', for silent execution. If not present, the command file is echoed to the screen as it is executed.*filename*,*option*Example:

`"commands.rpn,s" @`would silently execute the`rpn`commands in the file`commands.rpn`. - Opening and closing files:
`clos open``open`consumes the top of the string stack, and opens a file with the name given in that element. The string is of the format, where*filename*,*option**option*is either 'w' or 'r' for write or read.`open`pushes a file number onto the numeric stack. This should be stored in a variable for use with other file IO commands. The file numbers 0 and 1 are predefined, respectively, as the standard input and standard output.`clos`consumes the top of the numeric stack, and uses it as the number of a file to close. - Input/output commands:
`fprf gets puts`

These commands are like the C routines with similar names.`fprf`is like fprintf; it consumes the top of the string stack to get a fprintf format string for printing a number. It consumes the top of the numeric stack to get the file number, and uses the next item on the numeric stack as the number to print. This number is left on the stack.`gets`consumes the top of the numeric stack to get a file number from which to read. It reads a line of input from the given file, and pushes it onto the string stack. The trailing newline is removed. If successful,`gets`pushes true onto the logic stack, otherwise it pushes false.`puts`consumes the top of the string stack to get a string to output, and the top of the numeric stack to get a file number. Unlike the C routine of the same name, a newline is*not*generated. Both`puts`and`fprf`accept C-style escape sequences for including newlines and other such characters.

- Command file input:
**author:**M. Borland, ANL/APS.

- Mathematical operations: