#include <vectmath.h> CLRV(v) v = 0 i UNITV(v,j) v = delta i ij SETV(v,u) v = u i i ADDV(v,u,w) v = u + w i i i SUBV(v,u,w) v = u - w i i i MULVS(v,u,s) v = u s i i DIVVS(v,u,s) v = u / s i i DOTVP(s,v,u) s = v u i i dotvp(v,u) v u i i ABSV(s,v) s = sqrt(v v ) i i absv(v) sqrt(v v ) i i DISTV(s,v,u) s = sqrt((v - u ) (v - u )) i i i i distv(v,u) sqrt((v - u ) (v - u )) i i i i CROSSVP(s,v,u) s = eps v u [only in 2-D] ij i j CROSSVP(v,u,w) v = eps u w [only in 3-D] i ijk j k CLRM(p) p = 0 ij SETMI(p) p = delta ij ij SETM(p,q) p = q ij ij TRANM(p,q) p = q ij ji ADDM(p,q,r) p = q + r ij ij ij SUBM(p,q,r) p = q - r ij ij ij MULM(p,q,r) p = q r ij ik kj MULMS(p,q,s) p = q s ij ij DIVMS(p,q,s) p = q / s ij ij MULMV(v,p,u) v = p u i ij j OUTVP(p,v,u) p = v u ij i j TRACEM(s,p) s = Tr(p) tracem(p) Tr(p) SETVS(v,s) v = s i ADDVS(v,u,s) v = u + s i i SETMS(p,s) p = s ij MULVV(w,v,u) w = v * u i i i SADDV(v,u) v = v + u i i i SSUBV(v,u) v = v - u i i i SMULVS(v,s) v = v * s i i SDIVVS(v,s) v = v / s i i SMULVV(v,u) v = v * u i i i real s; vector v, u, w; matrix p, q, r;

To specify how many dimensions vectors have, define ONE of
the following symbols to the C preprocessor:

TWODIM - for 2-D vectors THREEDIM - for 3-D vectors NDIM - for N-D vectorsThe symbols

Unless
the symbol **NOTYPEDEF** is defined when *vectmath.h* is included, **vector** and
**matrix** will be defined as **NDIM** and **NDIM** by **NDIM** arrays of **real** numbers,
respectively (see *stdinc*(3NEMO)
for a description of **real**). These may be
used to declare vector and matrix objects to be manipulated.

The exact definitions
of these operations correspond to the index language expressions given
above. Some of these definitions imply restrictions on placing the same
object on both sides of the assignment operation. For example,

ADDV(v, v, u);does exactly the right thing, but

CROSSVP(v, v, u);puts garbage into

Most of these
operations are implemented as macros which expand in line. A subtle point
connected with this is that syntactically, a reference to of one of these
macros is a statement, not an expression. This means that, for example,
the code fragment

if (foobar) ADDV(x, y, z); else SUBV(x, y, z);will not compile, because the terminating semi-colon following the ADDV is seen as a seperate (null) statement. The best way to solve this problem is to code the above example as follows:

if (foobar) { ADDV(x, y, z); } else { SUBV(x, y, z); }The enclosing curly-brackets insure that the code is syntactically correct both before and after macro expansion.

Those operators which return a scalar
value instead of storing it (currently, *dotvp, absv, distv, and tracem*)
are implemented by functions which are called from macro expansions. These
functions need to know if their arguments are floating or double arrays;
*vectmath.h* uses the preprocessor symbol **SINGLEPREC** to determine the precision
in use. Mixed-precision expressions yield incorrect results; for example,

float x[NDIM];double y[NDIM];... dotvp(x,y); will fail. Consistent use of the abstractions real, vector, and matrix is suggested. Some impure, but useful, vector and matrix operations are also defined. For example, ADDVS sets each element of a vector to a scalar, and MULVV multiplies two vectors with each other, element by element. BugsYou cannot (easily) mix vectors and matrices of different dimensionality within the same source code. History 30-nov-86(man) CreatedJEB 22-oct-90Merged in some starlab macrosPJT 27-apr-92Added SMULVV and documented starlab macrosPJT