#### 4.93 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 \*‘

Use 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 atan(y∕x) 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 xt 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. Both take two items from the stack and place one result on the stack. For example, x i Jn would push Ji(x) onto the stack. Note that Y n(x) 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).  erf and erfc are the error function and complementary error function. By definition, erf(x) + erfc(x) 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: Note that erf(x∕ ) is the area under the normal Gaussian curve between -x and x.

gamP and gamQ are, respectively, the incomplete gamma function and its complement : 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 ln((x - 1)!). The gamma function is defined as: • 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 [0,1]. 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 form value index addr ] results in value being stored in the index position of address addr. value, index, and addr are consumed in this operation. Indices start from 0.

Similarly, index addr [ value pushes the value in the 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.

• 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

In order to keep the stack small, the command should be written “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 \$ "

which is similar to the rpnl command above.

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 \\$"

Note that the double quotes enclose the whole command argument, not just the sub-argument.

• 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.
• string comparison opertions: streq compares if two strings are the same. strgt compares if left string is greater than right string. strlt compares if left string is less than right string. strmatch compares if left string matches right string pattern.
• 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. strlen returns the lenght of a string.
• 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 filename,option. 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.

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 filename,option, where 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.

• author: M. Borland, ANL/APS.