/*  MatLib.h

  two-dimensional-matrix management functions.

  Copyright (c) 1996-2008 by OptiCode - Dr. Martin Sander Software Dev.
  All Rights Reserved.
*/

#ifndef __MATLIB_H
#define __MATLIB_H

#define C_MATRIX 1   /* does your compiler follow the C convention
                        of element ordering?
                        if not, change this line into
                        "   #define C_MATRIX 0   "!
                     */

#ifndef __VECLIB_H
    #include <VecLib.h>
#endif
#if defined( V_HUGE )
     #define   V_DATAPTR  huge
#else
     #define   V_DATAPTR
#endif

/**********************************************************************
 *   The following definitions ensure compatibility between           *
 *   dynamically allocated matrices (e.g., by MF_matrix) and          *
 *   static ones (declared, e.g., by float MA[20][20];                *
 *   for details see MFstd.h                                          */

typedef   char   V_DATAPTR  *           biPMatrix;
typedef   short  V_DATAPTR  *           siPMatrix;
typedef   int    V_DATAPTR  *           iPMatrix;
typedef   long   V_DATAPTR  *           liPMatrix;
typedef   quad   V_DATAPTR  *           qiPMatrix;
typedef   unsigned char  V_DATAPTR *    ubPMatrix;
typedef   unsigned short V_DATAPTR *    usPMatrix;
typedef   unsigned int   V_DATAPTR *    uPMatrix;
typedef   unsigned long  V_DATAPTR *    ulPMatrix;
typedef   ui        V_DATAPTR   *       uiPMatrix;   
typedef   float     V_DATAPTR   *       fPMatrix;
typedef   double    V_DATAPTR   *       dPMatrix;
typedef   extended  V_DATAPTR   *       ePMatrix;
typedef   fComplex  V_DATAPTR   *       cfPMatrix;
typedef   dComplex  V_DATAPTR   *       cdPMatrix;
typedef   eComplex  V_DATAPTR   *       cePMatrix;
typedef   fPolar    V_DATAPTR   *       pfPMatrix;
typedef   dPolar    V_DATAPTR   *       pdPMatrix;
typedef   ePolar    V_DATAPTR   *       pePMatrix;

typedef   biPMatrix  *        biMatrix;
typedef   ubPMatrix  *        ubMatrix;
typedef   siPMatrix  *        siMatrix;
typedef   usPMatrix  *        usMatrix;
typedef   iPMatrix   *        iMatrix;
typedef   uPMatrix   *        uMatrix;
typedef   liPMatrix  *        liMatrix;
typedef   ulPMatrix  *        ulMatrix;
typedef   uiPMatrix  *        uiMatrix;
typedef   qiPMatrix  *        qiMatrix;
typedef   fPMatrix   *        fMatrix;
typedef   dPMatrix   *        dMatrix;
typedef   ePMatrix   *        eMatrix;
typedef   cfPMatrix  *        cfMatrix;
typedef   cdPMatrix  *        cdMatrix;
typedef   cePMatrix  *        ceMatrix;
typedef   pfPMatrix  *        pfMatrix;
typedef   pdPMatrix  *        pdMatrix;
typedef   pePMatrix  *        peMatrix;

#ifdef __cplusplus
extern "C" {
#endif

/*************   Dynamic Generation of Matrices   ************************
          defined here only for the integer and polar-complex
          data types;
          for the floating-point types, see <MFstd.h> etc.
          For integer and polar-complex matrices, these are the 
          only functions so far included in MatrixLib.                   */

biMatrix __vf  MBI_matrix(  unsigned ht, unsigned len );
biMatrix __vf  MBI_matrix0( unsigned ht, unsigned len );
ubMatrix __vf  MUB_matrix(  unsigned ht, unsigned len );
ubMatrix __vf  MUB_matrix0( unsigned ht, unsigned len );
siMatrix __vf  MSI_matrix(  unsigned ht, unsigned len );
siMatrix __vf  MSI_matrix0( unsigned ht, unsigned len );
usMatrix __vf  MUS_matrix(  unsigned ht, unsigned len );
usMatrix __vf  MUS_matrix0( unsigned ht, unsigned len );
iMatrix  __vf  MI_matrix(   unsigned ht, unsigned len );
iMatrix  __vf  MI_matrix0(  unsigned ht, unsigned len );
uMatrix  __vf  MU_matrix(   unsigned ht, unsigned len );
uMatrix  __vf  MU_matrix0(  unsigned ht, unsigned len );
liMatrix __vf  MLI_matrix(  unsigned ht, unsigned len );
liMatrix __vf  MLI_matrix0( unsigned ht, unsigned len );
ulMatrix __vf  MUL_matrix(  unsigned ht, unsigned len );
ulMatrix __vf  MUL_matrix0( unsigned ht, unsigned len );
qiMatrix __vf  MQI_matrix(  unsigned ht, unsigned len );
qiMatrix __vf  MQI_matrix0( unsigned ht, unsigned len );
pfMatrix __vf  MPF_matrix(  unsigned ht, unsigned len );
pfMatrix __vf  MPF_matrix0( unsigned ht, unsigned len );
pdMatrix __vf  MPD_matrix(  unsigned ht, unsigned len );
pdMatrix __vf  MPD_matrix0( unsigned ht, unsigned len );
peMatrix __vf  MPE_matrix(  unsigned ht, unsigned len );
peMatrix __vf  MPE_matrix0( unsigned ht, unsigned len );
#if defined (_MSC_VER) && defined (_DEBUG)
    biMatrix __vf  MBI_matrix_dbg(  unsigned ht, unsigned len );
    biMatrix __vf  MBI_matrix0_dbg( unsigned ht, unsigned len );
    ubMatrix __vf  MUB_matrix_dbg(  unsigned ht, unsigned len );
    ubMatrix __vf  MUB_matrix0_dbg( unsigned ht, unsigned len );
    siMatrix __vf  MSI_matrix_dbg(  unsigned ht, unsigned len );
    siMatrix __vf  MSI_matrix0_dbg( unsigned ht, unsigned len );
    usMatrix __vf  MUS_matrix_dbg(  unsigned ht, unsigned len );
    usMatrix __vf  MUS_matrix0_dbg( unsigned ht, unsigned len );
    iMatrix  __vf  MI_matrix_dbg(   unsigned ht, unsigned len );
    iMatrix  __vf  MI_matrix0_dbg(  unsigned ht, unsigned len );
    uMatrix  __vf  MU_matrix_dbg(   unsigned ht, unsigned len );
    uMatrix  __vf  MU_matrix0_dbg(  unsigned ht, unsigned len );
    liMatrix __vf  MLI_matrix_dbg(  unsigned ht, unsigned len );
    liMatrix __vf  MLI_matrix0_dbg( unsigned ht, unsigned len );
    ulMatrix __vf  MUL_matrix_dbg(  unsigned ht, unsigned len );
    ulMatrix __vf  MUL_matrix0_dbg( unsigned ht, unsigned len );
    qiMatrix __vf  MQI_matrix_dbg(  unsigned ht, unsigned len );
    qiMatrix __vf  MQI_matrix0_dbg( unsigned ht, unsigned len );
    pfMatrix __vf  MPF_matrix_dbg(  unsigned ht, unsigned len );
    pfMatrix __vf  MPF_matrix0_dbg( unsigned ht, unsigned len );
    pdMatrix __vf  MPD_matrix_dbg(  unsigned ht, unsigned len );
    pdMatrix __vf  MPD_matrix0_dbg( unsigned ht, unsigned len );
    peMatrix __vf  MPE_matrix_dbg(  unsigned ht, unsigned len );
    peMatrix __vf  MPE_matrix0_dbg( unsigned ht, unsigned len );
    #if defined (_INC_CRTDBG) && defined (_CRTDBG_MAP_ALLOC) 
	    /* Automatic mapping for memory-leak detection by CRT debugging switched on? */ 
        #define MBI_matrix  MBI_matrix_dbg
        #define MBI_matrix0 MBI_matrix0_dbg 
        #define MUB_matrix  MUB_matrix_dbg
        #define MUB_matrix0 MUB_matrix0_dbg 
        #define MSI_matrix  MSI_matrix_dbg
        #define MSI_matrix0 MSI_matrix0_dbg 
        #define MUS_matrix  MUS_matrix_dbg
        #define MUS_matrix0 MUS_matrix0_dbg 
        #define MI_matrix   MI_matrix_dbg
        #define MI_matrix0  MI_matrix0_dbg 
        #define MU_matrix   MU_matrix_dbg
        #define MU_matrix0  MU_matrix0_dbg 
        #define MLI_matrix  MLI_matrix_dbg
        #define MLI_matrix0 MLI_matrix0_dbg 
        #define MUL_matrix  MUL_matrix_dbg
        #define MUL_matrix0 MUL_matrix0_dbg 
        #define MQI_matrix  MQI_matrix_dbg
        #define MQI_matrix0 MQI_matrix0_dbg 
        #define MPF_matrix  MPF_matrix_dbg
        #define MPF_matrix0 MPF_matrix0_dbg 
        #define MPD_matrix  MPD_matrix_dbg
        #define MPD_matrix0 MPD_matrix0_dbg 
        #define MPE_matrix  MPE_matrix_dbg
        #define MPE_matrix0 MPE_matrix0_dbg 
    #endif
#else
    #define MBI_matrix_dbg  MBI_matrix
    #define MBI_matrix0_dbg MBI_matrix0
    #define MUB_matrix_dbg  MUB_matrix
    #define MUB_matrix0_dbg MUB_matrix0
    #define MSI_matrix_dbg  MSI_matrix
    #define MSI_matrix0_dbg MSI_matrix0
    #define MUS_matrix_dbg  MUS_matrix
    #define MUS_matrix0_dbg MUS_matrix0
    #define MI_matrix_dbg   MI_matrix
    #define MI_matrix0_dbg  MI_matrix0
    #define MU_matrix_dbg   MU_matrix
    #define MU_matrix0_dbg  MU_matrix0
    #define MLI_matrix_dbg  MLI_matrix
    #define MLI_matrix0_dbg MLI_matrix0
    #define MUL_matrix_dbg  MUL_matrix
    #define MUL_matrix0_dbg MUL_matrix0
    #define MQI_matrix_dbg  MQI_matrix
    #define MQI_matrix0_dbg MQI_matrix0
    #define MPF_matrix_dbg  MPF_matrix
    #define MPF_matrix0_dbg MPF_matrix0
    #define MPD_matrix_dbg  MPD_matrix
    #define MPD_matrix0_dbg MPD_matrix0
    #define MPE_matrix_dbg  MPE_matrix
    #define MPE_matrix0_dbg MPE_matrix0
#endif
#if defined( V_HUGE )
   #define MUI_matrix  MUL_matrix
   #define MUI_matrix0 MUL_matrix0
#else
   #define MUI_matrix  MU_matrix
   #define MUI_matrix0 MU_matrix0
   #define MUI_matrix_dbg  MU_matrix_dbg
   #define MUI_matrix0_dbg MU_matrix0_dbg
#endif
    /*  notice that, in the memory model HUGE,
        neither len nor ht may exceed 32767/sizeof(type)            */

 /* the following functions allocate pointer vectors and pointer matrices: */ 
#if defined __COMPACT__ || defined __LARGE__ || defined __HUGE__
    #define VUP_vector  VUL_vector  /* pointer to vector */
    #define MUP_matrix  MUL_matrix  /* pointer to matrix */
#else
    #define VUP_vector  VU_vector
    #define MUP_matrix  MU_matrix
    #define VUP_vector_dbg  VU_vector_dbg
    #define MUP_matrix_dbg  MU_matrix_dbg
#endif

/*   de-allocation of matrices (common to all data types): */

void    __vf  Mfree( void **M );
#define M_free( M ) Mfree( (void **)(M) )
void    __vf  M_nfree( unsigned n, ... );
#if defined (_MSC_VER) && defined (_DEBUG) 
    void    __vf  Mfree_dbg( void **M );
    #define M_free_dbg( M ) Mfree_dbg( (void **)(M) )
    void    __vf  M_nfree_dbg( unsigned n, ... );
    #if defined (_INC_CRTDBG) && defined (_CRTDBG_MAP_ALLOC) 
	    /* Automatic mapping for memory-leak detection by CRT debugging switched on? */ 
        #define Mfree   Mfree_dbg
        #define M_free  M_free_dbg
        #define M_nfree M_nfree_dbg
    #endif
#else
    #define Mfree_dbg   Mfree
    #define M_free_dbg  M_free
    #define M_nfree_dbg M_nfree
#endif

#ifdef __cplusplus
}  // end of extern "C"
#endif

#undef V_DATAPTR
#endif   /* __MATLIB_H  */
