       OOOOOO                            VV        VV
      OO    OO   PPPPPPP   TTTTTTTT  II   VV      VV  EEEEEE   CCCCCC
      OO    OO   PP    PP     TT     II    VV    VV   EE       CC
      OO    OO   PPPPPPP      TT     II     VV   VV   EEEEEE   CC
      OO    OO   PP           TT     II       VVV     EE       CC
       OOOOOO    PP           TT     II        V      EEEEEE   CCCCCC


                       OptiVec  Version 1.4

              Part Three: Description of MatrixLib

                     Dr. Martin Sander Software Development
                     Sertrnerstr. 11
                     D-37085 Gttingen
                     Germany
                     e-mail: MartinSander@Bigfoot.com
                     http://www.optivec.com

****************************************************************************

!!     This is an ASCII text file!  It is best viewed with a simple        !!
!!     DOS editor.                                                         !!
!!     If you load this file into a word processor under Windows, you      !!
!!     must use the filter "DOS text".                                     !!
!!     Alternatively, you may use FCONVERT (shipped with Borland C++) to   !!
!!     convert from ASCII (OEM) into the ANSI character set.               !!
!!     Preferrably use the lettertype CourierNew 10 pt.                    !!

A general description of OptiVec is given in the  F i r s t  P a r t
of this documentation, in the file HANDBOOK.TXT.
Chapter 1.2 of that file contains the licence terms.
See FUNCREF.TXT for the description of VectorLib functions,
and CMATH.TXT for CMATH functions.

Copyright for the Software and its documentation (C) 1996-1999 Martin Sander


****************************************************************************
*                                                                          *
*******                           Contents                           *******
*                                                                          *
****************************************************************************

 1. MatrixLib Introduction
 2. Management of Dynamically Generated Matrices
 3. Initialization of Matrices
 4. Data-Type Conversions
 5. Transposing and Extracting Parts from a Matrix
 6. Arithmetic Operations Performed on a Single Row, Column, or the Diagonal
 7. Operations performed along all rows or all columns simultaneously
 8. Operations involving two rows or two colums
 9. Matrix Multiplication
10. Linear Algebra 
11. Eigenvalues and Eigenvectors
12. Two-Dimensional Fourier-Transform Methods
13. Data Fitting
14. Matrix Input and Output
15. Graphical Representation of Matrices
16. Alphabetical Syntax Reference


1. MatrixLib Introduction
-------------------------

MatrixLib defines the following data types:
  fMatrix   matrix of floats
  dMatrix   matrix of doubles
  eMatrix   matrix of extended (long double)
  cfMatrix  matrix of fComplex (complex<float>)
  cdMatrix  matrix of dComplex (complex<double>)
  ceMatrix  matrix of eComplex (complex<extended>)

The ordering of elements is the same as in the two-dimensional arrays
provided by the respective target compilers. This means that the matrices
are stored row-wise in MatrixLib versions for C and C++ compilers, but
column-wise in versions for Pascal and Fortran.
At present, integer matrices are defined, but no functions are available
for them.

While we recommend to exclusively use these dynamically allocated matrix
types, static matrices defined, e.g., as
    float  MX[4][6];
can be used in all MatrixLib functions with the exception of the multiLinfit
and multiNonlinfit routines.

Each MatrixLib function has a prefix defining the data type on which it acts:

MF_  for arguments of the types fMatrix, float and fVector
MD_  for arguments of the types dMatrix, double and dVector
ME_  for arguments of the types eMatrix, extended (long double) and eVector
MCF_ for arguments of the types cfMatrix, fComplex and cfVector
MCD_ for arguments of the types cdMatrix, dComplex and cdVector
MCE_ for arguments of the types ceMatrix, eComplex and ceVector


2. Management of Dynamically Generated Matrices
-----------------------------------------------

MF_matrix      allocate memory for a matrix
MF_matrix0     allocate memory and set all elements 0
M_free         free one matrix (data-type independent)
M_nfree        free n matrices (data-type independent)
V_freeAll      free all existing vectors and matrices 

OptiVec's dynamically allocated matrices can be addressed just like two-
dimensional static arrays of C. If you have, e.g., an fMatrix MX and
a variable float a, you can write a line like
     a = MX[3][5];

Additionally, there are two functions addressing single elements
(which are necessary for Pascal and for getting around the
pointer arithmetics bug in some versions of Borland C++):

MF_Pelement    Pointer to a specific matrix element
MF_element     value of a specific matrix element


3. Initialization of Matrices
-----------------------------

MF_equ0        set all elements to 0
MF_equ1        identity matrix: set all diagonal elements to 1.0,
               all others to 0
MF_outerprod   matrix formed by the "outer product" of two vectors

MF_Row_equC    set all elements of one specific row to the constant C
MF_Col_equC    set all elements of one specific column to the constant C
MF_Dia_equC    set all diagonal elements to the constant C
MF_Row_equV    copy a vector into one specific row
MF_Col_equV    copy a vector into one specific column
MF_Dia_equV    copy a vector into the diagonal

MF_equM        make one matrix the copy of another
MF_UequL       copy lower-diagonal elements into upper-diagonal
               by index-reflection, so as to get a symmetric matrix 
MF_LequU       copy upper-diagonal elements into lower-diagonal

Two-dimensional windows for spectral analysis are provided by:
MF_Hanning     Hanning window
MF_Parzen      Parzen window
MF_Welch       Welch window


4. Data-Type Conversions
------------------------

Matrices of every data type can be converted into every other.
Only a few examples are given; the rest should be obvious.

M_FtoD    fMatrix to dMatrix
M_CDtoCF  cdMatrix to cfMatrix (with overflow protection)
M_DtoE    dMatrix to eMatrix


5. Transposing and Extracting Parts from a Matrix
-------------------------------------------------

MF_transpose        transpose a matrix

MF_submatrix        extract a submatrix
MF_submatrix_equM   copy a submatrix back into another (normally larger)
                    matrix

MF_Row_extract      extract a single row and copy it into a vector
MF_Col_extract      extract a single column and copy it into a vector
MF_Dia_extract      extract the diagonal and copy it into a vector

6. Arithmetic Operations Performed on a Single Row, Column, or the Diagonal
---------------------------------------------------------------------------

MF_Row_addC         add a constant to all elements of a specific row
MF_Col_addC         add a constant to all elements of a specific column
MF_Dia_addC         add a constant to all diagonal elements
MF_Row_addV         add corresponding vector elements to all elements of a
                    specific row
MF_Col_addV         add corresponding vector elements to all elements of a
                    specific column
MF_Dia_addV         add corresponding vector elements to the diagonal elements

A few examples should suffice for the other functions of this family:
MF_Row_subC         subtract a constant from all elements of a specific row
MF_Col_subrC        reverse substraction: difference between column elements
                    and a constant
MF_Dia_mulV         multiply the diagonal elements with corresponding vector
                    elements
MF_Row_divV         divide all elements of a specific row by corresponding
                    vector elements
MF_Col_divrC        reverse division: division of a constant by the individual
                    column elements


7. Operations performed along all rows or all columns simultaneously,
         or along the diagonal of a square matrix
----------------------------------------------------------------------

MF_Rows_max         store the maxima of all rows in a column vector
MF_Cols_max         store the maxima of all colums in a row vector
MF_Dia_max          return the maximum of the diagonal as a scalar

MF_Rows_min         store the minima of all rows in a column vector
MF_Cols_min         store the minima of all colums in a row vector
MF_Dia_min          return the minimum of the diagonal as a scalar

MF_Rows_absmax      store the absolute maxima of all rows in a column vector
MF_Cols_absmax      store the absolute maxima of all colums in a row vector
MF_Dia_absmax       return the absolute maximum of the diagonal as a scalar
MF_Rows_absmin      store the absolute minima of all rows in a column vector
MF_Cols_absmin      store the absolute minima of all colums in a row vector
MF_Dia_absmin       return the absolute minimum of the diagonal as a scalar

MF_Rows_sum         sum, taken along rows and stored in a column vector
MF_Cols_sum         sum, taken along colums and stored in a row vector
MF_Dia_sum          sum of the diagonal elements

MF_Rows_prod        product, taken along rows and stored in a column vector
MF_Cols_prod        product, taken along colums and stored in a row vector
MF_Dia_prod         product of the diagonal elements

MF_Rows_runsum      running sum along rows
MF_Cols_runsum      running sum along columns
MF_Rows_runprod     running product along rows
MF_Cols_runprod     running product along columns

MF_Rows_rotate      rotate all rows by a specified number of positions
MF_Cols_rotate      rotate all rows by a specified number of positions
MF_Rows_reflect     set the upper halves of all rows equal to their reversed
                    lower halves
MF_Cols_reflect     set the upper halves of all columns equal to their
                    reversed lower halves


8. Operations involving two rows or two colums
----------------------------------------------

MF_Rows_exchange   exchange two rows
MF_Cols_exchange   exchange two columns

MF_Rows_add        add two rows  (destination += source)
MF_Cols_add        add two columns 

MF_Rows_sub        subtract two rows (destination -= source)
MF_Cols_sub        subtract two columns

MF_Rows_Cadd       add scaled row to another (destination += C * source)
MF_Cols_Cadd       add scaled column to another

MF_Rows_lincomb    linear combination of two rows
MF_Cols_lincomb    linear combination of two columns


9. Matrix Multiplication
------------------------

MF_mulV            multiply a matrix by a column vector
VF_mulM            multiply a row vector by a matrix
MF_mulM            multiply two matrices

10. Linear Algebra
------------------

First the "easy-to-use" versions of linear algebra functions:
MF_solve          solve simultaneous linear equations, using LU decomposition
MF_inv            invert a matrix
MF_det            determinant of a matrix
MF_solveBySVD     solve simultaneous linear equations, using Singular Value
                  Decomposition
MF_safeSolve      try first solution by LUD; if that fails, SVD is done.

Now some functions for LU decomposition and for treatment of
LU decomposed matrices:

MF_LUdecompose    decompose into LU form
MF_LUimprove      improve accuracy of LU decomposition by iteration
MF_LUDresult      check if MF_LUdecompose was successful
MF_LUDsetEdit     set editing threshold for MF_LUdecompose; may be used to
                  work around singularities
MF_LUDgetEdit     retrieve currently set threshold

MF_LUsolve        solve simultaneous linear equations, given the matrix in
                  LU form
MF_LUinv          invert matrix already composed into LU form
MF_LUdet          determinant of matrix already composed into LU form

Singular Value Decomposition and related functions:

MF_SVdecompose    Singular Value Decomposition
MF_SVsolve        solve SV-decomposed set of linear equations
MF_SVimprove      iterative improvement of solution found by MF_SVsolve
MF_SVDsetEdit     set threshold for Singular Value editing
MF_SVDgetEdit     retrieve current threshold for Singular Value editing


11. Eigenvalues and Eigenvectors
--------------------------------

MFsym_eigenvalues  eigenvalues with or without eigenvectors of a symmetric
                   real matrix (only this special, but most frequent case
                   is currently covered)

12. Two-Dimensional Fourier-Transform Methods
---------------------------------------------

MF_FFT            Fast Fourier Transform
MF_convolve       Convolution with a spacial response function
MF_deconvolve     Deconvolution
MF_filter         Spatial filtering
MF_autocorr       Spatial autocorrelation
MF_xcorr          Spatial cross-correlation
MF_spectrum       Spatial frequency spectrum


13. Data Fitting
----------------

The functions for fitting X-Y pairs of data are included in MatrixLib
rather than in VectorLib, because they heavily rely on matrix methods.
Their prefix, VF_, however, is a reminder that they actually work on
vectors, rather than on matrices. (The weighted variants actually do
also work on a matrix and calculate the covariance matrix of parameters).
The simplest form of data fitting, namely linear regression, does not
employ matrix methods and is described in the VectorLib documentation:
VF_linregress.

VF_polyfit        fit an X-Y data pair to a polynomial of arbitrary degree
VF_polyfitwW      the same with non-equal weighting of individual data points
VF_linfit         fit an X-Y data pair to a function linear in its parameters
VF_linfitwW       the same with non-equal weighting of individual data points
VF_nonlinfit      fit X-Y data to an arbitrary, possibly non-linear function
VF_nonlinfitwW    the same for non-equal data-point weighting
VF_multiLinfit       fit multiple X-Y data sets to one common model,
                     linear in its parameters
VF_multiLinfitwW     the same for non-equal data-point weighting
VF_multiNonlinfit    fit multiple X-Y data sets to one common model,
                     possibly nonlinear in its parameters
VF_multiNonlinfitwW  the same for non-equal data-point weighting

With the exception of fitting to polynoms, which are present only for the
X-Y data case, here are the corresponding functions for fitting
z = f(x,y) data (with the prefix MF_):

MF_linfit         fit X-Y-Z data to a function linear in its parameters
MF_linfitwW       the same with non-equal weighting of individual data points

MF_nonlinfit      fit X-Y-Z data to an arbitrary, possibly non-linear function
MF_nonlinfitwW    the same for non-equal data-point weighting

MF_multiLinfit       fit multiple X-Y-Z data sets to one common model,
                     linear in its parameters
MF_multiLinfitwW     the same for non-equal data-point weighting
MF_multiNonlinfit    fit multiple X-Y-Z data sets to one common model,
                     possibly nonlinear in its parameters
MF_multiNonlinfitwW  the same for non-equal data-point weighting

The nonlinear fitting routines are highly sophisticated and offer the user
a lot of different options. These options may be set by the function
V_setNonlinfitOptions. To retrieve current settings, use
V_getNonlinfitOptions.

All options are packed into a structure named VF_NONLINFITOPTIONS.
VF_NONLINFITOPTIONS has the following fields:

int      FigureOfMerit       0: least squares fitting
                             1: robust fitting, optimizing for minimum
                                absolute deviation
                             Default: 0

float    AbsTolChi           absolute change of chi (default: EPSILON)
float    FracTolChi          fractional change of chi
                                    (default: SQRT_EPSILON)
float    AbsTolPar           absolute change of all parameters
                                    (default: SQRT_MIN) 
float    FracTolPar          fractional change of all parameters
                                    (default: SQRT_EPSILON)
                             These four parameters describe the convergence
                             conditions: if the changes achieved in successive
                             iterations are smaller than demanded by these
                             criteria, this signals convergence. Set those
                             criteria to 0.0, which are not applicable

unsigned HowOftenFulfill     how often fulfill one of the above conditions
                             before convergence is considered achieved
                             (default: 3)

unsigned LevelOfMethod       1: Levenberg-Marquardt method,
                             2: Downhill Simplex (Nelder and Mead) method,
                             3: both methods alternating;
                                add 4 to this in order to try
                                breaking out of local minima;
                             0: no fit, calculate only chi2 (and Covar)
                             (default: 1)

unsigned LevMarIterations    max.number of successful iterations of LevMar
                             during one run (default: 100)

unsigned LevMarStarts        number of LevMar restarts per run (default: 2)

float    LambdaStart,
         LambdaMin,
         LambdaMax,
         LambdaDiv,
         LambdaMul           treatment of LevMar parameter lambda (don't
                             touch, unless you are an expert!)

unsigned DownhillIterations  max. number of successful iterations in Downhill
                             Simplex method  (default: 200)

float    DownhillReflection,
         DownhillContraction,
         DownhillExpansion   treatment of re-shaping of the simplex in
                             Downhill Simplex method  (don't touch
                             unless you are an expert!)

unsigned TotalStarts;        max. number of LevMar/Downhill pairs
                             (default: 16)

fVector  UpperLimits;        impose upper limits on parameters. Default: NULL
fVector  LowerLimits         impose lower limits on parameters. Default: NULL

void     (*Restrictions)(void);  user-defined function, implementing
                             restrictions on the parameters which are not
                             contained in the upper/lower limits restriction.
                             The function must check the whole parameter
                             vector and edit the parameters as needed.
                             Default: NULL 


The multifit functions, i.e. those which allow the treatment of several
X-Y or X-Y-Z data sets simultaneously, need the data to be passed in
structures named VF_EXPERIMENT for X-Y data and MF_EXPERIMENT for X-Y-Z
data:

VF_EXPERIMENT has the following fields:

fVector X, Y               X and Y vectors
fVector InvVar             inverse variances of the individual vector
                           elements (needed only for the "with weights"
                           functions)
ui      size               the number of vector elements 
float   WeightOfExperiment individual weight to be assigned to the
                           whole experiment (again needed only for
                           the weighted variants)

MF_EXPERIMENT has the following fields:

fVector   X, Y             X and Y vectors (independent variables)
fMatrix   MZ               measured data z=f(x,y)
fMatrix   MInvVar          inverse variances of the individual matrix
                           elements (needed only for the "with weights"
                           functions)
unsigned  htZ, lenZ        matrix dimensions
float     WeightOfExperiment weight to be assigned to the whole
                           experiment (again needed only for
                           the weighted variants)


14. Matrix Input and Output
---------------------------

The matrix input/output functions are all analogous to the corresponding
vector functions

MF_cprint   print a matrix to the screen. If necessary, rows are cut off
            at the screen boundaries. If there are more rows than screen
            lines, proper paging is applied.
MF_print    print a matrix to the screen (without paging or row cut-off)
MF_fprint   print a matrix in ASCII format to a stream. 

MF_store    store in binary format
MF_recall   retrieve in binary format
MF_write    write in ASCII format in a stream
MF_read     read from an ASCII file.


15. Graphical Representation of Matrices
----------------------------------------

True 3D-plotting functions will be included only in future versions.
For now, only color-density plots are available. In these plots, each
data value is translated into a color value by linear interpolatiion
between two colors, specified as mincolor and maxcolor.

MF_xyzAutoDensityMap    Color density map for z=f(x,y) with automatic
                        scaling of the X and Y axes and of the color
                        density scale between mincolor and maxcolor.
MF_xyzDataDensityMap    z=f(x,y) color density map, plotted into an
                        existing axis frame, and using the color density
                        scale set by the last call to an "AutoDensityMap"
                        function.
MF_zAutoDensityMap      Color density map for z=f(i,j) with automatic
                        scaling of the X and Y axes and of the color
                        density scale between mincolor and maxcolor.
                        i and j are the indices in X and Y direction,
                        respectively.
MF_zDataDensityMap      Color density map for z=f(i,j), plotted into
                        an existing axis frame, and using the color
                        density scale set by the last call to an
                        "AutoDensityMap" function.


16. Alphabetical Syntax Reference
---------------------------------

This chapter summarizes, in alphabetical order, the syntax of MatrixLib
functions. As usual, the MF_ or M_ prefix is neglected in the ordering
of entries. The particles "Row_", "Rows_", "Col_", "Cols_", and "Dia_",
however, are fully counted. For example, MF_Rows_ functions will come
after all MF_Row_ functions. While most MatrixLib functions have the
prefixes MF_ or M_, please note that some functions have the prefix VF_.
These functions have been included into MatrixLib, because they use
matrix methods. Their prefix is a reminder, however, that their functional
behaviour is aimed at vectors more than on matrices, as in VF_linfit and
other fitting functions. 

void    MF_autocorr( fPMatrix MACorr, fPMatrix MX,
                     unsigned ht, unsigned len );
void    M_CDtoCE( ceMatrix MF, cdMatrix MD, unsigned ht, unsigned len );
void    M_CDtoCF( cfMatrix MF, cdMatrix MD, unsigned ht, unsigned len );
void    M_CEtoCD( cdMatrix MF, ceMatrix MD, unsigned ht, unsigned len );
void    M_CEtoCF( cfMatrix MF, ceMatrix MD, unsigned ht, unsigned len );
void    M_CFtoCD( cdMatrix MF, cfMatrix MD, unsigned ht, unsigned len );
void    M_CFtoCE( ceMatrix MF, cfMatrix MD, unsigned ht, unsigned len );
void    MF_Col_addC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, float C );
void    MF_Col_addV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, fVector X );
void    MF_Col_divC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, float C );
void    MF_Col_divrC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, float C );
void    MF_Col_divrV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, fVector X );
void    MF_Col_divV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, fVector X );
void    MF_Col_equC( fMatrix MA, unsigned ht, unsigned len,
                     unsigned iCol, float C );
void    MF_Col_equV( fMatrix MA, unsigned ht, unsigned len,
                     unsigned iCol, fVector X );
void    MF_Col_extract( fVector Y, fMatrix MA, unsigned ht, unsigned len,
                        unsigned iCol );
void    MF_Col_mulC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, float C );
void    MF_Col_mulV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, fVector X );
void    MF_Col_subC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, float C );
void    MF_Col_subrC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, float C );
void    MF_Col_subV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, fVector X );
void    MF_Col_subrV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iCol, fVector X );
void    MF_Cols_absmax( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_absmin( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_add( fPMatrix MA, unsigned ht, unsigned len,
                     unsigned destCol, unsigned sourceCol );
void    MF_Cols_Cadd( fPMatrix MA, unsigned ht, unsigned len,
                      unsigned destCol, unsigned sourceCol, float C );
void    MF_Cols_exchange( fPMatrix MA, unsigned ht, unsigned len,
                          unsigned i1, unsigned i2 );
void    MF_Cols_lincomb( fPMatrix MA, unsigned ht, unsigned len,
                         unsigned destCol,  float  destC,
                         unsigned srceCol,  float  srceC );
void    MF_Cols_max( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_min( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_prod(fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_reflect( fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_rotate( fPMatrix MA, unsigned ht, unsigned len, int pos );
void    MF_Cols_runprod( fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_runsum( fPMatrix MA, unsigned ht, unsigned len );
void    MF_Cols_sub( fPMatrix MA, unsigned ht, unsigned len,
                     unsigned destCol, unsigned sourceCol );
void    MF_Cols_sum( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_convolve( fPMatrix MY, fPMatrix MFlt, fPMatrix MX,
                     fPMatrix MRsp, unsigned ht, unsigned len );
void    MF_cprint( fPMatrix MA, unsigned ht, unsigned len );
void    MF_deconvolve( fPMatrix MY, fPMatrix MFlt, fPMatrix MX,
                       fPMatrix MRsp, unsigned ht, unsigned len );
float   MF_det( fPMatrix MA, unsigned len );
float   MF_Dia_absmax(  fPMatrix MA, unsigned len );
float   MF_Dia_absmin(  fPMatrix MA, unsigned len );
void    MF_Dia_addC( fMatrix MA, unsigned len, float C );
void    MF_Dia_addV( fMatrix MA, unsigned len, fVector X );
void    MF_Dia_divC( fMatrix MA, unsigned len, float C );
void    MF_Dia_divrC( fMatrix MA, unsigned len, float C );
void    MF_Dia_divrV( fMatrix MA, unsigned len, fVector X );
void    MF_Dia_divV( fMatrix MA, unsigned len, fVector X );
void    MF_Dia_equC( fMatrix MA, unsigned len, float C );
void    MF_Dia_equV( fMatrix MA, unsigned len, fVector X );
void    MF_Dia_extract( fVector Y, fMatrix MA, unsigned len );
float   MF_Dia_max(  fPMatrix MA, unsigned len );
float   MF_Dia_min(  fPMatrix MA, unsigned len );
void    MF_Dia_mulC( fMatrix MA, unsigned len, float C );
void    MF_Dia_mulV( fMatrix MA, unsigned len, fVector X );
float   MF_Dia_prod( fPMatrix MA, unsigned len );
void    MF_Dia_subrC( fMatrix MA, unsigned len, float C );
void    MF_Dia_subrV( fMatrix MA, unsigned len, fVector X );
void    MF_Dia_subC( fMatrix MA, unsigned len, float C );
void    MF_Dia_subV( fMatrix MA, unsigned len, fVector X );
float   MF_Dia_sum(  fPMatrix MA, unsigned len );
void    M_DtoE( eMatrix MF, dMatrix MD, unsigned ht, unsigned len );
void    M_DtoF( fMatrix MF, dMatrix MD, unsigned ht, unsigned len );

float   MF_element( fMatrix X, unsigned ht, unsigned len,
                    unsigned m, unsigned n );
void    MFsym_eigenvalues( fVector EigV, fPMatrix EigM, fPMatrix MA,
                           unsigned len, int CalcEigenVec );
void    MF_equ0( fMatrix MA, unsigned ht, unsigned len );
void    MF_equ1( fMatrix MA, unsigned len );  /* identity matrix */
void    MF_equM( fMatrix MB, fMatrix MA, unsigned ht, unsigned len );
void    M_EtoD( dMatrix MF, eMatrix MD, unsigned ht, unsigned len );
void    M_EtoF( fMatrix MF, eMatrix MD, unsigned ht, unsigned len );
void    MF_filter( fPMatrix MY, fPMatrix MX, fPMatrix MFlt,
                   unsigned ht, unsigned len );
void    MF_FFT( fPMatrix MY, fPMatrix MX,
                 unsigned ht, unsigned len, int dir );
void    M_findDensityMapBounds( extended xmin, extended xmax,
                                extended ymin, extended ymax,
                                extended zmin, extended zmax,
                                COLORREF mincolor, COLORREF maxcolor );
void    MF_fprint( FILE  *stream, fPMatrix MA, unsigned ht,
                     unsigned len, unsigned linewidth );
void    M_free( void **M );
void    M_FtoD( dMatrix MF, fMatrix MD, unsigned ht, unsigned len );
void    M_FtoE( eMatrix MF, fMatrix MD, unsigned ht, unsigned len );
float   VF_getLinfitNeglect( void );
void    VF_getNonlinfitOptions( VF_NONLINFITOPTIONS *Options );
void    MF_Hanning( fMatrix MA, unsigned ht, unsigned len );
int     MF_inv( fPMatrix MInv, fPMatrix MA, unsigned len );
void    MF_LequU( fMatrix MA, unsigned len );
void    VF_linfit( fVector A, iVector AStatus, unsigned npars,
                   fVector X, fVector Y, ui sizex,
                   void (*funcs)(fVector BasFuncs, float x, unsigned nfuncs));
void    VF_linfitwW( fVector A, fPMatrix Covar, iVector AStatus,
                 unsigned npars,
                 fVector X, fVector Y, fVector InvVar, ui sizex,
                 void (*funcs)(fVector BasFuncs, float x, unsigned nfuncs));
void    MF_linfit( fVector A, iVector AStatus, unsigned npars,
               fVector X, fVector Y, fPMatrix MZ, unsigned htZ, unsigned lenZ,
               void (*funcs)(fVector BasFuncs, float x, float y,
                             unsigned nfuncs));
void    MF_linfitwW( fVector A, fPMatrix Covar, iVector AStatus,
                     unsigned npars,
                     fVector X, fVector Y, fPMatrix MZ, fPMatrix MInvVar,
                     unsigned htZ, unsigned lenZ,
                     void (*funcs)(fVector BasFuncs, float x, float y,
                                   unsigned nfuncs));
int     MF_LUdecompose( fPMatrix MLU,  uiVector Ind, fPMatrix MA,
                            unsigned len );
float   MF_LUdet( fPMatrix MLU, unsigned len, int permut );
float   MF_LUDgetEdit( void );
void    MF_LUDsetEdit( float Thresh );
     /*  Editing threshold for MF_LUdecompose; used to cure singularities */
int     MF_LUDresult( void ); /* returns 0, if MF_LUdecompose was successful;
                  returns 1, if MA was (nearly) singular in MF_LUdecompose. */
void    MF_LUinv( fPMatrix MInv, fPMatrix MLU, uiVector Ind,
                      unsigned len );
void    MF_LUsolve( fVector X, fPMatrix MLU, fVector B, uiVector Ind,
                        unsigned len );
void    MF_LUimprove( fVector X, fVector B, fPMatrix MA, fPMatrix MLU,
                          uiVector Ind, unsigned len );
fMatrix MF_matrix( unsigned ht, unsigned len );
fMatrix MF_matrix0( unsigned ht, unsigned len );
void    MF_mulM( fPMatrix MC, fPMatrix MA, fPMatrix MB,
                    unsigned htA, unsigned lenA, unsigned lenB );
void    VF_mulM( fVector Y, fVector X, fPMatrix MA,
                    unsigned sizX, unsigned lenA );
void    MF_mulV( fVector Y, fPMatrix MA, fVector X,
                    unsigned htA, unsigned lenA );
void    MF_multiLinfit( fVector A, iVector AStatus, unsigned npars,
                MF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
                void (*funcs)(fVector BasFuncs, float x, float y,
                              unsigned nfuncs, unsigned iexperiment) );
void    VF_multiLinfit( fVector A, iVector AStatus, unsigned npars,
                VF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
                void (*funcs)(fVector BasFuncs, float x,
                              unsigned nfuncs, unsigned iexperiment) );
void    MF_multiLinfitwW( fVector A, fPMatrix Covar,
                iVector AStatus, unsigned npars,
                MF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
                void (*funcs)(fVector BasFuncs, float x, float y,
                              unsigned nfuncs, unsigned nexperiment) );
void    VF_multiLinfitwW( fVector A, fPMatrix Covar,
                iVector AStatus, unsigned npars,
                VF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
                void (*funcs)(fVector BasFuncs, float x,
                              unsigned nfuncs, unsigned nexperiment) );
float   MF_multiNonlinfit( fVector A, iVector AStatus, unsigned npars,
               MF_EXPERIMENT _VFAR *ListOfExperiments, unsigned nexperiments,
               void (*modelfunc)(fMatrix MZModel, unsigned htZ, unsigned lenZ,
                                 fVector X, fVector Y, unsigned iexperiment),
               void (*derivatives)(fMatrix dZdAi, unsigned htZ, unsigned lenZ,
                                   fVector X, fVector Y, unsigned ipar,
                                   unsigned iexperiment) );
float   VF_multiNonlinfit( fVector A, iVector AStatus, unsigned npars,
               VF_EXPERIMENT _VFAR *ListOfExperiments, unsigned nexperiments,
               void (*modelfunc)(fVector YModel, fVector XModel,
                                 ui size, unsigned iexperiment),
               void (*derivatives)(fVector dYdAi,fVector X, ui size,
                                 unsigned ipar, unsigned iexperiment) );

void    VF_multiNonlinfit_autoDeriv( fVector dYdAi, fVector X, ui size,
                                       unsigned iexperiment, unsigned ipar );
void    MF_multiNonlinfit_autoDeriv(fMatrix dZdAi, unsigned htZ, unsigned lenZ,
                                    fVector X, fVector Y,
                                    unsigned ipar, unsigned iexperiment );
void     MF_multiNonlinfit_getBestA( fVector ABest );
void     VF_multiNonlinfit_getBestA( fVector ABest );
float    MF_multiNonlinfit_getChi2( void );
float    VF_multiNonlinfit_getChi2( void );
int      MF_multiNonlinfit_getTestDir( void );
int      VF_multiNonlinfit_getTestDir( void );
unsigned MF_multiNonlinfit_getTestPar( void );
unsigned VF_multiNonlinfit_getTestPar( void );
unsigned MF_multiNonlinfit_getTestRun( void );
unsigned VF_multiNonlinfit_getTestRun( void );
void     MF_multiNonlinfit_stop( void );
void     VF_multiNonlinfit_stop( void );

float   MF_multiNonlinfitwW( fVector A, fPMatrix Covar,
                iVector AStatus, unsigned npars,
                MF_EXPERIMENT  *ListOfExperiments, unsigned nexperiments,
                void (*modelfunc)(fMatrix MZModel, unsigned htZ, unsigned lenZ,
                                  fVector X, fVector Y, unsigned iexperiment ),
                void (*derivatives)(fMatrix dZdAi, unsigned htZ, unsigned lenZ,
                                    fVector X, fVector Y,
                                    unsigned ipar, unsigned iexperiment) );
float   VF_multiNonlinfitwW( fVector A, fPMatrix Covar,
                iVector AStatus, unsigned npars,
                VF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
                void (*modelfunc)(fVector YModel, fVector X, ui size,
                                  unsigned iexperiment),
                void (*derivatives)(fVector dYdAi, fVector X, ui size,
                                  unsigned ipar, unsigned iexperiment) );
void    MF_multiNonlinfitwW_autoDeriv( fMatrix dZdAi,
                                    unsigned htZ, unsigned lenZ,
                                    fVector X, fVector Y,
                                    unsigned ipar, unsigned iexperiment );
void    VF_multiNonlinfitwW_autoDeriv( fVector dYdAi, fVector X, ui size,
                                       unsigned iexperiment, unsigned ipar );
void     MF_multiNonlinfitwW_getBestA( fVector ABest );
void     VF_multiNonlinfitwW_getBestA( fVector ABest );
float    MF_multiNonlinfitwW_getChi2( void );
float    VF_multiNonlinfitwW_getChi2( void );
int      MF_multiNonlinfitwW_getTestDir( void );
int      VF_multiNonlinfitwW_getTestDir( void );
unsigned MF_multiNonlinfitwW_getTestPar( void );
unsigned VF_multiNonlinfitwW_getTestPar( void );
unsigned MF_multiNonlinfitwW_getTestRun( void );
unsigned VF_multiNonlinfitwW_getTestRun( void );
void     MF_multiNonlinfitwW_stop( void );
void     VF_multiNonlinfitwW_stop( void );


void    M_nfree( unsigned n, ... );
float   MF_nonlinfit( fVector A, iVector AStatus, unsigned npars,
                    fVector X, fVector Y, fPMatrix MZ, unsigned htZ, unsigned lenZ,
                    void (*modelfunc)(fMatrix MZModel, unsigned htZ, unsigned lenZ, fVector X, fVector Y ),
                    void (*derivatives)(fMatrix dZdAi, unsigned htZ, unsigned lenZ, fVector X, fVector Y, unsigned ipar) );
       /* returns figure-of-merit of best A. If you don't know the partial
          derivatives with respect to A, call with derivatives=NULL */
float   MF_nonlinfitwW( fVector A, fPMatrix Covar, iVector AStatus, unsigned npars,
                    fVector X, fVector Y, fPMatrix MZ, fPMatrix MInvVar, unsigned htZ, unsigned lenZ,
                    void (*modelfunc)(fMatrix MZModel, unsigned htZ, unsigned lenZ, fVector X, fVector Y ),
                    void (*derivatives)(fMatrix dZdAi, unsigned htZ, unsigned lenZ, fVector X, fVector Y, unsigned ipar) );
float   VF_nonlinfit( fVector A, iVector AStatus, unsigned npars,
                      fVector X, fVector Y, ui sizex,
                      void (*modelfunc)(fVector YModel, fVector XModel, ui size),
                      void (*derivatives)(fVector dYdAi,fVector X, ui size, unsigned iPar) );
float   VF_nonlinfitwW( fVector A, fPMatrix Covar, iVector AStatus, unsigned npars,
                    fVector X, fVector Y, fVector InvVar, ui sizex,
                    void (*modelfunc)(fVector YModel, fVector X, ui size),
                    void (*derivatives)(fVector dYdAi, fVector X, ui size, unsigned i) );
void    MF_outerprod( fMatrix MA, fVector X,  fVector Y,
                      unsigned ht, unsigned len );
void    MF_Parzen( fMatrix MA, unsigned ht, unsigned len );
float * MF_Pelement( fMatrix X, unsigned ht, unsigned len,
                     unsigned m, unsigned n );
void    VF_polyfit( fVector A, unsigned deg, fVector X, fVector Y, ui sizex );
void    VF_polyfitwW( fVector A, fPMatrix Covar, unsigned deg,
                      fVector X, fVector Y, fVector InvVar, ui sizex );
void    MF_read( fPMatrix X, unsigned ht, unsigned len, FILE  *stream );
void    MF_recall( fMatrix MA, unsigned ht, unsigned len, FILE *stream);
void    MF_Row_addC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, float C );
void    MF_Row_addV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, fVector X );
void    MF_Row_divC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, float C );
void    MF_Row_divrC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, float C );
void    MF_Row_divrV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, fVector X );
void    MF_Row_divV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, fVector X );
void    MF_Row_equC( fMatrix MA, unsigned ht, unsigned len,
                     unsigned iRow, float C );
void    MF_Row_equV( fMatrix MA, unsigned ht, unsigned len,
                     unsigned iRow, fVector X );
void    MF_Row_extract( fVector Y, fMatrix MA, unsigned ht, unsigned len,
                        unsigned iRow );
void    MF_Row_mulC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, float C );
void    MF_Row_mulV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, fVector X );
void    MF_Row_subC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, float C );
void    MF_Row_subrC( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, float C );
void    MF_Row_subrV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, fVector X );
void    MF_Row_subV( fMatrix MA, unsigned ht, unsigned len,
                         unsigned iRow, fVector X );
void    MF_Rows_absmax( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_absmin( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_add( fPMatrix MA, unsigned ht, unsigned len,
                     unsigned destRow, unsigned sourceRow );
void    MF_Rows_Cadd( fPMatrix MA, unsigned ht, unsigned len,
                      unsigned destRow, unsigned sourceRow, float C );
void    MF_Rows_exchange( fPMatrix MA, unsigned ht, unsigned len,
                         unsigned i1, unsigned i2 );
void    MF_Rows_lincomb( fPMatrix MA, unsigned ht, unsigned len,
                         unsigned destRow,  float  destC,
                         unsigned srceRow,  float  srceC );
void    MF_Rows_max( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_min( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_prod(fVector Y, fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_reflect( fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_rotate( fPMatrix MA, unsigned ht, unsigned len, int pos );
void    MF_Rows_runprod( fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_runsum( fPMatrix MA, unsigned ht, unsigned len );
void    MF_Rows_sub( fPMatrix MA, unsigned ht, unsigned len,
                     unsigned destRow, unsigned sourceRow );
void    MF_Rows_sum( fVector Y, fPMatrix MA, unsigned ht, unsigned len );
int     MF_safeSolve( fVector X, fPMatrix MA, fVector B, unsigned len );
              /* ret.value 0: success via LUD; 1: success via SVD; -1: error */

void    M_setDensityMapBounds(  extended xmin, extended xmax,
                                extended ymin, extended ymax,
                                extended zmin, extended zmax,
                                COLORREF mincolor, COLORREF maxcolor );
void    M_setDensityBounds(  extended zmin, extended zmax,
                             COLORREF mincolor, COLORREF maxcolor );

void    VF_setLinfitNeglect( float Thresh );
                /* neglect A[i]=0, if significance smaller than Thresh */
void    VF_setNonlinfitOptions( VF_NONLINFITOPTIONS *Options );
void    MF_setWriteFormat( char *FormatString );
void    MF_setWriteSeparate( char *SepString );
int     MF_solve( fVector X, fPMatrix MA, fVector B, unsigned len );
int     MF_solveBySVD( fVector X, fPMatrix MA, fVector B,
                           unsigned htA, unsigned lenA );
              /*  sizX = lenA,  sizB = htA.  ret.value != 0 signals failure */
void    MF_spectrum( fPMatrix MSpec, unsigned htSpec, unsigned lenSpec,
                     fPMatrix MX, unsigned htX, unsigned lenX,
                     fPMatrix MWin );
          /*   htSpec, lenSpec must be 2**n,
               MSpec has [htSpec+1][lenSpec+1] elements (!)
               htX >= n*htSpec,  lenX >= n*lenSpec,
               htWin = 2*htSpec, lenWin = 2*lenSpec     */

void    MF_store( FILE *str, fMatrix MA, unsigned ht, unsigned len );
void    MF_submatrix( fMatrix MSub,
                      unsigned subHt,  unsigned subLen,
                      fMatrix MSrce,
                      unsigned srceHt,  unsigned srceLen,
                      unsigned firstRowInCol,  unsigned sampInCol,
                      unsigned firstColInRow,  unsigned sampInRow );

void    MF_submatrix_equM( fMatrix MDest,
                           unsigned destHt,  unsigned destLen,
                           unsigned firstRowInCol,  unsigned sampInCol,
                           unsigned firstColInRow,  unsigned sampInRow,
                           fMatrix MSrce,
                           unsigned srceHt,  unsigned srceLen );
int     MF_SVdecompose( fPMatrix MU, fPMatrix MV, fVector W, fPMatrix MA,
                           unsigned htA, unsigned lenA );
void    MF_SVDsetEdit( float Thresh );
float   MF_SVDgetEdit( void ); /* Override of the standard values for editing
                threshholds in MF_SVsolve. Calling MF_setEdit with Thresh=0.0
                means that you do the necessary editing of W yourself before
                calling  MD_SVsolve                           */
void    MF_SVimprove(  fVector X, fVector B, fPMatrix MA,
                       fPMatrix MU, fPMatrix MV, fVector W,
                       unsigned htA, unsigned lenA );
void    MF_SVsolve( fVector X, fPMatrix MU, fPMatrix MV, fVector W,
                       fVector B, unsigned htU, unsigned lenU );
void    MF_transpose( fMatrix MTr, fPMatrix MA,
                       unsigned htTr, unsigned lenTr );
void    MF_UequL( fMatrix MA, unsigned len );
void    MF_Welch( fMatrix MA, unsigned ht, unsigned len );
void    MF_write( FILE  *stream, fPMatrix X, unsigned ht, unsigned len  );
void    MF_xcorr( fPMatrix MXCorr, fPMatrix MX, fPMatrix MY,
                     unsigned ht, unsigned len );
void    MF_xyzAutoDensityMap( fVector X, fVector Y, fMatrix MZ,
                              unsigned ht, unsigned len,
                              COLORREF mincolor, COLORREF maxcolor );
void    MF_xyzDataDensityMap( fVector X, fVector Y, fMatrix MZ,
                              unsigned ht, unsigned len );
void    MFzAutoDensityMap( fMatrix MZ, unsigned ht, unsigned len,
                             COLORREF mincolor, COLORREF maxcolor );
void    MFzDataDensityMap( fMatrix MZ, unsigned ht, unsigned len );


****************************************************************************
*                                                                          *
*******                      E  N  D                                 *******
*                                                                          *
****************************************************************************

Copyright for OptiVec software and documentation
(C) 1996-1999 Martin Sander.
All rights reserved!
