   PROMATH 3.0            Manual Errata 
-----------------------------------------------
New functions and Manual corrections as of October 20, 1999
added sections 10/26/1999

If you find any errors that are not in this list, please let us know.
email support@teratech.com 

1) Routines that have misleading descriptions
2) Question & Answer
3) Corrections

***********************************************
1) Routines that have misleading descriptions :
(new descriptions will be written soon)

208             DotProduct
211             MATSADD
212             MATSPRD
220             CMATDCPY

350             RK5

***********************************************
2) Q & A

Q: In ProMath 3.0 manual, Chapter 14, Fast Fourier Transform,  what are the FFT 
subroutines BFFT (page 255) and BFFT2 (page  261)?  The descriptions and 
examples given are exactly the same as for the FFT and FFT2 subroutines 
respectively.  The problem is,  BFFT and BFFT2 both have a parameter, IFLAG, 
which must be passed to them.  No where can I find an explanation of what 
IFLAG is or what it does.  I tried looking at the code but it does not have 
comments and does not explain IFLAG.

A:  Forward Fourier Transforms take a set of values in the Time
Domain and transform them to a corresponding set of values in the Frequency
Domain. Inverse Fourier Transforms go from Frequency Domain to Time Domain.

There are two FFT algorithms, one forward FFT (just called FFT) and one
inverse FFT (called IFFT). They are mathematically very similar. If you look
on page 253 of the manual - description of FFT, you will note the descrete
forward transform has an exponential factor:
    Exp(i*2*pi*n*k/N)
and the inverse transform has an exponential  factor:
    Exp(-i*2*pi*n*k/N)

Using this similarity, both FFT and IFFT call BFFT; FFT uses an IFlag of +1
and IFFT uses an IFlag of -1. BFFT uses IFlag to put the sign in the
exponential factor. Thus BFFT does most of the work for both FFT and IFFT.

I am sorry that the manual does not explain what is going on here. You have
to look at the code. Much the same situation applies to FFT2, IFFT2 and
BFFT2.

Think of the BFFT routines as auxiliaries, rather than ones you would want
to call. Indeed in our latest revision of the ProMath routines We propose to
make both BFFT and BFFT2 Private Subs. And to revise the manual, by removing
most of the BFFT text, (as you point out it is just a copy of the FFT text).

I hope this rather short explanation will help you understand the reasons
for BFFT and the way ProMath uses it

***********************************************
***********************************************
3) Corrections

Below we describe routines which are in ProMath, but not in Manual
------------------------------------------------------------------

Routine:      CMatEleDiv
File:         MATRIX.BAS
Usage:        Call CMatEleDiv(A(), B(), R(), N, M)

Divide all the elements of a complex matrix A(), by another B(). 
All elements are complex.
         A(I,J)
R(I,J) = ------
         B(I,J)

A, B and R must be the same size NxM.
The following parameters are passed:

A() Name of first input (complex) NxM matrix
B() Name of second input (complex) NxM matrix
R() Name of output (complex) NxM matrix
N   Number of rows in A(),B(), and R()
M   Number of columns in A(),B(), and R()


------------------------------------------------------------------
Routine:      AllStats
File:         STATS.BAS
Usage:        Call Allstats(Dat#(), Start%, NSamples%, Min#, Max#, Range#, _
 	                    Average#, StdDev#)

Calculates the average, standard deviation, minimum, maximum and range of 
all or part of a set of samples.

The following arguments are passed:
Dat#()     the array holding the data. It must be dimensioned to at least 
	   (Start% + Nsamples% -1) locations. It is unchanged.
Start%     the location from which calculation starts
Nsamples%  the Number of samples used in calculation
min#       returned with the least value found
max#       returned with the largest value found
Range#     returned with the range, Max# - Min#
Average#   returned with the average of the Nsamples%
StdDev#    returned with the Standard Deviation of the Nsamples%

Algorithm:
The routine combines several of the most used statistic routines and 
allows you the additional flexibility of starting from any location. 
It will exit if Nsamples% is less than 2. Please see AVERAGE and STANDARDDEV 
for similar individual routines.

------------------------------------------------------------------
------------------------------------------------------------------
------------------------------------------------------------------
Corrections :
------------------------------------------------------------------
------------------------------------------------------------------

Routine:      MatEquate
File:         MATRIX.BAS
Usage:        CALL MatEquate(A(),B(),N,M)

This routine copies one real matrix into another.
The following parameters are passed:
A()	A real matrix of dimension NM. A() is unchanged
B()	A real matrix of dimension NM. B() is replaced by A()
N	The first dimension of the real matrices, A() and B().
M	The second dimension of the real matrices, A() and B().

Caution:  It is important to remember that the matrix B() is altered 
on return to the calling module.

Algorithm:
The matrix is copied term by term.

------------------------------------------------------------------
Routine:      CMatEquate
File:         MATRIX.BAS
Usage:        CALL CMatEquate(A() AS COMPLEX,B() AS COMPLEX,N,M)

This routine copies one complex matrix into another.
The following parameters are passed:
A()	A complex matrix of dimension NM. A() is unchanged
B()	A complex matrix of dimension NM. B() is replaced by A()
N	The first dimension of the complex matrices, A() and B().
M	The second dimension of the complex matrices, A() and B().

Caution:  It is important to remember that the matrix B() is altered 
on return to the calling module.

Algorithm:
The matrix is copied term by term.

------------------------------------------------------------------
Routine:      CMatEquateReal
File:         MATRIX.BAS
Usage:        CALL CMatEquateReal(A() AS COMPLEX,B(),N,M)

This routine copies the real parts of a complex matrix into a real matrix.
The following parameters are passed:
A()	A complex matrix of dimension NM. A() is unchanged
B()	A real matrix of dimension NM. B() is replaced by the real parts of A()
N	The first dimension of the matrices, A() and B().
M	The second dimension of the matrices, A() and B().

Caution:  It is important to remember that the matrix B() is altered 
on return to the calling module.

Algorithm:
The real parts of the matrix is copied term by term into a real matrix

------------------------------------------------------------------
Routine:      CMatIdent
File:         MATRIX.BAS
Usage:        CALL CMatIdent(A() AS COMPLEX,N)

Makes A() into a unit matrix.
The following arguments are passed:
A()	The complex, square matrix to be returned as a unit complex matrix. 
	Note the dimension of this matrix is NxN.
N	The dimension of the NxN square matrix A().

Algorithm:
Writes 1 + i0 on the main diagonal of A() and 0 + i0 elsewhere.

------------------------------------------------------------------
Routine:      CMATINV
File:         MATRIX.BAS
Usage:        CALL CMATINV(A() AS COMPLEX,Y() AS COMPLEX,N, ErrCode)

To invert a complex square matrix and return its inverse.
The following arguments are passed:
A()	The complex, square matrix whose inverse is to be computed. 
	Note that this matrix is destroyed. The dimension of this matrix is NxN.
Y()	Returned with the inverse of the matrix A().
N	The dimension of the NxN square matrices A() and Y().

Algorithm:
One of the most efficient ways to compute the inverse of a matrix is using the 
LU decomposition technique. Given a square matrix A, if we decompose it once 
using the LU decomposition and subsequently use back substitution on the 
LU decomposed matrix, the resulting matrix is the inverse of the matrix A. 
We have adapted the LU method to complex matrices.


------------------------------------------------------------------
------------------------------------------------------------------
------------------------------------------------------------------
Matrix Printing for Visual Basic

Tip:  The matrix print routines have been updated to allow them to be used 
	in Visual Basic. Some Basic Language definitions allow you to write 
	Print <expression> where Visual Basic requires you to write statements 
	like FormName.Print <expression>. We have introduced an extra parameter 
	to specify where you want the printing to take place, so that our routines 
	will work on VB 4.0 and later versions 

Caution:  We have kept the same routine names for routines with the same function. 
	Since they have different parameters please take care not to mix them up.
------------------------------------------------------------------
------------------------------------------------------------------

------------------------------------------------------------------
Routine:      MATPRINT
File:         MATRIX.BAS
Usage:        CALL MATPRINT (ObjName As Object, A#(), N%, M%, Formt$)

MatPrint lists a matrix on a form, picture or printer.
The following arguments are passed:

ObjName	The name of the place where printing is to take place. 
	ObjectName may be a form name or a picture name, or a printer name. 
	Or, to print on the default printer, use Printer. Also during 
	development you may use Debug.
A()	The matrix of dimension NM to be listed on the ObjName.
N	The number of rows in the matrix A() (printing starts at 1)
M	The number of columns in the matrix A(). M should be 1 if the array is 
	one-dimensional.
Formt$	A string specifying the number format to be used in printing the numbers. 
	The format is identical to BASIC's PRINT USING. If Formt$ = "", default 
	scientific notation is used (i.e., 10.5 is written as 0.105D+2).

Algorithm
Matprint calls MatPrint1 if it is printing a one-dimensional array or MatPrint2 for two-dimensional arrays.
Example:
DIM A(3, 5)
N = 3                                 ' number of rows
M = 5                                 ' number of columns
'--- define the matrix A
FOR I = 1 TO N
  FOR J = 1 TO M
    A(I, J) = I + J
  NEXT J
NEXT I
F$ = ""        ' default scientific notation for matprint
CALL MATPRINT(Form1, A(), N, M,F$,)  ' print to Form1
Results:
0.200D+1  0.300D+1  0.400D+1  0.500D+1  0.600D+1
0.300D+1  0.400D+1  0.500D+1  0.600D+1  0.700D+1
0.400D+1  0.500D+1  0.600D+1  0.700D+1  0.800D+1

------------------------------------------------------------------
Routine:      MATPRINT1
File:         MATRIX.BAS
Usage:        CALL MATPRINT1(ObjName As Object, A#(), N%, Formt$)

This routine lists a one-dimensional matrix on a form, picture or printer. 
(You don't have to call it directly).

The following arguments are passed:
ObjName	The name of the place where printing is to take place. 
	ObjectName may be a form name or a picture name, or a printer name. 
	Or, to print on the default printer, use Printer. Also during 
	development you may use Debug.
A()	The matrix of dimension N to be listed on the ObjName.
N	The number of rows in the matrix A() (printing starts at 1)
Formt$	A string specifying the number format to be used in printing the numbers. 
	The format is identical to BASIC's PRINT USING. If FORM$ = "", default 
	scientific notation is used (i.e., 10.5 is written as 0.105D+2).

Example:
DIM A(3, 5)
N = 3                                 ' number of rows
M = 5                                 ' number of columns
'--- define the matrix A
FOR I = 1 TO N
  FOR J = 1 TO M
    A(I, J) = I + J
  NEXT J
NEXT I
F$ = ""        ' default scientific notation for matprint
CALL MATPRINT(form1, A(), N, M,F$,"SCREEN")  ' print to form1
Results:
0.200D+1  0.300D+1  0.400D+1  0.500D+1  0.600D+1

------------------------------------------------------------------
Routine:      MATPRINT2
File:         MATRIX.BAS
Usage:        CALL MATPRINT2(ObjName As Object, A#(), N%, M%, Formt$)

This routine lists a two-dimensional matrix on a form, picture or printer. 
(You don't have to call it directly).

The following arguments are passed:
ObjName	The name of the place where printing is to take place. 
	ObjectName may be a form name or a picture name, or a printer name. 
	Or, to print on the default printer, use Printer. Also during 
	development you may use Debug.
A()	The matrix of dimension NM to be listed on the ObjName.
N	The number of rows in the matrix A() (printing starts at 1)
M	The number of columns in the matrix A().(printing starts at 1)
Formt$	A string specifying the number format to be used in printing the numbers. 
	The format is identical to BASIC's PRINT USING. If Formt$ = "", default 
	scientific notation is used (i.e., 10.5 is written as 0.105D+2).

Example:
DIM A(3, 5)
N = 3                                 ' number of rows
M = 5                                 ' number of columns
'--- define the matrix A
FOR I = 1 TO N
  FOR J = 1 TO M
    A(I, J) = I + J
  NEXT J
NEXT I
F$ = ""        ' default scientific notation for matprint
CALL MATPRINT(form1, A(), N, M,F$,"SCREEN")  ' print to form1
Results:
0.200D+1  0.300D+1  0.400D+1  0.500D+1  0.600D+1
0.300D+1  0.400D+1  0.500D+1  0.600D+1  0.700D+1
0.400D+1  0.500D+1  0.600D+1  0.700D+1  0.800D+1

------------------------------------------------------------------
Routine:      CMATPRINT
File:         MATRIX.BAS
Usage:        CALL CMATPRINT(ObjName As Object, A() As COMPLEX, N%, M%, _
			     MaxCha%, Formt$)

This routine lists a complex matrix on a form, picture or printer.

The following arguments are passed:
ObjName	The name of the place where printing is to take place. 
	ObjectName may be a form name or a picture name, or a printer name. 
	Or, to print on the default printer, use Printer. 
	Also during development you may use Debug.
A()	The complex matrix of dimension NM to be listed on the ObjectName.
N	The number of rows in the matrix A() (printing starts at 1)
M	The number of columns in the matrix A(). Use M = 1 for a 1-dimensional array.
MaxCha%	the real part and the imaginary part of each number will be printed 
	to a maximum of MaxCha% characters (may override Formt$)
Formt$	A string specifying the number format to be used in printing the numbers. 
	The format is identical to BASIC's PRINT USING. If Formt$ = "", default 
	scientific notation is used (i.e., 10.5 is written as 0.105D+2).

Algorithm:
CMatprint calls CMatPrint1 if it is printing a one-dimensional complex array 
or CMatPrint2 for two-dimensional complex arrays. These routines both use Cformat$ 
to get a print string for each complex number and then add brackets for separation.

Example:
DIM A(3, 3) AS COMPLEX
N = 3                                 ' number of rows
M = 3                                 ' number of columns
'--- define the matrix A
FOR I = 1 TO N
  FOR J = 1 TO M
    A(I, J).X = I : A(I,J).Y= J
  NEXT J
NEXT I
F$ = ""       ' default scientific notation for cmatprint
CALL CMATPRINT(form1, A(), N, M,F$,"SCREEN") ' print to form1
Results:
(0.100D+1 0.100D+1i) (0.100D+1 0.200D+1i) (0.100D+1 0.300D+1i)
(0.200D+1 0.100D+1i) (0.200D+1 0.200D+1i) (0.200D+1 0.300D+1i)
(0.300D+1 0.100D+1i) (0.300D+1 0.200D+1i) (0.300D+1 0.300D+1i)

------------------------------------------------------------------
Routine:      CMATPRINT1
File:         MATRIX.BAS
Usage:        CALL CMATPRINT1(ObjName As Object, A() As COMPLEX, N%, _
				MaxCha%, Formt$)
 

This routine lists a one-dimensional complex matrix on a form, picture or printer. 
You do not have to call it directly.

The following arguments are passed:
ObjName	The name of the place where printing is to take place. 
	ObjectName may be a form name or a picture name, or a printer name. 
	Or, to print on the default printer, use Printer. Also during 
	development you may use Debug.
A()	The matrix of dimension N to be listed on the ObjName
N	The number of rows in the matrix A().
MaxCha%	the real part and the imaginary part of each number will be printed to 
	a maximum of MaxCha% characters (may override Formt$)
Formt$	A string specifying the number format to be used in printing the numbers. 
	The format is identical to BASIC's PRINT USING. If Formt$ = "", default 
	scientific notation is used (i.e., 10.5 is written as 0.105D+2).
Example:
DIM A(3, 3) AS COMPLEX
N = 3                                 ' number of rows
M = 3                                 ' number of columns
'--- define the matrix A
FOR I = 1 TO N
  FOR J = 1 TO M
    A(I, J).X = I : A(I,J).Y= J
  NEXT J
NEXT I
F$ = ""       ' default scientific notation for cmatprint
CALL CMATPRINT(form1, A(), N, M,F$,"SCREEN") ' print to form1
Results:
(0.100D+1 0.100D+1i) (0.100D+1 0.200D+1i) (0.100D+1 0.300D+1i)

------------------------------------------------------------------
Routine:      CMATPRINT2
File:         MATRIX.BAS
Usage:        CALL CMATPRINT2(ObjName As Object, A() As COMPLEX, N%, M%, _
				MaxCha%, Formt$)

This routine lists a two-dimensional complex matrix on a form, picture or printer. 
(You do not have to call it directly)

The following arguments are passed:
ObjName	The name of the place where printing is to take place. 
	ObjectName may be a form name or a picture name, or a printer name. 
	Or, to print on the default printer, use Printer. Also during 
	development you may use Debug.
A()	The matrix of dimension NM to be listed on the ObjectName.
N	The number of rows in the matrix A() (printing starts at one)
M	The number of columns in the matrix A().
MaxCha%	the real part and the imaginary part of each number will be printed 
	to a maximum of MaxCha% characters (may override Formt$)
Formt$	A string specifying the number format to be used in printing the numbers. 
	The format is identical to BASIC's PRINT USING. If Formt$ = "", default 
	scientific notation is used (i.e., 10.5 is written as 0.105D+2).

Example:
DIM A(3, 3) AS COMPLEX
N = 3                                 ' number of rows
M = 3                                 ' number of columns
'--- define the matrix A
FOR I = 1 TO N
  FOR J = 1 TO M
    A(I, J).X = I : A(I,J).Y= J
  NEXT J
NEXT I
F$ = ""       ' default scientific notation for cmatprint
CALL CMATPRINT(form1, A(), N, M,F$,"SCREEN") ' print to form1
Results:
(0.100D+1 0.100D+1) (0.100D+1 0.200D+1) (0.100D+1 0.300D+1)
(0.200D+1 0.100D+1) (0.200D+1 0.200D+1) (0.200D+1 0.300D+1)
(0.300D+1 0.100D+1) (0.300D+1 0.200D+1) (0.300D+1 0.300D+1)

------------------------------------------------------------------
------------------------------------------------------------------
Matrix Printing for DOS
These versions of the matrix printing routines are the original ones, 
with some corrections. 
------------------------------------------------------------------
------------------------------------------------------------------
