Go to the previous, next section.
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 ... 2
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-orientated 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 2
.
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@example
SET vec = { list 2
For example@example
SET r = 0,10
is equivalent to@example
SET r = { 0 1 2 3 4 5 6 8 9 10 2
In fact, { list 2
is an expression, so
SET vec = 2*{1 3 12
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 2
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 42
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@example
SET $0 = $1**$2
then the command@example
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 2 + { x y z 2results 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 strthe test will fail as
'b' == str
is the 4-element vector
{ 0 1 0 1 2
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
(@xref{IMAGE}) defined, you can extract a set of values
using the expression IMAGE(expr,expr)
, where the two expr
s
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@example SET vec[ expr ] = expr or@example SET vec = WORD(expr) or@example SET DIMEN(vec) = number or@example SET vec = expr1 IF(expr2) or@example SET vec = expr1 ? expr2 : expr3 The 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 2command, 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,@example
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.
Go to the previous, next section.