/*
    Theseus - maximum likelihood superpositioning of macromolecular structures

    Copyright (C) 2004-2015 Douglas L. Theobald

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the:

    Free Software Foundation, Inc.,
    59 Temple Place, Suite 330,
    Boston, MA  02111-1307  USA

    -/_|:|_|_\-
*/

#ifndef MATUTILS_SEEN
#define MATUTILS_SEEN

typedef struct
{
    int             rows;
    int             cols;
    int             depth;
    double       ***matrix;
    double        **matrixc;
    double         *matrixd;
} Matrix3D;

void
MatPrint(double **matrix, const int size);

void
MatPrintRec(double **matrix, const int n, const int m);

void
MatDestroy(double ***matrix_ptr);

void
MatCharDestroy(char ***matrix_ptr);

double
**MatAlloc(const int rows, const int cols);

char
**MatCharAlloc(const int rows, const int cols);

void
MatIntDestroy(int ***matrix);

int
**MatIntInit(const int rows, const int cols);

Matrix3D
*Mat3DInit(const int rows, const int cols, const int depth);

void
Mat3DDestroy(Matrix3D **matrix3d_ptr);

double
MatFrobNorm(const double **mat1, const double **mat2, const int row, const int col);

double
MatDiff(const double **mat1, const double **mat2, const int row, const int col);

void
MatCpySqr(double **matrix2, const double **matrix1, const int dim);

void
MatCpyGen(double **matrix2, const double **matrix1, const int rows, const int cols);

void
MatMultGenUSVOp(double **c, const double **u, double *s, const double **v,
                const int udim, const int sdim, const int vdim);

void
MatMultGen(double **C, const double **A, const int ni, const int nk, const double **B, const int nj);

void
MatMultGenIp(double **A, const int nk, const int ni, const double **B, const int nj);

void
MatTransMultGen(double **C, const double **A, const int ni, const int nk, const double **B, const int nj);

void
MatTransMultGenIp(double **A, const int nk, const int ni, const double **B, const int nj);

void
MatMultSym(double **C, const double **A, const double **B, const int len);

void
MatMultSymDiag(double **C, const double **A, const double **B, const int len);

void
MatTransIp(double **mat, const int dim);

void
MatTransOp(double **outmat, const double **inmat, const int dim);

void
cholesky(double **mat, const int dim, double *p);

double
MatDet(const double **mat, const int dim);

double
MatGenLnDet(const double **mat, const int dim);

double
MatSymLnDet(const double **mat, const int dim);

double
MatTrace(const double **mat, const int dim);

int
TestZeroOffDiag(const double **mat, const int dim, const double precision);

int
TestIdentMat(const double **mat, const int dim, const double precision);

double
FrobDiffNormIdentMat(const double **mat, const int dim);

#endif /* !MATRIXUTILS_SEEN */
