The basic unit of data in SM is the `vector', a named set of one or more numbers or strings. There is no limit to the number of vectors that may be defined. SM allows the user to read vectors from files or define them from the keyboard, to plot them and to perform arithmetic operations upon them. SM's string-valued vectors are less generally useful, but can be used for such purposes as labelling points on a graph.
To read a vector vec from a column of numbers in a file, where the
filename has been specified
using DATA and, possibly, the range of lines in the file to be used
has been specified using the
LINES command, use READ vec nn where nn is the column number,
or READ { vec1 n1 vec2 n2 ... } to read many vectors.
It is also possible to read a row, using READ ROW vec nn, where nn is
the row number in the file. See READ for how to read a
string-valued vector.
Instead of using simple column-oriented input
it is possible to specify a format like those used by C's scanf
functions (Fortran formats are not supported); if you provide your own
format string you can only read numbers.
For example, if your data file has lines like
1:12:30 -45:30:11you could read it with
read '%d:%d:%d %f:%f:%f' { hr min sec deg dmin dsec }.
A vector may also be defined as SET vec = x1,x2,dx to take on
the values x1,x1+dx,...,x2, where dx defaults to 1
if omitted. If a scalar is
encountered where a vector is expected, it is promoted to be a vector
of the appropriate dimension; all other dimension mismatches are
errors. Example:
SET value = 5 SET x = 0, 50, 2 SET y = x SET y = x*0 + value SET y[0] = 2*pi SET y = value SET x=0,1,.1 SET y=IMAGE(x,1.5) SET s=str SET s='str' SET s[0]=1.23 SET x=1.23 SET s=x SET s=STRING(x)will define a scalar,
value, with a value of 5, then define a vector,
x, with 26 elements, valued 0, 2, 4, 6,..., 50, then define another
vector, y with size 26 and the same values as x,
set all 26 elements of y to have the value 5,
set the first element of y to be 2 pi,
set y
to be a vector with one element with value 5, and finally
set y to be a vector with the values taken from a horizontal
cross-section from 0 to 1 through the current image. Unless a vector
str is defined SET s=str is an error; to make s a
string-valued vector use SET s='str'.
SET s[0]=1.23 makes s[0] have the value "1.23" (a string),
as s is now a pre-existing string vector.
An arithmetic vector x is then
defined, and s is redefined as an arithmetic vector too -- you must
be careful when dealing with string vectors! Finally, we explicitly
convert an arithmetic vector to a string-valued one with the STRING
operator.
This is a somewhat
contrived example, designed mainly to illustrate the convenience of the
SET command. The ability to set particular elements is mostly
used in macros such as smirnov2 which calculates the
Kolmogorov-Smirnov statistic from a pair of vectors.
If you don't have many data points, rather than type them into a file, and use
READ vec nn to define a vector, you can use the command
SET vec = { list }
For example
SET r = 0,10is equivalent to
SET r = { 0 1 2 3 4 5 6 8 9 10 }
In fact, { list } is an expression, so
SET vec = 2*{1 3 1} is also legal.
If the first element of a list is a word, the vector is taken to be
string-valued: SET s={ William William Henry Steven } defines a
4-element string vector, or you can use a string in quotes:
SET s=<'1' 2 3 4> (if you used SET s={'1' 2 3 4} the first
element would be '1' rather than 1).
Once a vector is defined, you can write it to a file for later study using the
PRINT command.
A scalar may be an integer, a floating point number, a scalar
expression, DIMEN(vector), or WORD[expr]. The last two are the
dimension of a vector, and an element of the vector with expr a
scalar subscript. Note that subscripts start at 0 and that [ ]
`not' () are used to subscript variables.
The expression WORD[expr] is in fact allowed even if expr
is not a scalar, in which case the result is a vector with the same
dimension as expr, and with the values taken from WORD in
the obvious way.
Once vectors are defined, they may be combined into expressions using
the operators +, -, *, /, **,
CONCAT and the
functions COS(), SIN(), TAN(), ACOS(),
ASIN(), ATAN(), ATAN2(), ABS(), DIMEN(), INT(), LG(), EXP(), LN(),
SQRT(), STRING(), STRLEN(), and
SUM().
The meaning of most of these is obvious, ATAN2 is like ATAN
but takes two arguments, x and y and returns an angle in the
proper sector.
DIMEN returns the number of
elements in a vector, SUM gives the sum of all the elements,
CONCAT concatenates two vectors,
INT gives the integral part of a vector, STRING
converts a number to a string, and STRLEN gives the length of a string
(in plotting units, not just the number of characters). STRING uses
the same code as the axis-labelling routines, so FORMAT can be used
to modify its behaviour; whether the x- or y-axis formats is used depends
on whether the label is more nearly horizontal or vertical.
An example would be
set x=3.08e16 define s (string(x)) relocate 0.5 0.5 putlabel 5 $sThe precedence and binding are as for C (or Fortran), and may be altered by using parentheses (
CONCAT has a binding just below + and -).
All of these operators work element by element, so
y = 2 + sin(x)is interpreted as
If there is a size mismatch the operation will only be carried out up to the length of the shorter vector and a message is printed; if
VERBOSE is 1 or more, the line where the error occurred will
be printed too.
The constant PI is predefined.
You can also use WORD([ expr [ , ... ]]) as part of
an expression, where WORD is a macro taking zero or more arguments.
It is a bit dishonest to write the arguments as expr, as in fact they
must be either the names of vectors or numbers.
Suppose we define a macro pow with two arguments as
SET $0 = $1**$2then the command
SET y = 10 + 2*pow(x,3)is equivalent to
SET y = 10 + 2*x**3.
In addition to these arithmetic operations, there are also logical
operators == (equals), != (not equals),
>, >=, <, <=, &&
(logical and), and || (logical or). The meanings of the symbols are the
same as in C, and as in C the value 0 is false while all other values are true.
String vectors may only be concatenated, added, or tested for (in)equality. Adding two string-valued vectors concatenates their elements, so
{ a b c } + { x y z }
results in the vector ax by cz.
Testing equality for string vectors seems to cause some confusion. Consider
set str=<'a' b c d>
if('a' == 'str') { # test if the strings `a' and `str' are equal
if('a' == str) { # test if the string `a' equals the vector `str'
if(a == str) { # test if the vector `a' equals the vector `str'
The second of these tests will succeed, but if you then try
if('b' == str) { # try to see if `b' is an element of str
the test will fail as 'b' == str is the 4-element vector
{ 0 1 0 1 } and only its first element is used by the if test;
what you want is
if(sum('b' == str)) { # is `b' an element of str?
There are also a number of less mathematical operations. If you have an
IMAGE (see section Image) defined, you can extract a set of values
using the expression IMAGE(expr,expr), where the two exprs
give the coordinates where the values are desired. Note that this may be
used as a way of reading large data files that are stored unformatted.
The expression HISTOGRAM(expr : expr) can be used to convert a
vector into a histogram. The second expression is taken to be the
centres of the desired bins: bin boundaries are taken at the mean points
(and points in the first expression lying on a boundary are taken to
fall into the lower bin. Note the use of `:' not `,').
Vectors may be assigned to, using the syntax
SET vec = expror
SET vec[ expr ] = expror
SET vec = WORD(expr)or
SET DIMEN(vec) = numberor
SET vec = expr1 IF(expr2)or
SET vec = expr1 ? expr2 : expr3The first form sets
vec to have the value expr, element by
element, vec is the name of the new vector. The form
vec[expr] may be used to assign to an element of a vector, as usual
the index starts at 0. Before you can use SET to assign values to the
elements of a vector, you must create it using one of the other forms
of the SET command.
If you want to define a vector to which you will subsequently assign values
using SET vec[ expr ] = expr, you may use SET DIMEN(vec) = number
which declares vec to be a vector of size number, and
initialises it to zero. You can optionally supply a qualifier to the
number, either a .f (the default), or a .s to
specify that the vector is string valued.
If the IF clause is present, only those
elements of expr1 for which the corresponding element of expr2 is
true
(non-zero) are copied into vec; in general vec will have a
smaller dimension than expr1. The last SET statement (with ?:)
again borrows
from C. If expr1_i is true, then vec_i is set
to expr2_i, otherwise it is
set to expr3_i. In this form of conditional assignment, the dimension
of vec is the same as that of the right hand side. It may look
strange, but it can be just what you want.
Each vector also has a help field, which may be used to provide a string describing the vector. The field is set by
SET HELP vec strand viewed by
HELP vecIf
VERBOSE is one or more, if a vector is arithmetic or string
will also be noted. Vectors may be printed using the
PRINT [ file ] [format] { vec1, ..., vecn }
command, where if the optional
file is missing, the values are typed to the keyboard; if the
optional format is omitted, a suitable one will be chosen for you.
Any combination of string- and arithmetic-vectors may be printed.
If a value
exceeds 1e36, it is printed as a *. This is consistent with the
convention used in reading data that a `missing' number is represented
as 1.001e36; see READ for details.
Vectors may be deleted with the command
DELETE vecand listed with the command
LIST SETVectors are listed in ascii order along with their dimension, and any help string specified using the
SET HELP command
An IF clause has been
added to the plotting commands, to allow only those elements of a
vector which satisfy some condition to be plotted, for example
POINTS x y IF(z > 3*x)Of course, you could have used the
IF command and the regular
POINTS command if you had preferred. In fact,
CONNECT x y IF(z > 3*x)isn't quite the same as
SET log = z > 3*x SET x = x IF(log) SET y = y IF(log) CONNECT x yas the former will only connect contiguous points.