Programming Gri
1: Introduction
2: Simple example
3: Fancy example
4: Running Gri
5: Programming Gri
6: General Issues
7: X-Y Plots
8: Contour Plots
9: Image Plots
10: Examples
11: Handling Data
12: Gri Commands
13: Gri Extras
14: Evolution of Gri
15: Installing Gri
16: Gri Bugs
17: System Tools
18: Acknowledgments
19: License
20: Newsgroup
21: Concept Index
|
5.8: Built-in rpn Calculator
Gri can do simple mathematics on numbers. The syntax is reverse-polish
notation (`rpn '), which is used in some calculators. Most users
can learn rpn in a few minutes, so don't worry if you don't know RPN
yet.
syntax rpn expressions can be used anywhere Gri expects a number.
RPN expressions start with a opening curly brace (`{ ') which is
immediately followed by the word `rpn '. rpn expressions end with a
closing curly brace (`} '). Instead of `set x size 10 ' you
could write `set x size {rpn 20 2 /} ', where the expression
`{rpn 20 2 /} ' tells Gri to insert the number 20 onto a stack,
then insert the number 2 above it on the stack, and then divide the top
two items on the stack. The following are equivalent:
set x size {rpn 20 2 /} # 10 = 20/2
set x size {rpn 30 2 / 5 -} # 10 = (30/2-5)
set x size {rpn pi 3.1415 / 10 *} # 10 = 10*pi/pi
|
RPN operations can be divided roughly into the following groups.
5.8.1: Stack Operators
Stack operators manipulate or display the stack. `pop ' removes the
top item from the stack, `dup ' duplicates the top item on the
stack, `exch ' reorders the top two items on the stack,
`pstack ' prints the items on the stack (without changing the
stack), `roll_right ' rolls the items to the right and
`roll_left ' rolls the items to the left, e.g.
# following yields [4 1 2 3] on the stack
{rpn 1 2 3 4 roll_right pstack}
|
5.8.2: Rpn function Operators
`rpnfunction ' operators are user-defined operators. The parser
replaces any such operator with the user-defined rpn expression. The
`rpnfunction ' operators are both general and powerful. An
`rpnfunction ' may be composed of any legal primitive rpn constructs
or even other legal `rpnfunction ' constructs. For details,
see Rpnfunction.
5.8.3: rpn constants
Gri knows the values `pi ' = 3.141...,
`e ' = 2.718.... These are defined near the end of the startup
file `gri.cmd' as `rpnfunction ' commands see Rpnfunction.
To add more builtin constants, follow the same `rpnfunction '
procedure.
5.8.4: Testing for Existence of Files, Variables, and Synonym
The `defined ' operator checks whether synonyms
or variables are defined, e.g.
.var_exists. = {rpn ".var." defined}
.syn_exists. = {rpn "\\syn" defined}
|
Note the double-backslash used in the synonym case, which is
required to prevent Gri from substituting the synonym value into the string.
To test for the existence of files, use the operating system, e.g.,
testing for existence of unix file called `A':
.file_exists. = {rpn \
"test -r A && echo 1 || echo 0" system
"1" ==}
|
Another way to do this is
\file_exists = "\$(test -r A && echo 1 || echo 0)"
|
5.8.5: Binary Operators
Binary operators act on the top two items on the stack. With most
binary operators, the result is to replace these two items with a single
new item. For example, `{rpn 1 2 /} ' yields 0.5.
Some binary operators replace the top two items with two new items.
Examples are the pairwise conversion operators `xyusertocm ' and
`xycmtouser '.
List of binary operators:
`+ ',
`- ',
`* ',
`/ ',
`< ' (e.g., `1 2 < ' yields 0 since 2 is not less than 1),
`<= ',
`> ', (e.g., `0 10 > ' yields 1 since 10 is greater than 0),
`>= ',
`== ',
`& ',
`| ',
`power ' (e.g., `2 3 power ' yields 8),
`exch ' (exchange two items on top of stack),
`strcat ' (add top string to end of string before it, then delete top string),
`= ' (assign string value to synonym or numerical value to variable; see example below),
`sup ' picks the larger of two values on stack,
`inf ' picks the smaller of two values on the stack,
`remainder ' yields the remainder from division of two values on the
stack, using the C-language subroutine `fmod ', which is similar to
`mod ' in fortran. See the manuals on these functions, and the
examples below, for details on sign of the result compared to the two
input numbers.
Notes:
-
String comparison operators are done with the operators `
== '
and `!= ', as in the example below (see About Synonyms.).
if {rpn "\item" "S" ==}
show "The item is 'S'"
end if
|
-
Assignment to variables and synonyms:
# Variable assignment. Note that the '=' operator
# removes the last two items from the stack, so
# this whole line translates to a blank line,
# which gri then ignores.
{rpn 2 pi * ".two_pi." =}
# String assignment; note double quote needed,
# so Gri won't try to substitute for an
# existing synonym.
{rpn "Hi there" "\\politeness" =}
|
5.8.6: Unary Operators
First, an operation that does not require even a single item on the
stack: random number generation. Random numbers are given by
`rand '.
Unary operators replace the last item on the stack with another item.
For example, the `sin ' operator takes the sine of the number on the
top of the stack; e.g., `{rpn 45 sin} ' yields sin of 45 degrees.
List of unary operators:
`ismissing ' (=1 if value is current missing value, 0 otherwise),
`abs ',
`atof ' (converts string to number),
`! ',
`acosh ',
`asinh ',
`atanh ',
`acos ',
`asin ',
`atan ',
`sin ',
`cos ',
`tan ',
`cosh ',
`sinh ',
`tanh ',
`sqrt ',
`system ' (replaces string with output when that string is fed to the operating system),
`log ',
`ln ',
`exp ',
`exp10 ',
`ceil ',
`floor ',
`cmtopt ',
`pttocm ',
`xusertocm ',
`yusertocm ',
`xcmtouser ',
`ycmtouser ',
`width ' (e.g., `"hi" width ' yields the width of this string in cm),
`ascent ' (e.g., `"hi" ascent ' yields the ascent above the baseline in cm),
`descent ' (e.g.,m `"hi" descent ' yields the descent below the baseline in cm),
`pop ' (removes top item from stack),
`dup ' (duplicates top item on stack).
5.8.7: Manipulation of Columns etc
5.8.7.1: Columns
Individual data in the `x ', `y ', `z ', `u ', `v '
and `weight ' columns can be accessed with the `@ ' operator.
The first point has index 0. Examples:
show "first x is " {rpn x 0 @ }
show "last x is " {rpn x ..num_col_data.. 1 - @ }
show "and here are all the data:"
.i. = 0
while {rpn .i. ..num_col_data.. >}
show {rpn x .i. @ }
.i. += 1
end while
|
The mean value is available from the `mean ' operator (e.g.,
`.xmean. = {rpn x mean } ', while the standard deviation is given
by `stddev ' and the minimal and maximal values are given by
`min ' and `max '.
The area under the curve y=y(x) is found by `{rpn y x area } ',
defined by
`0.5 * sum ( (y[i] + y[i-1]) * (x[i] - x[i-1]) ) '
for `i ' ranging from 1 to `..num_col_data.. '-1.
5.8.7.2: Grid
Grid data can be accessed with e.g. `{rpn grid min } ',
`{rpn grid max } ', and `{rpn grid mean } '.
The value of the grid at a given `(.x.,.y.) ' coordinate may be
found by by e.g. `{rpn grid .x. .y. interpolate} '. The
interpolation scheme is the same as that used in converting grids to
images.
5.8.8: rpn Examples
Here are some reverse-polish expressions and the corresponding algebraic
interpretations:
- `
{rpn 1 2 + 10 / } '
= (1+2)/10
- `
{rpn .a. .b. + .c. + .d. / } '
= (.a.+.b.+.c.)/.d.
- `
{rpn e 2 / } '
= e/2 (Gri knows values of ``e'' and ``pi'')
- `
{rpn 23 sin 100 * 12 cos + } '
= cos(12) + 100sin(23)
- `
{rpn 5 2 power } '
= 25
- `
{rpn 2 log exp } '
= exp(log 2)
- `
{rpn 2 ln exp10 } '
= 10^ln2
- `
{rpn 1.7 floor } '
= 1 (rounds down to nearest integer. Note that the floor of -1.7 is -2)
- `
{rpn 10.1 2 remainder } '
= 0.1 (remainder of 10.1 after division by 2; see C function `remainder(x,y) ')
- `
{rpn -10.1 2 remainder } '
= -0.1
- `
{rpn -10.1 -2 remainder } '
= -0.1
- `
{rpn .num. 10 > } '
= 1 if 10 exceeds .num., or 0 otherwise
NOTES:
-
The units of `
sin ', `cos ', etc, are degrees, not radians.
-
The scales of the plot are accessible to `
rpn '. For example, with
the command
you draw the indicated string at the indicated location in
user coordinates. To put it 0.15 centimetres to the right of this
location and 0.1 centimetres lower, you could do as follows:
draw label "\label" at \
{rpn .x. xusertocm 0.15 + xcmtouser} \
{rpn .y. yusertocm 0.10 - ycmtouser}
|
(Note that the x and y scales have individual translations from "user"
to "cm" coordinates.)
-
Some conversion factors are built into `
rpn '; `cmtopt '
converts from centimetres to points (by dividing by 28.45; the
conversion factor to inches is 72.27) while `pttocm ' converts from
points to centimetres. For example, here is how to label a data curve
with a label placed near the last y-value of the data set:
draw curve
.y. = {rpn ..lasty.. yusertocm 0.5 - ycmtouser}
draw label "Smoothed" at ..lastx.. .y.
|
|