/*
    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 DLTMATH_SEEN
#define DLTMATH_SEEN

#define MY_E             2.7182818284590452354   /* e */
#define MY_LOG2E         1.4426950408889634074   /* log 2e */
#define MY_LOG10E        0.43429448190325182765112891891660508229439700580367   /* log 10e */
#define MY_LN2           0.69314718055994530942  /* log e2 */
#define MY_LN10          2.30258509299404568402  /* log e10 */
#define MY_PI            3.14159265358979323846264338327950288419716939937511   /* pi */
#define MY_PI_SQR        9.86960440108935861883449099987615113531369940724079   /* pi^2 */
#define MY_PI_2          1.57079632679489661923  /* pi/2 */
#define MY_PI_4          0.78539816339744830962  /* pi/4 */
#define MY_1_PI          0.31830988618379067153776752674502872406891929148091   /* 1/pi */
#define MY_2_PI          0.63661977236758134308  /* 2/pi */
#define MY_2_SQRTPI      1.12837916709551257390  /* 2/sqrt(pi) */
#define MY_SQRT2         1.41421356237309504880168872420969807856967187537695   /* sqrt(2) */
#define MY_SQRT1_2       0.70710678118654752440  /* 1/sqrt(2) */
#define MY_BFACT        78.956835208714863938439521007239818572998046875        /* 8 * (pi)^2 */
#define MY_1_BFACT       0.0126651479552922219262711678311461582779884338378906 /* 1/BFACT */
#define MY_EULER         0.577215664901532860606512090082

#define SCREAMS(string_val)  fprintf(stderr, "\n!SCREAMS! %s:%d:%s= %s", __FILE__, __LINE__, #string_val,  string_val);  fflush(NULL)
#define SCREAMC(char_val)    fprintf(stderr, "\n!SCREAMC! %s:%d:%s= %c", __FILE__, __LINE__, #char_val,    char_val);    fflush(NULL)
#define SCREAMD(integer_val) fprintf(stderr, "\n!SCREAMD! %s:%d:%s= %d", __FILE__, __LINE__, #integer_val, integer_val); fflush(NULL)
#define SCREAMF(double_val)  fprintf(stderr, "\n!SCREAMF! %s:%d:%s= %f", __FILE__, __LINE__, #double_val,  double_val);  fflush(NULL)
#define SCREAME(double_val)  fprintf(stderr, "\n!SCREAME! %s:%d:%s= %e", __FILE__, __LINE__, #double_val,  double_val);  fflush(NULL)
#define SCREAMP(pointer_val) fprintf(stderr, "\n!SCREAMP! %s:%d:%s= %p", __FILE__, __LINE__, #pointer_val,  pointer_val);  fflush(NULL)
#define BUFFLEN          FILENAME_MAX
/*#define FILENAME_MAX  FILENAME_MAX*/
#define MAX(a,b) ((a) < (b) ? (b) : (a)) /* can't deal with side effects, side DON'T USE THEM */
#define MIN(a,b) ((a) > (b) ? (b) : (a)) /* can't deal with side effects, side DON'T USE THEM */
#define SQR(a) ((a)*(a))
#define CUBE(a) ((a)*(a)*(a))
#define POW4(a) ((a)*(a)*(a)*(a))
#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))

#ifndef MAT3UTILS_SEEN
#define MAT3UTILS_SEEN

void
Mat3Print(double **matrix);

double
**Mat3Ident(double **matrix);

int
Mat3Eq(const double **matrix1, const double **matrix2, const double precision);

int
Mat3FrobEq(const double **matrix1, const double **matrix2, const double precision);

void
Mat3Cpy(double **matrix2, const double **matrix1);

void
Mat3MultOp(double **C, const double **A, const double **B);

void
Mat3MultIp(double **A, const double **B);

void
Mat3MultUSVOp(double **C, const double **U, double *S, const double **V);

void
Mat3PreMultIp(const double **A, double **B);

void
Mat3Sqr(double **C, const double **A);

void
Mat3SqrTrans2(double **C, const double **A);

void
Mat3SqrTrans1(double **C, const double **A);

void
Mat3TransSqr(double **C, const double **A);

void
Mat3MultTransA(double **C, const double **A, const double **B);

void
Mat3MultTransB(double **C, const double **A, const double **B);

void
Mat3Add(double **C, const double **A, const double **B);

void
Mat3Sub(double **A, double **B, double **C);

void
Mat3TransposeIp(double **matrix);

void
Mat3TransposeOp(double **matrix2, const double **matrix1);

double
Mat3Det(const double **matrix);

void
Mat3Invert(double **outmat, const double **inmat);

void
Mat3SymInvert(double **outmat, const double **inmat);

void
Mat3MultVec(double *outv, const double **inmat, const double *vec);

int
VerifyRotMat(double **rotmat, double tol);

double
**ClosestRotMat(double **inmat);

void
ClosestRotMatIp(double **inmat);

double
RotMat2AxisAngle(double **rot, double *v);

#endif /* !MATRIXUTILS_SEEN */ 
#ifndef MAT4UTILS_SEEN
#define MAT4UTILS_SEEN

void
Mat4Print(double **matrix);

void
Mat4Copy(double **matrix2, const double **matrix1);

void
Mat4TransposeIp(double **matrix);

void
Mat4TransposeOp(double **matrix2, const double **matrix1);

#endif /* !MATRIXUTILS_SEEN */ 
#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);

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

void
MatIntDestroy(int ***matrix_ptr);

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
MatCpySqrgen(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 */ 
#ifndef REGGAMMA_SEEN
#define REGGAMMA_SEEN

/* double */
/* IncompleteGamma (double theA, double theX); */
/*  */
/* double */
/* regularizedGammaP(double a, double x, double epsilon, int maxIterations); */
/*  */
/* double */
/* regularizedGammaQ(double a, double x, double epsilon, int maxIterations); */
/*  */
/* double */
/* gamain( double x, double p, double g ); */
/*  */
/* double */
/* gamln( double x ); */
/*  */
/* void */
/* grat1(double a, double x, double r, double *p, double *q, */
/*           double eps); */

double
InBeta(double a, double b, double x);

double
InGamma(double a, double x);

double
InGammaQ(double a, double x);

double
InGammaP(double a, double x);

#endif
#ifndef VECUTILS_SEEN
#define VECUTILS_SEEN

void
VecPrint(double *vec, const int size);

void
InvRotVec(double *newvec, double *vec, double **rotmat);

void
RotVec(double *newvec, double *vec, double **rotmat);

int
VecEq(const double *vec1, const double *vec2, const int len, const double tol);

void
RevVecIp(double *vec, const int len);

double
VecSmallest(double *vec, const int len);

double
VecBiggest(double *vec, const int len);

#endif /* !MATRIXUTILS_SEEN */ 
#ifndef EIGEN_SEEN
#define EIGEN_SEEN

double
*NormalizeVec(double *vect);

void
EigenSort(double **eigenvectors, double *eigenvalues);

void
EigenSort3(double **eigenvectors, double *eigenvalues, double *tmpevec);

void
EigenSort3b(double **eigenvectors, double *eigenvalues);

void
EigenSort4(double **eigenvectors, double *eigenvalues);

void
EvalSort4(double *eigenvalues);

void
CopyEvec(double *evec1, double *evec2, int length);

void
SwapEvec(double *evec1, double *evec2, int length);

void
Swap3Evec(double *evec1, double *evec2, double *tmpevec);

void
eigen3(double **z, double *eigenval);

void
Eigen4Min(double **eigenvectors, double *eigenvalues);

void
eigen4(double **Q, double *eigenval);

void
eigenval4(double **Q, double *eigenval);

double
pythag(double a, double b);

void
tred24(double **a, double *d, double *e);

void
tred24vals(double **a, double *d, double *e);

void
tqli4(double *d, double *e, double **z);

void
tqli4vals(double *d, double *e, double **z);

int
jacobi3(double **a, double *d, double **v, double tol);

int
jacobi3_cyc(double **a, double *d, double **v, double tol);

void
jacobi4(double **a, double *d, double **v);

void
rotate(double **a, double s, double tau,
       int i, int j, int k, int l);

double
InvSymEigenOp(double **invmat, const double **mat, int n,
              double *evals, double **evecs, const double tol);

void
eigensym(const double **mat, double *evals, double **evecs, int n);

void
eigensym2(const double **mat, double *evals, double **evecs, int n, double *work);

void
eigenvalsym(const double **mat, double *evals, double **evecs, int n);

void
eigenvalsym2(const double **mat, double *evals, double **evecs, int n, double *work);

void
eigengen(const double **mat, double *evals, double **evecs, int n);

void
transevecs(double **mat, int len);

void
eigen_quicksort(double *evals, double **evecs, int len);

void
EigenReconSym(double **mat, const double **evecs, const double *evals, const int n);

int
SymbolicEigen4 (double **mat, double *evals);

#endif

#ifndef INTEGRATE_SEEN
#define INTEGRATE_SEEN

double
trapzd(double (*func)(double, double, double),
       double param1, double param2, double a, double b, int n);

double
integrate_qsimp(double (*func)(double, double, double),
                double param1, double param2, double a, double b);

double
integrate_romberg(double (*f)(double a, double p1, double p2),
                  double p1, double p2, double a, double b);

#endif


void
matinv(double **a, double **outmat, int N, int *indx);

void
lubksb(double **a, int n, int *indx, double b[]);

void
ludcmp(double **a, int n, int *indx, double *d);
#ifndef MYRANDOM_SEEN
#define MYRANDOM_SEEN

void
init_genrand(unsigned long s);

void
init_by_array(unsigned long init_key[], unsigned long key_length);

unsigned long
genrand_int32(void);

long
genrand_int31(void);

double
genrand_real1(void);

double
genrand_real2(void);

double
genrand_real3(void);

double
genrand_res53(void);

double
expondev(void);

double
gaussdev(void);

double
Normal(void);

void
shuffle(int *a, int n);

void
shufflef(double *a, int n);

#endif
#ifndef ALGO_BLAST_CORE__NCBIMATH
#define ALGO_BLAST_CORE__NCBIMATH

/* $Id: ncbi_math.h,v 1.11 2005/03/10 16:12:59 papadopo Exp $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
 *
 *  This software/database is a "United States Government Work" under the
 *  terms of the United States Copyright Act.  It was written as part of
 *  the author's official duties as a United States Government employee and
 *  thus cannot be copyrighted.  This software/database is freely available
 *  to the public for use. The National Library of Medicine and the U.S.
 *  Government have not placed any restriction on its use or reproduction.
 *
 *  Although all reasonable efforts have been taken to ensure the accuracy
 *  and reliability of the software and data, the NLM and the U.S.
 *  Government do not and cannot warrant the performance or results that
 *  may be obtained by using this software or data. The NLM and the U.S.
 *  Government disclaim all warranties, express or implied, including
 *  warranties of performance, merchantability or fitness for any particular
 *  purpose.
 *
 *  Please cite the author in any work or product based on this material.
 *
 * ===========================================================================
 *
 * Authors:  Gish, Kans, Ostell, Schuler
 *
 * Version Creation Date:   10/23/91
 *
 * ==========================================================================
 */

/** @file ncbi_math.h
 * Prototypes for portable math library (ported from C Toolkit)
 */

/*#include <algo/blast/core/ncbi_std.h> 
#include <algo/blast/core/blast_export.h>*/

double 
s_PolyGamma(double x, int order);

/** Natural logarithm with shifted input
 *  @param x input operand (x > -1)
 *  @return log(x+1)
 */
 
double BLAST_Log1p (double x);

/** Exponentional with base e 
 *  @param x input operand
 *  @return exp(x) - 1
 */
 
double BLAST_Expm1 (double x);

/** Factorial function
 *  @param n input operand
 *  @return (double)(1 * 2 * 3 * ... * n)
 */
 
double BLAST_Factorial(int n);

/** Logarithm of the factorial 
 *  @param x input operand
 *  @return log(1 * 2 * 3 * ... * x)
 */
 
double BLAST_LnFactorial (double x);

/** log(gamma(n)), integral n 
 *  @param n input operand
 *  @return log(1 * 2 * 3 * ... (n-1))
 */
 
double BLAST_LnGammaInt (int n);

/** Romberg numerical integrator 
 *  @param f Pointer to the function to integrate; the first argument
 *               is the variable to integrate over, the second is a pointer
 *               to a list of additional arguments that f may need
 *  @param fargs Pointer to an array of extra arguments or parameters
 *               needed to compute the function to be integrated. None
 *               of the items in this list may vary over the region
 *               of integration
 *  @param p Left-hand endpoint of the integration interval
 *  @param q Right-hand endpoint of the integration interval
 *           (q is assumed > p)
 *  @param eps The relative error tolerance that indicates convergence
 *  @param epsit The number of consecutive diagonal entries in the 
 *               Romberg array whose relative difference must be less than
 *               eps before convergence is assumed. This is presently 
 *               limited to 1, 2, or 3
 *  @param itmin The minimum number of diagnonal Romberg entries that
 *               will be computed
 *  @return The computed integral of f() between p and q
 */
 
double BLAST_RombergIntegrate (double (*f) (double, void*), 
                               void* fargs, double p, double q, 
                               double eps, int epsit, int itmin);

/** Greatest common divisor 
 *  @param a First operand (any integer)
 *  @param b Second operand (any integer)
 *  @return The largest integer that evenly divides a and b
 */
 
int BLAST_Gcd (int a, int b);

/** Divide 3 numbers by their greatest common divisor
 * @param a First integer [in] [out]
 * @param b Second integer [in] [out]
 * @param c Third integer [in] [out]
 * @return The greatest common divisor
 */
 
int BLAST_Gdb3(int* a, int* b, int* c);

/** Nearest integer 
 *  @param x Input to round (rounded value must be representable
 *           as a 32-bit signed integer)
 *  @return floor(x + 0.5);
 */
 
long BLAST_Nint (double x);

/** Integral power of x 
 * @param x floating-point base of the exponential
 * @param n (integer) exponent
 * @return x multiplied by itself n times
 */
 
double BLAST_Powi (double x, int n);

/** Number of derivatives of log(x) to carry in gamma-related 
    computations */
#define LOGDERIV_ORDER_MAX    4  
/** Number of derivatives of polygamma(x) to carry in gamma-related 
    computations for non-integral values of x */
#define POLYGAMMA_ORDER_MAX    LOGDERIV_ORDER_MAX

/** value of pi is only used in gamma-related computations */
#define NCBIMATH_PI    3.1415926535897932384626433832795

/** Natural log(2) */
#define NCBIMATH_LN2    0.69314718055994530941723212145818
/** Natural log(PI) */
#define NCBIMATH_LNPI    1.1447298858494001741434273513531

#ifdef __cplusplus
}
#endif

/*
 * ===========================================================================
 *
 * $Log: ncbi_math.h,v $
 * Revision 1.11  2005/03/10 16:12:59  papadopo
 * doxygen fixes
 *
 * Revision 1.10  2004/11/18 21:22:10  dondosha
 * Added BLAST_Gdb3, used in greedy alignment; removed extern and added  to all prototypes
 *
 * Revision 1.9  2004/11/02 13:54:33  papadopo
 * small doxygen fixes
 *
 * Revision 1.8  2004/11/01 16:37:57  papadopo
 * Add doxygen tags, remove unused constants
 *
 * Revision 1.7  2004/05/19 14:52:01  camacho
 * 1. Added doxygen tags to enable doxygen processing of algo/blast/core
 * 2. Standardized copyright, CVS $Id string, $Log and rcsid formatting and i
 *    location
 * 3. Added use of @todo doxygen keyword
 *
 * Revision 1.6  2003/09/26 20:38:12  dondosha
 * Returned prototype for the factorial function (BLAST_Factorial)
 *
 * Revision 1.5  2003/09/26 19:02:31  madden
 * Prefix ncbimath functions with BLAST_
 *
 * Revision 1.4  2003/09/10 21:35:20  dondosha
 * Removed Nlm_ prefix from math functions
 *
 * Revision 1.3  2003/08/25 22:30:24  dondosha
 * Added LnGammaInt definition and Factorial prototype
 *
 * Revision 1.2  2003/08/11 14:57:16  dondosha
 * Added algo/blast/core path to all #included headers
 *
 * Revision 1.1  2003/08/02 16:32:11  camacho
 * Moved ncbimath.h -> ncbi_math.h
 *
 * Revision 1.2  2003/08/01 21:18:48  dondosha
 * Correction of a #include
 *
 * Revision 1.1  2003/08/01 21:03:40  madden
 * Cleaned up version of file for C++ toolkit
 *
 * ===========================================================================
 */


#endif /* !ALGO_BLAST_CORE__NCBIMATH */

#ifndef QUICKSORT_SEEN
#define QUICKSORT_SEEN

/*---------------       quicksort.h              --------------*/
/*
 * The key TYPE.
 * COARRAY_T is the type of the companion array
 * The keys are the array items moved with the SWAP macro
 * around using the SWAP macro.
 * the comparison macros can compare either the key or things
 * referenced by the key (if its a pointer)
 */ 
typedef double      KEY_T;
typedef char       *COARRAY_T;
/*
 * The comparison macros:
 *
 *  GT(x, y)  as   (strcmp((x),(y)) > 0)
 *  LT(x, y)  as   (strcmp((x),(y)) < 0)
 *  GE(x, y)  as   (strcmp((x),(y)) >= 0)
 *  LE(x, y)  as   (strcmp((x),(y)) <= 0)
 *  EQ(x, y)  as   (strcmp((x),(y)) == 0)
 *  NE(x, y)  as   (strcmp((x),(y)) != 0)
 */
#define GT(x, y) ((x) > (y))
#define LT(x, y) ((x) < (y))
#define GE(x, y) ((x) >= (y))
#define LE(x, y) ((x) <= (y))
#define EQ(x, y) ((x) == (y))
#define NE(x, y) ((x) != (y))

/*
 * Swap macro:
 */
 
/* double              tempd; */
/* char               *tempc; */
/*  */
/* #define SWAPD(x, y) tempd = (x); (x) = (y); (y) = tempd */
/* #define SWAPC(x, y) tempc = (x); (x) = (y); (y) = tempc */

extern void
swapd(double *x, double *y);

extern void
swapc(char **x, char **y);

extern void
insort2 (KEY_T *array1, COARRAY_T *array2, int len);

extern void
insort2d (KEY_T *array1, KEY_T *array2, int len);

extern void
insort (KEY_T *array1, int len);

extern void
partial_quicksort2 (KEY_T *array1, COARRAY_T *array2, int lower, int upper);

extern void
partial_quicksort2d (KEY_T *array1, KEY_T *array2, int lower, int upper);

extern void
partial_quicksort (KEY_T *array, int lower, int upper);

extern void
quicksort2 (KEY_T *array1, COARRAY_T *array2, int len);

extern void
quicksort2d (KEY_T *array1, KEY_T *array2, int len);

extern void
quicksort (KEY_T *array, int len);

#endif
/* ------------------------------------------------------------- 
 * Name            : rvms.h (header file for the library rvms.c) 
 * Author          : Steve Park & Dave Geyer
 * Language        : ANSI C
 * Latest Revision : 11-02-96
 * -------------------------------------------------------------- 
 */

#if !defined( _RVMS_ )
#define _RVMS_

double LogFactorial(long n);
double LogChoose(long n, long m);

double pdfBernoulli(double p, long x);
double cdfBernoulli(double p, long x);
long   idfBernoulli(double p, double u);

double pdfEquilikely(long a, long b, long x);
double cdfEquilikely(long a, long b, long x);
long   idfEquilikely(long a, long b, double u);

double pdfBinomial(long n, double p, long x);
double cdfBinomial(long n, double p, long x);
long   idfBinomial(long n, double p, double u);

double pdfGeometric(double p, long x);
double cdfGeometric(double p, long x);
long   idfGeometric(double p, double u);

double pdfPascal(long n, double p, long x);
double cdfPascal(long n, double p, long x);
long   idfPascal(long n, double p, double u);

double pdfPoisson(double m, long x);
double cdfPoisson(double m, long x);
long   idfPoisson(double m, double u);

double pdfUniform(double a, double b, double x);
double cdfUniform(double a, double b, double x);
double idfUniform(double a, double b, double u);

double pdfExponential(double m, double x);
double cdfExponential(double m, double x);
double idfExponential(double m, double u);

double pdfErlang(long n, double b, double x);
double cdfErlang(long n, double b, double x);
double idfErlang(long n, double b, double u);

double pdfNormal(double m, double s, double x);
double cdfNormal(double m, double s, double x);
double idfNormal(double m, double s, double u);

double pdfLognormal(double a, double b, double x);
double cdfLognormal(double a, double b, double x);
double idfLognormal(double a, double b, double u);

double pdfChisquare(long n, double x);
double cdfChisquare(long n, double x);
double idfChisquare(long n, double u);

double pdfStudent(long n, double x);
double cdfStudent(long n, double x);
double idfStudent(long n, double u);

#endif
#ifndef SPECFUNC_SEEN
#define SPECFUNC_SEEN

double
BesselI(const double nu, const double z);

double
BesselI0(const double z);

double
BesselI1(const double z);

double
bessi(const int n, const double x);

double
bessi0(const double x);

double
bessi1(const double x);

double
UpperIncompleteGamma(const double a, const double x);

double
gammp(const double a, const double x);

double
gammq(const double a, const double x);

double
gcf(double a, double x);

double
gser(double a, double x);

double
IncompleteGamma(const double x, const double alpha);

double
lngamma(const double xx);

double
mygamma(const double xx);

double
harmonic(int x);

double
polygamma(int k, double x);

double
betai(double a, double b, double x);

double
betacf(double a, double b, double x);

double
beta(double z, double w);

double
mysquare(const double val);

double
mycube(const double val);

double
mypow4(double val);

#endif
#ifndef MAT3UTILS_SEEN
#define MAT3UTILS_SEEN

void
Mat3Print(double **matrix);

double
**Mat3Ident(double **matrix);

int
Mat3Eq(const double **matrix1, const double **matrix2, const double precision);

int
Mat3FrobEq(const double **matrix1, const double **matrix2, const double precision);

void
Mat3Cpy(double **matrix2, const double **matrix1);

void
Mat3MultOp(double **C, const double **A, const double **B);

void
Mat3MultIp(double **A, const double **B);

void
Mat3MultUSVOp(double **C, const double **U, double *S, const double **V);

void
Mat3PreMultIp(const double **A, double **B);

void
Mat3Sqr(double **C, const double **A);

void
Mat3SqrTrans2(double **C, const double **A);

void
Mat3SqrTrans1(double **C, const double **A);

void
Mat3TransSqr(double **C, const double **A);

void
Mat3MultTransA(double **C, const double **A, const double **B);

void
Mat3MultTransB(double **C, const double **A, const double **B);

void
Mat3Add(double **C, const double **A, const double **B);

void
Mat3Sub(double **A, double **B, double **C);

void
Mat3TransposeIp(double **matrix);

void
Mat3TransposeOp(double **matrix2, const double **matrix1);

double
Mat3Det(const double **matrix);

void
Mat3Invert(double **outmat, const double **inmat);

void
Mat3SymInvert(double **outmat, const double **inmat);

void
Mat3MultVec(double *outv, const double **inmat, const double *vec);

int
VerifyRotMat(double **rotmat, double tol);

double
**ClosestRotMat(double **inmat);

void
ClosestRotMatIp(double **inmat);

#endif /* !MATRIXUTILS_SEEN */ 
#ifndef MAT4UTILS_SEEN
#define MAT4UTILS_SEEN

void
Mat4Print(double **matrix);

void
Mat4Copy(double **matrix2, const double **matrix1);

void
Mat4TransposeIp(double **matrix);

void
Mat4TransposeOp(double **matrix2, const double **matrix1);

#endif /* !MATRIXUTILS_SEEN */ 
#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);

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

void
MatIntDestroy(int ***matrix_ptr);

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
MatCpySqrgen(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 */ 
#ifndef REGGAMMA_SEEN
#define REGGAMMA_SEEN

/* double */
/* IncompleteGamma (double theA, double theX); */
/*  */
/* double */
/* regularizedGammaP(double a, double x, double epsilon, int maxIterations); */
/*  */
/* double */
/* regularizedGammaQ(double a, double x, double epsilon, int maxIterations); */
/*  */
/* double */
/* gamain( double x, double p, double g ); */
/*  */
/* double */
/* gamln( double x ); */
/*  */
/* void */
/* grat1(double a, double x, double r, double *p, double *q, */
/*           double eps); */

double
InBeta(double a, double b, double x);

double
InGamma(double a, double x);

double
InGammaQ(double a, double x);

double
InGammaP(double a, double x);

#endif
#ifndef VECUTILS_SEEN
#define VECUTILS_SEEN

void
VecPrint(double *vec, const int size);

void
InvRotVec(double *newvec, double *vec, double **rotmat);

void
RotVec(double *newvec, double *vec, double **rotmat);

int
VecEq(const double *vec1, const double *vec2, const int len, const double tol);

void
RevVecIp(double *vec, const int len);

double
VecSmallest(double *vec, const int len);

double
VecBiggest(double *vec, const int len);

#endif /* !MATRIXUTILS_SEEN */ 
#ifndef EIGEN_SEEN
#define EIGEN_SEEN

double
*NormalizeVec(double *vect);

void
EigenSort(double **eigenvectors, double *eigenvalues);

void
EigenSort3(double **eigenvectors, double *eigenvalues, double *tmpevec);

void
EigenSort4(double **eigenvectors, double *eigenvalues);

void
EvalSort4(double *eigenvalues);

void
CopyEvec(double *evec1, double *evec2, int length);

void
SwapEvec(double *evec1, double *evec2, int length);

void
Swap3Evec(double *evec1, double *evec2, double *tmpevec);

void
eigen3(double **z, double *eigenval);

void
Eigen4Min(double **eigenvectors, double *eigenvalues);

void
eigen4(double **Q, double *eigenval);

void
eigenval4(double **Q, double *eigenval);

double
pythag(double a, double b);

void
tred24(double **a, double *d, double *e);

void
tred24vals(double **a, double *d, double *e);

void
tqli4(double *d, double *e, double **z);

void
tqli4vals(double *d, double *e, double **z);

int
jacobi3(double **a, double *d, double **v, double tol);

int
jacobi3_cyc(double **a, double *d, double **v, double tol);

void
jacobi4(double **a, double *d, double **v);

void
rotate(double **a, double s, double tau,
       int i, int j, int k, int l);

double
InvSymEigenOp(double **invmat, const double **mat, int n,
              double *evals, double **evecs, const double tol);

void
eigensym(const double **mat, double *evals, double **evecs, int n);

void
eigensym2(const double **mat, double *evals, double **evecs, int n, double *work);

void
eigenvalsym(const double **mat, double *evals, double **evecs, int n);

void
eigenvalsym2(const double **mat, double *evals, double **evecs, int n, double *work);

void
eigengen(const double **mat, double *evals, double **evecs, int n);

void
transevecs(double **mat, int len);

void
eigen_quicksort(double *evals, double **evecs, int len);

void
EigenReconSym(double **mat, const double **evecs, const double *evals, const int n);

int
SymbolicEigen4 (double **mat, double *evals);

#endif

#ifndef INTEGRATE_SEEN
#define INTEGRATE_SEEN

double
trapzd(double (*func)(double, double, double),
       double param1, double param2, double a, double b, int n);

double
integrate_qsimp(double (*func)(double, double, double),
                double param1, double param2, double a, double b);

double
integrate_romberg(double (*f)(double a, double p1, double p2),
                  double p1, double p2, double a, double b);


int
Dgesvd(char jobu, char jobvt, int m, int n, 
       double **a, int lda, double *s,
       double **u, int ldu, 
       double **vt, int ldvt,
       double *work, int lwork);

int
dgesvd_opt_dest(double **a, int m, int n,
                double **u, double *s, double **vt);

int
dgesvd_opt_save(double **a, int m, int n,
                double **u, double *s, double **vt);

int
Dsyev(char jobz_v, char uplo_u,
      int n, double **amat, double *w,
      double *work, int lwork);

int
dsyev_opt_dest(double **amat, int n, double *w);

int
dsyev_opt_save(double **amat, int n, double **evecs, double *evals);

int
Dsyevr(char jobz, char range, char uplo, int n, 
       double **a, int lda,
       double vl, double vu,
       int il, int iu,
       double abstol, int m, double *w, 
       double **z__, int ldz, int *isuppz,
       double *work, int lwork,
       int *iwork, int liwork);

int
dsyevr_opt_dest(double **mat, int n,
                int lower, int upper,
                double *evals, double **evecs,
                double abstol);

int
dsyevr_opt_save(const double **amat, int n,
                int lower, int upper,
                double *evals, double **evecs);

void
dpotr_invert(double **mat, int idim);

int
dpotrf_opt_dest(double **amat, int dim);

int
pseudoinv_sym(double **inmat, double **outmat, int n, const double tol);

#endif
void
matinv(double **a, double **outmat, int N, int *indx);

void
lubksb(double **a, int n, int *indx, double b[]);

void
ludcmp(double **a, int n, int *indx, double *d);
#ifndef MYRANDOM_SEEN
#define MYRANDOM_SEEN

void
init_genrand(unsigned long s);

void
init_by_array(unsigned long init_key[], unsigned long key_length);

unsigned long
genrand_int32(void);

long
genrand_int31(void);

double
genrand_real1(void);

double
genrand_real2(void);

double
genrand_real3(void);

double
genrand_res53(void);

double
expondev(void);

double
gaussdev(void);

double
Normal(void);

void
shuffle(int *a, int n);

void
shufflef(double *a, int n);

#endif
#ifndef ALGO_BLAST_CORE__NCBIMATH
#define ALGO_BLAST_CORE__NCBIMATH

/* $Id: ncbi_math.h,v 1.11 2005/03/10 16:12:59 papadopo Exp $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
 *
 *  This software/database is a "United States Government Work" under the
 *  terms of the United States Copyright Act.  It was written as part of
 *  the author's official duties as a United States Government employee and
 *  thus cannot be copyrighted.  This software/database is freely available
 *  to the public for use. The National Library of Medicine and the U.S.
 *  Government have not placed any restriction on its use or reproduction.
 *
 *  Although all reasonable efforts have been taken to ensure the accuracy
 *  and reliability of the software and data, the NLM and the U.S.
 *  Government do not and cannot warrant the performance or results that
 *  may be obtained by using this software or data. The NLM and the U.S.
 *  Government disclaim all warranties, express or implied, including
 *  warranties of performance, merchantability or fitness for any particular
 *  purpose.
 *
 *  Please cite the author in any work or product based on this material.
 *
 * ===========================================================================
 *
 * Authors:  Gish, Kans, Ostell, Schuler
 *
 * Version Creation Date:   10/23/91
 *
 * ==========================================================================
 */

/** @file ncbi_math.h
 * Prototypes for portable math library (ported from C Toolkit)
 */

/*#include <algo/blast/core/ncbi_std.h> 
#include <algo/blast/core/blast_export.h>*/

double 
s_PolyGamma(double x, int order);

/** Natural logarithm with shifted input
 *  @param x input operand (x > -1)
 *  @return log(x+1)
 */
 
double BLAST_Log1p (double x);

/** Exponentional with base e 
 *  @param x input operand
 *  @return exp(x) - 1
 */
 
double BLAST_Expm1 (double x);

/** Factorial function
 *  @param n input operand
 *  @return (double)(1 * 2 * 3 * ... * n)
 */
 
double BLAST_Factorial(int n);

/** Logarithm of the factorial 
 *  @param x input operand
 *  @return log(1 * 2 * 3 * ... * x)
 */
 
double BLAST_LnFactorial (double x);

/** log(gamma(n)), integral n 
 *  @param n input operand
 *  @return log(1 * 2 * 3 * ... (n-1))
 */
 
double BLAST_LnGammaInt (int n);

/** Romberg numerical integrator 
 *  @param f Pointer to the function to integrate; the first argument
 *               is the variable to integrate over, the second is a pointer
 *               to a list of additional arguments that f may need
 *  @param fargs Pointer to an array of extra arguments or parameters
 *               needed to compute the function to be integrated. None
 *               of the items in this list may vary over the region
 *               of integration
 *  @param p Left-hand endpoint of the integration interval
 *  @param q Right-hand endpoint of the integration interval
 *           (q is assumed > p)
 *  @param eps The relative error tolerance that indicates convergence
 *  @param epsit The number of consecutive diagonal entries in the 
 *               Romberg array whose relative difference must be less than
 *               eps before convergence is assumed. This is presently 
 *               limited to 1, 2, or 3
 *  @param itmin The minimum number of diagnonal Romberg entries that
 *               will be computed
 *  @return The computed integral of f() between p and q
 */
 
double BLAST_RombergIntegrate (double (*f) (double, void*), 
                               void* fargs, double p, double q, 
                               double eps, int epsit, int itmin);

/** Greatest common divisor 
 *  @param a First operand (any integer)
 *  @param b Second operand (any integer)
 *  @return The largest integer that evenly divides a and b
 */
 
int BLAST_Gcd (int a, int b);

/** Divide 3 numbers by their greatest common divisor
 * @param a First integer [in] [out]
 * @param b Second integer [in] [out]
 * @param c Third integer [in] [out]
 * @return The greatest common divisor
 */
 
int BLAST_Gdb3(int* a, int* b, int* c);

/** Nearest integer 
 *  @param x Input to round (rounded value must be representable
 *           as a 32-bit signed integer)
 *  @return floor(x + 0.5);
 */
 
long BLAST_Nint (double x);

/** Integral power of x 
 * @param x floating-point base of the exponential
 * @param n (integer) exponent
 * @return x multiplied by itself n times
 */
 
double BLAST_Powi (double x, int n);

/** Number of derivatives of log(x) to carry in gamma-related 
    computations */
#define LOGDERIV_ORDER_MAX    4  
/** Number of derivatives of polygamma(x) to carry in gamma-related 
    computations for non-integral values of x */
#define POLYGAMMA_ORDER_MAX    LOGDERIV_ORDER_MAX

/** value of pi is only used in gamma-related computations */
#define NCBIMATH_PI    3.1415926535897932384626433832795

/** Natural log(2) */
#define NCBIMATH_LN2    0.69314718055994530941723212145818
/** Natural log(PI) */
#define NCBIMATH_LNPI    1.1447298858494001741434273513531

#ifdef __cplusplus
}
#endif

/*
 * ===========================================================================
 *
 * $Log: ncbi_math.h,v $
 * Revision 1.11  2005/03/10 16:12:59  papadopo
 * doxygen fixes
 *
 * Revision 1.10  2004/11/18 21:22:10  dondosha
 * Added BLAST_Gdb3, used in greedy alignment; removed extern and added  to all prototypes
 *
 * Revision 1.9  2004/11/02 13:54:33  papadopo
 * small doxygen fixes
 *
 * Revision 1.8  2004/11/01 16:37:57  papadopo
 * Add doxygen tags, remove unused constants
 *
 * Revision 1.7  2004/05/19 14:52:01  camacho
 * 1. Added doxygen tags to enable doxygen processing of algo/blast/core
 * 2. Standardized copyright, CVS $Id string, $Log and rcsid formatting and i
 *    location
 * 3. Added use of @todo doxygen keyword
 *
 * Revision 1.6  2003/09/26 20:38:12  dondosha
 * Returned prototype for the factorial function (BLAST_Factorial)
 *
 * Revision 1.5  2003/09/26 19:02:31  madden
 * Prefix ncbimath functions with BLAST_
 *
 * Revision 1.4  2003/09/10 21:35:20  dondosha
 * Removed Nlm_ prefix from math functions
 *
 * Revision 1.3  2003/08/25 22:30:24  dondosha
 * Added LnGammaInt definition and Factorial prototype
 *
 * Revision 1.2  2003/08/11 14:57:16  dondosha
 * Added algo/blast/core path to all #included headers
 *
 * Revision 1.1  2003/08/02 16:32:11  camacho
 * Moved ncbimath.h -> ncbi_math.h
 *
 * Revision 1.2  2003/08/01 21:18:48  dondosha
 * Correction of a #include
 *
 * Revision 1.1  2003/08/01 21:03:40  madden
 * Cleaned up version of file for C++ toolkit
 *
 * ===========================================================================
 */


#endif /* !ALGO_BLAST_CORE__NCBIMATH */

#ifndef QUICKSORT_SEEN
#define QUICKSORT_SEEN

/*---------------       quicksort.h              --------------*/
/*
 * The key TYPE.
 * COARRAY_T is the type of the companion array
 * The keys are the array items moved with the SWAP macro
 * around using the SWAP macro.
 * the comparison macros can compare either the key or things
 * referenced by the key (if its a pointer)
 */ 
typedef double      KEY_T;
typedef char       *COARRAY_T;
/*
 * The comparison macros:
 *
 *  GT(x, y)  as   (strcmp((x),(y)) > 0)
 *  LT(x, y)  as   (strcmp((x),(y)) < 0)
 *  GE(x, y)  as   (strcmp((x),(y)) >= 0)
 *  LE(x, y)  as   (strcmp((x),(y)) <= 0)
 *  EQ(x, y)  as   (strcmp((x),(y)) == 0)
 *  NE(x, y)  as   (strcmp((x),(y)) != 0)
 */
#define GT(x, y) ((x) > (y))
#define LT(x, y) ((x) < (y))
#define GE(x, y) ((x) >= (y))
#define LE(x, y) ((x) <= (y))
#define EQ(x, y) ((x) == (y))
#define NE(x, y) ((x) != (y))

/*
 * Swap macro:
 */
 
/* double              tempd; */
/* char               *tempc; */
/*  */
/* #define SWAPD(x, y) tempd = (x); (x) = (y); (y) = tempd */
/* #define SWAPC(x, y) tempc = (x); (x) = (y); (y) = tempc */

extern void
swapd(double *x, double *y);

extern void
swapc(char **x, char **y);

extern void
insort2 (KEY_T *array1, COARRAY_T *array2, int len);

extern void
insort2d (KEY_T *array1, KEY_T *array2, int len);

extern void
insort (KEY_T *array1, int len);

extern void
partial_quicksort2 (KEY_T *array1, COARRAY_T *array2, int lower, int upper);

extern void
partial_quicksort2d (KEY_T *array1, KEY_T *array2, int lower, int upper);

extern void
partial_quicksort (KEY_T *array, int lower, int upper);

extern void
quicksort2 (KEY_T *array1, COARRAY_T *array2, int len);

extern void
quicksort2d (KEY_T *array1, KEY_T *array2, int len);

extern void
quicksort (KEY_T *array, int len);

#endif
/* ------------------------------------------------------------- 
 * Name            : rvms.h (header file for the library rvms.c) 
 * Author          : Steve Park & Dave Geyer
 * Language        : ANSI C
 * Latest Revision : 11-02-96
 * -------------------------------------------------------------- 
 */

#if !defined( _RVMS_ )
#define _RVMS_

double LogFactorial(long n);
double LogChoose(long n, long m);

double pdfBernoulli(double p, long x);
double cdfBernoulli(double p, long x);
long   idfBernoulli(double p, double u);

double pdfEquilikely(long a, long b, long x);
double cdfEquilikely(long a, long b, long x);
long   idfEquilikely(long a, long b, double u);

double pdfBinomial(long n, double p, long x);
double cdfBinomial(long n, double p, long x);
long   idfBinomial(long n, double p, double u);

double pdfGeometric(double p, long x);
double cdfGeometric(double p, long x);
long   idfGeometric(double p, double u);

double pdfPascal(long n, double p, long x);
double cdfPascal(long n, double p, long x);
long   idfPascal(long n, double p, double u);

double pdfPoisson(double m, long x);
double cdfPoisson(double m, long x);
long   idfPoisson(double m, double u);

double pdfUniform(double a, double b, double x);
double cdfUniform(double a, double b, double x);
double idfUniform(double a, double b, double u);

double pdfExponential(double m, double x);
double cdfExponential(double m, double x);
double idfExponential(double m, double u);

double pdfErlang(long n, double b, double x);
double cdfErlang(long n, double b, double x);
double idfErlang(long n, double b, double u);

double pdfNormal(double m, double s, double x);
double cdfNormal(double m, double s, double x);
double idfNormal(double m, double s, double u);

double pdfLognormal(double a, double b, double x);
double cdfLognormal(double a, double b, double x);
double idfLognormal(double a, double b, double u);

double pdfChisquare(long n, double x);
double cdfChisquare(long n, double x);
double idfChisquare(long n, double u);

double pdfStudent(long n, double x);
double cdfStudent(long n, double x);
double idfStudent(long n, double u);

#endif

#ifndef EIGEN_GSL_SEEN
#define EIGEN_GSL_SEEN

void
EigenvalsGSL(double **mat, const int dim, double *eval);

void
EigenvalsGSLDest(double **mat, const int dim, double *eval);

void
EigenGSL(double **mat, const int dim, double *eval, double **evec, int order);

void
EigenGSLDest(double **mat, const int dim, double *eval, double **evec, int order);

void
svdGSLDest(double **A, const int dim, double *singval, double **V);

void
CholeskyGSLDest(double **A, const int dim);

void
PseudoinvSymGSL(double **inmat, double **outmat, int n, double tol);

#endif

#ifndef MULTIVARGAMMA_SEEN
#define MULTIVARGAMMA_SEEN

double
MultivarLnGamma(const int k, const double a);

#endif

#ifndef SPECFUNC_SEEN
#define SPECFUNC_SEEN

double
BesselI(const double nu, const double z);

double
BesselI0(const double z);

double
BesselI1(const double z);

double
bessi(const int n, const double x);

double
bessi0(const double x);

double
bessi1(const double x);

double
UpperIncompleteGamma(const double a, const double x);

double
gammp(const double a, const double x);

double
gammq(const double a, const double x);

double
gcf(double a, double x);

double
gser(double a, double x);

double
IncompleteGamma(const double x, const double alpha);

double
lngamma(const double xx);

double
mygamma(const double xx);

double
harmonic(int x);

double
polygamma(int k, double x);

double
betai(double a, double b, double x);

double
betacf(double a, double b, double x);

double
beta(double z, double w);

#endif

int
findmin(const double *vec, const int len);

int
findmax(const double *vec, const int len);

double
mymaxdbl(const double x, const double y);

double
mymindbl(const double x, const double y);

int
mymaxint(const int x, const int y);

int
myminint(const int x, const int y);

int
myround(const double num);

double
mysquare(const double val);

double
mycube(const double val);

double
mypow4(double val);

#endif

