.NH 1 "VMATH LIBRARY"
.XS
\s12\*(SN  VMATH LIBRARY\s0
.XE
.sp 2
.NH 2 "INTRODUCTION TO THE VMATH LIBRARY"
.XS
      \*(SN  INTRODUCTION
.XE
.sp 2
.PP
\fIvmath\fP is a Khoros Library which contains routines 
that perform a variety of mathematical operations.
It is used by many vipl and dspl routines when certain math functions are
necessary that are not available in the standard C math library.
.PP
The \fIvmath\fP library contains functions that generate random noise sequences
and signal sequences of various types, as well as functions that operate on  
complex numbers, and implement functions such as impulses and factorials.
.sp 2
.bp
.NH 2 " absolute()"
.XS
      \*(SN   absolute()
.XE
.sp
.LP
Return the absolute value of the first argument.
.LP
.B 
.sp
double absolute(num)
.br
double num;
.sp 
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP num: 10
The argument to take the absolute value of.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " bess()"
.XS
      \*(SN   bess()
.XE
.sp
.LP
Return the value of a bessel function.
.LP
.sp
.B
.sp
double bess(num)
.br
double num;
.br
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP num: 10
The independent argument to the bessel function. 
.sp
.LP
=====================================================================
.sp 3
.NH 2 " cadd()"
.XS
      \*(SN   cadd()
.XE
.sp
.LP
Find complex result from (r1,i1)+(r2,i2) and put the result in (r3,i3)
.sp
.B
.sp
int cadd(r3,i3,r1,i1,r2,i2)
.br
float r1,i1,r2,i2,*r3,*i3;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r3: 10
The real part of the return value.
.sp
.IP i3: 10
The imaginary part of the return value.
.sp
.IP r1: 10
The real part of the first complex number.
.sp
.IP i1: 10
The imaginary part of the first complex number.
.sp 
.IP r2: 10
The real part of the second complex number.
.sp
.IP i2: 10
The imaginary part of the second complex number.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " cang()"
.XS
      \*(SN   cang()
.XE
.sp
.LP
Return phasor angle of a complex number.
.sp
.B
.sp
double cang(r,i)
.br
float r,i;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r: 10
The real part of the input value.
.sp
.IP i: 10
The imaginary part of the input value.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " cconj()"
.XS
      \*(SN   cconj()
.XE
.sp
.LP
This routine finds the conjugate of the complex number (r1,i1) and
places it in (r2,i2).
.sp
.B
.sp
int cconj(r2,i2,r1,i1)
.br
float r1,i1,*r2,*i2;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r2: 10
The real part of the return value.
.sp
.IP i2: 10
The imaginary part of the return value.
.sp
.IP r1: 10
The real part of the input value.
.sp
.IP i1: 10
The imaginary part of the input value.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " cdiv()"
.XS
      \*(SN   cdiv()
.XE
.sp
.LP
 Find complex quotient from (r1,i1)/(r2,i2) and put the result in (r3,i3).
.sp
.B
.sp
cdiv(r3,i3,r1,i1,r2,i2)
.br
float r1, i1;
.br
float r2, i2;
.br
float *r3,*i3;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r1: 10
The real part of the first input value.
.sp
.IP i1: 10
The imaginary part of the first input value.
.sp
.IP r2: 10
The real part of the second input value.
.sp
.IP i2: 10
The imaginary part of the second input value.
.sp
.IP r3: 10
Pointer to the real part of the output value.
.sp
.IP i3: 10
Pointer to the imaginary part of the output value.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " cmagsq()"
.XS
      \*(SN   cmagsq()
.XE
.sp
.LP
Return power of complex number.
.sp
.B
.sp
double cmagsq(r,i)
.br
float r,i;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r: 10
The real part of the input value.
.sp
.IP i: 10
The imaginary part of the input value.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " cmul()"
.XS
      \*(SN   cmul()
.XE
.sp
.LP
Find complex result from (r1,i1)*(r2,i2) and put the result in (r3,i3).
.sp
.B
.sp
int cmul(r3,i3,r1,i1,r2,i2)
.br
float r1,i1,r2,i2,*r3,*i3;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r3: 10
The real part of the return value.
.sp
.IP i3: 10
The imaginary part of the return value.
.sp
.IP r1: 10
The real part of the first complex number.
.sp
.IP i1: 10
The imaginary part of the first complex number.
.sp
.IP r2: 10
The real part of the second complex number.
.sp
.IP i2: 10
The imaginary part of the second complex number.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " cquad()"
.XS
      \*(SN   cquad()
.XE
.sp
.LP
This routine evaluates the following expression:
.br
s*s + coeff1*s + coeff2,
.br
where s = real + imag.
.br
and places the result in (real,imag).
.sp
.B
.sp
int cquad(real,imag,coeff1,coeff2)
.br
float coeff1, coeff2, *real, *imag;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP real: 10
The real part of the return value.
.sp
.IP imag: 10
The imaginary part of the return value.
.sp
.IP coeff1: 10
Coefficient of first order term.
.sp
.IP coeff2: 10
Coefficient of the constant term.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " csub()"
.XS
      \*(SN   csub()
.XE
.sp
.LP
Find complex result from (r1,i1)-(r2,i2) and put the result in (r3,i3).
.sp
.B
.sp
int csub(r3,i3,r1,i1,r2,i2)
.br
float r1,i1,r2,i2,*r3,*i3;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r3: 10
The real part of the return value.
.sp
.IP i3: 10
The imaginary part of the return value.
.sp
.IP r1: 10
The real part of the first complex number.
.sp
.IP i1: 10
The imaginary part of the first complex number.
.sp
.IP r2: 10
The real part of the second complex number.
.sp
.IP i2: 10
The imaginary part of the second complex number.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " dpower()"
.XS
      \*(SN   dpower()
.XE
.sp
.LP
Returns the double representing \fIbase\fP raised to the \fIexp\fP power.
.sp
.B
.sp
double dpower(base,exp)
.br
int exp;
.br
double base;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP base: 10
Integer base to be raised to the exp power.
.sp
.IP exp: 10
Double exponent to raise base to.
.LP
=====================================================================
.sp 3
.NH 2 " get_princ_axis()"
.XS
      \*(SN   get_princ_axis()
.XE
.sp
.LP
Obtain the principal axis (the eigenvector associated with the largest 
eigenvalue) for the covariance matrix "a" of size nXn. Put the principal 
eigenvector in the location specified by  "y". NOTE: a and y should be of 
type DOUBLE! Also note that since "a" is a covariance matrix, it is 
symmetric, real, and very likely to be positive definite. It is certainly
positive semidefinate, and may also be diagonal dominant.
.LP
This algorithm uses the power iteration method to obtain the dominant 
eigenvalue and its associated eigenvector as described in Gollub and VanLoan,
MATRIX COMPUTATIONS, pp 209. The difficulty with this technique is that
convergence is proportional to lambda(2)/lambda(1) where lambda(1)
is the dominant eigenvector. If these eigenvalues are closely spaced
then we won't get a decent eigenvector (it will have an incorrect
direction).
.PP
Fortunately, when using the principal axis to split a cluster and there
are two very strongly dominant axes  with the same ellipticity, then
we can split on any combination of those axis and reduce the cluster
variances greatly.
.PP
The 10 iterations used in the code have been found to be satisfactory
for all of the data encountered with the exception of a few uncommon
special cases.
.sp
.B
.sp
get_princ_axis(a, n, y)
.br
double *a; 
.br
int n;
.br
double *y;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP a: 10
Pointer to matrix (of type double)
.IP n: 10
Size of matrix (nXn)
.IP y: 10
Pointer to output vector representing the eigenvector associated
with the dominant eigenvalue of a (of type double)
.sp
=====================================================================
.sp 3
.NH 2 " gexpon()"
.XS
      \*(SN   gexpon()
.XE
.sp
.LP
Generates a 2d exponential random noise data set
.sp
.B
.sp
int gexpon(vect,rows,cols,variance)
.br
float *vect,variance
.br
int rows,cols;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting exponential noise data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP variance: 10
Variance of data set.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " ggauss()"
.XS
      \*(SN   ggauss()
.XE
.sp
.LP
Generates a 2d Gaussian distributed random noise data set, with
dimensions and characteristics as specified.
.sp
.B
.sp
int ggauss(vect,rows,cols,mean,variance)
.br
float *vect,mean,variance;
.br
int rows,cols;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting Gaussian noise data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP mean: 10
Arithmetic mean (average) of data set.
.IP variance: 10
Variance of data set.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " gpoiss()"
.XS
      \*(SN   gpoiss()
.XE
.sp
.LP
Generates a 2d Poisson random noise data set
.sp
.B
.sp
int gpoiss(vect,rows,cols,variance,time)
.br
float *vect,time,variance;
.br
int rows,cols;
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting Poisson noise data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP variance: 10
Variance of data set.
.IP time: 10
Time in seconds (or unit time)that process is active.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " gpwl()"
.XS
      \*(SN   gpwl()
.XE
.sp
.LP
Generates a 2d "piecewise linear" data set.  By properly
setting arguments to this routine, you can generate
impulse data (spikes), triangular waves, sawtooth waves,
reverse sawtooth waves, and square waves.
.sp
.B
.sp
int gpwl(vect,rows,cols,sample,minimum,maximum,rperiod,cperiod,rrise,crise,
rwidth,cwidth)
.br
float *vect,sample,minimum,maximum,rperiod,cperiod;
.br
float rrise,crise,rfall,cfall,rwidth,cwidth;
.br
int rows,cols;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting piecewise linear data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP sample: 10
Sampling period for sampling the signal.
.IP minimum: 10
Minimum value of signal.
.IP maximum: 10
Maximum value of signal.
.IP rperiod: 10
Period in row direction.
.IP cperiod: 10
Period in column direction.
.IP rrise: 10
Pulse rise time in row direction.
.IP crise: 10
Pulse rise time in column direction.
.IP rwidth: 10
Pulse width (up time) in row direction
.IP cwidth: 10
Pulse width (up time) in column direction
.sp
.LP
=====================================================================
.sp 3
.NH 2 " grleigh()"
.XS
      \*(SN   grleigh()
.XE
.sp
.LP
Generates a 2d Rayleigh random noise data set.
.sp
.B
.sp
int grleigh(vect,rows,cols,variance)
.br
float *vect,variance;
.br
int rows,cols;
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting Rayleigh noise data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP variance: 10
Variance of data set.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " gsin()"
.XS
      \*(SN   gsin()
.XE
.sp
.LP
Generates a 2d sinusoid data set
.sp
.B
.sp
int gsin(vect,rows,cols,sample,amp,rfreq,cfreq,rphase,cphase)
.br
float *vect,sample,amp,rfreq,cfreq,rphase,cphase;
.br
int rows,cols;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting sinusoidal data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP sample: 10
Sampling period of signal.
.IP amp: 10
Maximum magnitude of signal.
.IP rfreq: 10
Frequency in row direction.
.IP cfreq: 10
Frequency in column direction.
.IP rphase: 10
Phase shift in row direction.
.IP cphase: 10
Phase shift in column direction.
.sp
.LP
=====================================================================
.sp 3
.sp 3
.NH 2 " gsinc()"
.XS
      \*(SN   gsinc()
.XE
.sp
.LP
Generates a 2d Sinc data set.
.sp
.B
.sp
int gsinc(vect, rows, cols, sample, amp, rfreq, cfreq, center)
.br
float *image,sample,amp,rfreq,cfreq;
.br
int rows,cols,center;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting piecewise linear data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP sample: 10
Sampling period for sampling the signal.
.IP amp: 10
Maximum amplitude of signal.
.IP rfreq: 10
Frequency in row direction.
.IP cfreq: 10
Frequency in column direction.
.IP center: 10
If zero the signal is not to be centered.
.sp
=====================================================================
.sp 3
.NH 2 " gunif()"
.XS
      \*(SN   gunif()
.XE
.sp
.LP
Generates a 2d uniform random noise data set with minimum and maximum
as specified.
.sp
.B
.sp
int gunif(vect,rows,cols,minimum,maximum)
.br
float *vect,minimum,maximum;
.br
int rows,cols;
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP vect: 10
Resulting uniform noise data set.
.IP rows: 10
Number of rows in data set.
.IP cols: 10
Number of columns in data set.
.IP minimum: 10
Minimum value of data set.
.IP maximum: 10
Maximum value of data set.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " inner()"
.XS
      \*(SN   inner()
.XE
.sp
.LP
Computes the inner (dot) product of two vectors
.sp
.B
.sp
double inner(x, y, n)
.br
double *x, *y;
.br
int n;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP x: 10
Pointer to first vector (of type double)
.IP y: 10
Pointer to second vector (of type double)
.IP n: 10
Number of components the vectors.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " kfmod()"
.XS
      \*(SN   kfmod()
.XE
.sp
.LP
Computes the double precision floating point modulos. That
is kfmod returns x mod y.
.sp
.B
.sp
double kfmod(x, y)
.br
double x, y;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP x: 10
First number (of type double)
.IP y: 10
Second number (of type double)
.sp
=====================================================================
.sp 3
.NH 2 " matvec()"
.XS
      \*(SN   matvec()
.XE
.sp
.LP
Computes the product of a matrix with a vector
.sp
.B
.sp
matvec(y, a, x, row, cols)
.br
double *y;
.br
double *a;
.br
double *x;
.br
int rows, cols;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP y: 10
Resulting output vector (pointer of type double)
.IP a: 10
Input matrix (pointer of type double)
.IP x: 10
Input vector (pointer of type double)
.IP rows: 10
Number of rows in matrix a.
.IP cols: 10
Number of columns in matrix a.
.sp
=====================================================================
.sp 3
.NH 2 " powtwo()"
.XS
      \*(SN   powtwo()
.XE
.sp
.LP
Returns 1 if length is an integer power of 2, 0 otherwise.
.sp
.B
.sp
int powtwo(length)
.br
int length;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP length: 10
An integer length to be tested to see if it is a power of two.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " urng()"
.XS
      \*(SN   urng()
.XE
.sp
.LP
Returns a (float) uniform random number.  This routine has no arguments.
.sp
.B
.sp
float urng()
.br
.R
.LP
=====================================================================
.sp 3
.NH 2 " vcabs()"
.XS
      \*(SN   vcabs()
.XE
.sp
.LP
Return the magnitude of complex number.
.sp
.B
.sp
double vcabs(r,i)
.br
float r,i;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP r: 10
The real part of the input value.
.sp
.IP i: 10
The imaginary part of the input value.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vfact()"
.XS
      \*(SN   vfact()
.XE
.sp
.LP
Computes the factorial (n!) of a number.
.sp
.B
.sp
double vfact(n)
.br
double n;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP n: 10
The number whose factorial is to be computed.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vgnoise()"
.XS
      \*(SN   vgnoise()
.XE
.sp
.LP
Generates a gaussian random number.
.sp
.B
.sp
double vgnoise(x)
.br
double x;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP x: 10
A seed from which to generate the gaussian random number.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vimpulse()"
.XS
      \*(SN   vimpulse()
.XE
.sp
.LP
Gives the impulse function of the argument.
.B
.sp
double vimpulse(x)
.br
double x;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP x: 10
The number whose impulse is to be computed.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vsrandom()"
.XS
      \*(SN   vsrandom()
.XE
.sp
.LP
Sets the seed for use by the \fIvrandom()\fP random number generator. If the
compile variable RANDOM is defined, then the system call \fIsrandom()\fP is
used; otherwise, the system call \fIsrand()\fP is used.  Note that anyone
using a call to \fIvrandom()\fP should make a call to this routine first.
For more information, do \f(CW%man srand\fP or \f(CW%man srandom\fP.
.B
.sp
vsrandom(seed)
.br
int seed;
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP seed:
The seed for the random number generator. Often, the current clock time is
used for the seed.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vrandom()"
.XS
      \*(SN   vrandom()
.XE
.sp
.LP
Generates a random number.  If the compile variable RANDOM is defined, then the
system call \fIrandom()\fP is used, and \fIbig\fP will be returned as 2^31-1.
Otherwise, the system call \fIrand()\fP is used, and \fIbig\fP will be returned
as 2^15-1.  For more information, do \f(CW%man rand\fP or \f(CW%man random\fP.
.B
.sp
vrandom(big)
.br
long *big;
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP big:
Returns the largest integer accepted by the system's random number generator,
so that the random number returned may be scaled, for example, from 0 to 1.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vsign()"
.XS
      \*(SN   vsign()
.XE
.sp
.LP
Determines the sign of the argument.
Returns -1 if argument is less that 0.0; 1 if it is greater
than 0.0; and 0 if it is equal to zero.
.sp
.B
.sp
double vsign(x)
.br
double x;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP x: 10
The number whose sign is to be determined.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vstep()"
.XS
      \*(SN   vstep()
.XE
.sp
.LP
Gives the step function of x (if x < 0, it returns 0; otherwise it returns 1).
.sp
.B
.sp
double vstep(x)
.br
double x;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP x: 10
The number for which the step function is to be returned.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " vunoise()"
.XS
      \*(SN   vunoise()
.XE
.sp
.LP
Generates a uniform random number with variance 1 and mean 0.
.sp
.B
.sp
double vunoise(x)
.br
double x;
.br
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP x: 10
A seed from which to generate the uniform random number.
.LP
=====================================================================
