
/**
 * \file la.h
 *
 * \brief Wrapper headers for BLAS/LAPACK.
 *
 * This program is free software under the GNU General Public License
 * (>=v2). Read the file COPYING that comes with GRASS for details.
 *
 * \author David D. Gray, ddgray@armacde.demon co uk
 * \author GRASS GIS Development Team
 *
 * \date 2000-2007
 */

#ifndef HAVE_LIBBLAS
#error GRASS GIS is not configured with BLAS (la.h cannot be included)
#endif

#ifndef HAVE_LIBLAPACK
#error GRASS GIS is not configured with LAPACK (la.h cannot be included)
#endif

#ifndef GRASS_LA_H
#define GRASS_LA_H

/* QUESTION: On some systems there appears to be no default link
   to this. Do we create a symlink to
   /usr/lib/gcc-lib/<platform>/<vers_num>/include/g2c.h

   or link to any old f2c.h that happens to hanging around?

   A job for autoconf

   [Also a consideration for -lg2c]
 */

#include <grass/config.h>
#include <stdio.h>

#ifdef HAVE_G2C_H
typedef int __g77_integer;
typedef unsigned int __g77_uinteger;
typedef long int __g77_longint;
typedef unsigned long int __g77_ulongint;
#include <g2c.h>
#else /* for gcc4+ */
typedef int integer;
typedef unsigned int uinteger;
typedef char *address;
typedef short shortint;
typedef float real;
typedef double doublereal;
typedef struct
{
    real r, i;
} complex;
typedef struct
{
    doublereal r, i;
} doublecomplex;
typedef int logical;
typedef short shortlogical;
typedef char logical1;
typedef char integer1;
typedef long longint;
typedef unsigned long ulongint;

/* IO stuff */
typedef int ftnlen;

/* procedure parameter types for -A */
typedef int (*U_fp) ();
typedef shortint(*J_fp) ();
typedef integer(*I_fp) ();
typedef real(*R_fp) ();
typedef doublereal(*D_fp) (), (*E_fp) ();
typedef void (*C_fp) ();
typedef void (*Z_fp) ();
typedef logical(*L_fp) ();
typedef shortlogical(*K_fp) ();
typedef void (*H_fp) ();
typedef int (*S_fp) ();

/* E_fp is for real functions when -R is not specified */
typedef void C_f;		/* complex function                    */
typedef void H_f;		/* character function                  */
typedef void Z_f;		/* double complex function             */
typedef doublereal E_f;		/* real function with -R not specified */
#endif /* HAVE_G2C_H */

/* The following may have to be selectively installed according
   to platform, at least partly
 */

#if defined(HAVE_LIBBLAS) && defined(HAVE_LIBLAPACK)
#include <grass/blas.h>
#include <grass/lapack.h>
#endif


/* Useful defines */

#define MAX_POS          1	/* Indicates maximum value         */
#define MAX_NEG         -1	/* Indicates minimum value         */
#define MAX_ABS          0	/* Indicates absolute value        */

#define DO_COMPACT       0	/* Eliminate unnecessary rows (cols) in matrix  */
#define NO_COMPACT       1	/* ... or not                                    */


/* define macros for fortran symbols (called directly). Needed because 
   of platform invariance on fortran->C symbol translations
 */

#if defined(HAVE_LIBBLAS) && defined(HAVE_LIBLAPACK)
#define f77_dgesv                   dgesv_
#define f77_dgemm                   dgemm_
#define f77_dnrm2                   dnrm2_
#endif

/* Operations should know type of coefficient matrix, so that
   they can call the right driver
 */

typedef enum
{ NONSYM, SYM, HERMITIAN } mat_type;
typedef enum
{ MATRIX_, ROWVEC_, COLVEC_ } mat_spec;
typedef enum
{ RVEC, CVEC } vtype;


/************************************************************
 *                                                          *
 * A general matrix wrapper for use with BLAS / LAPACK      *
 *  routines, and perhaps elsewhere                         *
 *                                                          *
 ************************************************************/

typedef struct matrix_
{

    mat_spec type;		/* matrix, row vector or column vector? */
    int v_indx;			/* If a vector, which row(column) is active?
				 * If a matrix this is ignored. If value is < 0,
				 * the first row(column) is assumed, ie. index 0.  */
    int rows, cols;		/* Rows and columns of matrix */
    int ldim;			/* Lead dimension of matrix. How many `rows' are
				 * alloc'ed? May exceed real number of rows `rows' */
    doublereal *vals;		/* The values (should be dimensioned to lda * cols */
    int is_init;		/* Is  matrix initialised: values array
				 * is allocated and parameters set ?               */
} mat_struct;

typedef mat_struct vec_struct;

#include <grass/defs/la.h>

#endif /* GRASS_LA_H */
