Next: array() Up: MacAnova Help File Previous: arimahelp()   Contents

# arithmetic

Usage:
 ```a + b, a - b, a * b, a / b, a %% b, a^b, -a, +a a <-+ b, a <-- b, a <-* b, a <-/ b, a <-%% b, a <-^ b ```

Keywords: syntax, operations, missing values
```There are 8 operators for doing arithmetic with MacAnova variables.

Operators        Precedence  Meaning
a + b               9      Addition (sum of a and b)
a - b               9      Subtraction (difference of a and b)
a * b              10      Multiplication (product of a and b)
a / b              10      Division (a divided by b)
a %% b             10      Modular division (see below)
-a                12      Unary minus ((-1)*a)
+a                12      Unary plus ((+1)*a))
a ^ b or a ** b         13      Exponentiation (a to the b-th power)

(Level 11 is the precedence level of matrix multiplication; see
topic 'matrices'.)

The arithmatic operators are all element-wise operations: When a and b
are vectors, matrices, or arrays with identical dimensions, then c <- a
OP b, computes a result of the same size and shape such that c[i,j,...]
is a[i,j,...] OP b[i,j,...], where OP is one of these operators.
Similarly (-a)[i,j,...]  is -(a[i,j,...]).

Cmd> vector(1,3,2,0) + vector(8,-1,2,9)
(1)           9           2           4           9

Cmd> -vector(1,3,2,0)
(1)          -1          -3          -2           0

See below for how they work when a and b do not have identical
dimensions.

Modular division x %% y computes the non-integral part of x / y or zero
if y exactly divides x.  It is implemented as x %% y = x - y*floor(x/y).
In particular, 17 %% 4 is 1, -17 %% 4 is 3, and -17 %% -4 is -1.  a %% 0
is always MISSING.

When a is not zero, a / 0 yields has value MISSING.  However, 0 / 0 has
value 0.  This can be a useful convention when a and b have the same
pattern of zero elements.

When p is not an integer, a^p (or a**p) is defined to be
sign(a)*abs(a)^p and a warning message is printed when a < 0.  0^p is
zero when p > 0 or MISSING when p < 0.  a^0 is always 1, even when a =
0.

LOGICAL variables and constants may be used in arithmetic expressions
and comparisons.  Values True and False are translated as 1 and 0,
respectively.  In particular 1*w converts a LOGICAL vector, matrix, or
array w to a numerical vector, matrix or array of 0's and 1's..

When any elements of a and/or b are MISSING, so is the corresponding
element of a OP b and a warning message is printed.

When any element of the result is too large a number to be represented
in the computer (for example, 1e300/1e-300), the result is set to
MISSING and a warning message printed.

See subtopic 'options:"warnings"' for information on option 'warnings'
which you can set to suppress warning messages.

The precedence level in the list of operators affects the order of
evaluation when there is more than one operator in an expression.  An
operator with higher precedence is evaluated before one with lower
precedence.  For example, 3 + 2 * 4 is interpreted as 3 + (2*4) = 11
because '*' has higher precedence than '+'.  See topic 'precedence' for
complete information on the order of evaluation.

Behavior of arithmetic, logical, and bit operations
when operands differ in size.

Scalar operand:
A scalar operand (single number, all dimensions 1) is combined or
compared with all the elements of the other operand.  For example, x -
2 subtracts 2 from each element of x and x == 2 compares every element
with 2.  The result has the same dimensions and labels as the other
operand.

When both operands are scalars, the result is unlabeled unless both
operands have the same number of dimensions and the same labels.  If
the number of dimensions is different, the result has the larger
number of dimensions.

Column vector operand and matrix operand:
When a column vector of length m (m by 1 matrix or vector of length m)
is combined or compared with a m by n matrix, it is combined or
compared with each column of the matrix to yield a m by n matrix.  For
example, when a is 3 by 6, run(3) + a adds 1 to row 1, 2 to row 2, and
3 to row 3, and a != vector(1,1,2) compares elements in rows 1 and 2
with 1 and elements in row 3 with 2.

Row vector operand and matrix operand:
When a 1 by n matrix (a row vector) is combined or compared with a m
by n matrix, the row vector is combined or compared with each row of
the matrix.  For example, if x is a matrix

Cmd> xbar <- sum(x)/nrows(x); resids <- x - xbar

subtracts the average of the rows of x from every row, since sum(x)
computes a row vector with the same number of columns as x.  This
would not work if xbar were computed as xbar <- describe(x,mean:T)
because describe() computes it as a vector, not a row vector.
However, in this case, resids <- x - xbar' would work.

Row vector operand and column vector operand:
When a column vector of length m is combined or compared with a row
vector of length n, the result is the m by n matrix obtained by
combining each element of the column vector with each element of the
row vector, what might be called an outer product, outer sum, etc.
Examples
Cmd> run(2)/run(3)'
(1,1)           1         0.5     0.33333   [1/1  1/2   1/3]
(2,1)           2           1     0.66667   [2/1  2/2   2/3]

Cmd> run(2) <= run(3)'
(1,1) T       T       T                     [1<=1  1<=2   1<=3]
(2,1) F       T       T                     [2<=1  2<=2   2<=3]

Structure operand(s)
When one of the operands is a structure, each of its components is
combined with the other argument, following the same rules of
compatibility just described, producing a structure with the same
shape as the structure argument.  When both arguments are structures,
they must have the same number of components at every level and the
corresponding components are combined.  NULL components are permitted
as long as they appear in both operands in the same places.
Example:
Cmd> structure(x:run(2),y:run(4),z:NULL)/structure(run(3)',4,NULL)
component: x
(1,1)           1         0.5     0.33333
(2,1)           2           1     0.66667
component: y
(1)        0.25         0.5        0.75           1
component: z
(NULL)

Arithmetic assignment operators
Operators '<-+', '<--', '<-*', '<-/', '<-^', '<-**', and '<-%%' are
useful for modifying a variable.  They are best illustrated by example.

a <-+ 3      is equivalent to a <- a + 3
a <-%% b     is equivalent to a <- a %% b
a <-^ -1     is equivalent to a <- a^(-1)

To avoid ambiguity, '<-+' and '<--' must be followed by at least one
space so that, for example 'a <-- 3' means 'a <- a - 3' instead of 'a <-
-3'.

You can't modify parts of a vector, matrix or array using assignment
operators.  For example, a[1,2] <-/ 3 is illegal. Use a[1,2] <-
a[1,2]/3.

See topic 'precedence' for information on what happens when more than
one of these operators is used in an expression.

See also topics 'logic', 'structures', 'syntax', 'bit_ops'.
```

Gary Oehlert 2003-01-15