/*
    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

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

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>


#ifndef BETAPRIME_DIST_SEEN
#define BETAPRIME_DIST_SEEN

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

double
betaprime_dev(const double a, const double b, const gsl_rng *r2);

double
betaprime_pdf(const double x, const double a, const double b);

double
betaprime_lnpdf(const double x, const double a, const double b);

double
betaprime_cdf(const double x, const double a, const double b);

double
betaprime_sdf(const double x, const double a, const double b);

double
betaprime_int(const double x, const double y, const double a, const double b);

//double
//betaprime_logL(const double a, const double b);

double
betaprime_fit(const double *x, const int n, double *ra, double *rb, double *prob);

#endif

#ifndef EVD_FIT_SEEN
#define EVD_FIT_SEEN

double
EVD_dev(const double mu, const double lambda, const gsl_rng *r2);

double
EVD_pdf(const double x, const double mu, const double lambda);

double
EVD_lnpdf(const double x, const double mu, const double lambda);

double
EVD_cdf(const double x, const double mu, const double lambda);

double
EVD_sdf(const double x, const double mu, const double lambda);

double
EVD_int(const double x, const double y, const double mu, const double lambda);

void
Lawless416(const double *x, const int n, const double lambda,
           double *ret_f, double *ret_df);

double
EVD_fit(const double *x, const int n, double *rmu, double *rlambda, double *prob);

#endif

#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 BETA_DIST_SEEN
#define BETA_DIST_SEEN

double
beta_dev(const double a, const double b, const gsl_rng *r2);

double
beta_pdf(const double x, const double a, const double b);

double
beta_lnpdf(const double x, const double a, const double b);

double
beta_cdf(const double x, const double a, const double b);

double
beta_sdf(const double x, const double a, const double b);

double
beta_int(const double x, const double y, const double a, const double b);

double
beta_logL(const double a, const double b);

double
beta_fit(const double *x, const int n, double *ra, double *rb, double *prob);

#endif
#ifndef BETASYM_DIST_SEEN
#define BETASYM_DIST_SEEN

double
betasym_dev(const double a, const double b, const gsl_rng *r2);

double
betasym_pdf(const double x, const double a, const double b);

double
betasym_lnpdf(const double x, const double a, const double b);

double
betasym_cdf(const double x, const double a, const double b);

double
betasym_sdf(const double x, const double a, const double b);

double
betasym_int(const double x, const double y, const double a, const double b);

double
betasym_logL(const double a, const double b);

double
betasym_fit(const double *x, const int n, double *ra, double *rb, double *prob);

#endif
#ifndef BIMULTINOM_SEEN
#define BIMULTINOM_SEEN

double
binomialdev(double pp, int n);

void
multinomialdev(int n, int dim, double *p, double *x);

void
multinomial_eqdev(int n, double p, double *x, int dim);

#endif
#ifndef BINOMIAL_DIST_SEEN
#define BINOMIAL_DIST_SEEN

double
binomial_dev(const double n, const double p, const gsl_rng *r2);

double
binomial_pdf(const double x, const double n, const double p);

double
binomial_lnpdf(const double x, const double n, const double p);

double
binomial_cdf(const double x, const double n, const double p);

double
binomial_sdf(const double x, const double n, const double p);

double
binomial_int(const double x, const double y, const double n, const double p);

double
binomial_logL(const double n, const double p);

double
binomial_fit(const double *x, const int num, double *n, double *p, double *prob);

#endif
#ifndef CAUCHY_SEEN
#define CAUCHY_SEEN

double
cauchy_dev(const double a, const double b, const gsl_rng *r2);

double
cauchy_pdf(const double x, const double a, const double b);

double
cauchy_lnpdf(const double x, const double a, const double b);

double
cauchy_cdf(const double x, const double a, const double b);

double
cauchy_sdf(const double x, const double a, const double b);

double
cauchy_int(const double x, const double y, const double a, const double b);

double
cauchy_logL(const double a, const double b);

double
cauchy_fit(const double *x, const int n, double *ra, double *rb, double *logL);

void
evalcauchyML(const double *x, const int n,
             double *params, double *fvec, double **fjac);

int
mnewt_cauchyML(const int ntrials, const double *x, const int n,
               double *params, const double tolx, const double tolf);

#endif
#ifndef CHI_DIST_SEEN
#define CHI_DIST_SEEN

double
chi_dev(const double nu, const double nullp, const gsl_rng *r2);

double
chi_pdf(const double x, const double nu, const double nullp);

double
chi_lnpdf(const double x, const double nu, const double nullp);

double
chi_cdf(const double x, const double nu, const double nullp);

double
chi_sdf(const double x, const double nu, const double nullp);

double
chi_int(const double x, const double y, const double nu, const double nullp);

double
chi_logL(const double nu, const double nullval);

void
evalchiML(const double logterm, const double nu, double *fx, double *dfx);

double
chi_fit(const double *data, const int num, double *nu, double *nullp, double *prob);

#endif
#ifndef CHISQR_DIST_SEEN
#define CHISQR_DIST_SEEN

double
chisqr_dev(const double nu, const double nullval, const gsl_rng *r2);

double
chisqr_pdf(const double x, const double nu, const double nullval);

double
chisqr_lnpdf(const double x, const double nu, const double nullval);

double
chisqr_cdf(const double x, const double nu, const double nullval);

double
chisqr_sdf(const double x, const double nu, const double nullval);

double
chisqr_int(const double x, const double y, const double nu, const double nullval);

double
chisqr_logL(const double nu, const double nullval);

void
evalchisqrML(const double logterm, const double nu, double *fx, double *dfx);

double
chisqr_fit(const double *data, const int num, double *nu, double *nullp, double *prob);

#endif
#ifndef CHISQRGEN_DIST_SEEN
#define CHISQRGEN_DIST_SEEN

double
chisqrgen_dev(const double nu, const double lambda, const gsl_rng *r2);

double
chisqrgen_pdf(const double x, const double nu, const double lambda);

double
chisqrgen_lnpdf(const double x, const double nu, const double lambda);

double
chisqrgen_cdf(const double x, const double nu, const double lambda);

double
chisqrgen_sdf(const double x, const double nu, const double lambda);

double
chisqrgen_int(const double x, const double y, const double nu, const double lambda);

double
chisqrgen_logL(const double nu, const double lambda);

double
chisqrgen_fit(const double *data, const int num, double *nu, double *lambda, double *prob);

#endif

#ifndef EXP_DIST_SEEN
#define EXP_DIST_SEEN

double
exp_dev(const double mu, const double nullp, const gsl_rng *r2);

double
exp_pdf(const double x, const double mu, const double nullp);

double
exp_lnpdf(const double x, const double mu, const double nullp);

double
exp_cdf(const double x, const double mu, const double nullp);

double
exp_sdf(const double x, const double mu, const double nullp);

double
exp_int(const double x, const double y, const double mu, const double nullp);

double
exp_fit(const double *x, const int n, double *mu, double *nullp, double *prob);

double
exp_histfit(double *x, double *freq, int n, double *mu, double *nullp, double *logL);

#endif
#ifndef GAMMA_DIST_SEEN
#define GAMMA_DIST_SEEN

double
gamma_dev(const double a, const double b, const gsl_rng *r2);

double
gamma_int_dev(const unsigned int a);

double
gamma_large_dev(const double a);

double
gamma_frac_dev(const double a);

double
gamma_pdf(const double x, const double a, const double b);

double
gamma_lnpdf(const double x, const double b, const double c);

double
gamma_cdf(const double x, const double a, const double b);

double
gamma_sdf(const double x, const double a, const double b);

double
gamma_int(const double x, const double y, const double a, const double b);

double
gamma_logL(const double b, const double c);

double
lngamma(const double xx);

double
gamma_MMfit(const double *data, const int num, double *alpha, double *theta, double *prob);

double
gamma_Stacyfit(const double *data, const int num, double *b, double *c, double *logL);

double
gamma_fit(const double *data, const int num, double *alpha, double *theta, double *logL);

void
gamma_fit_no_stats(const double *data, const int num, double *b, double *c);

double
gamma1_fit(const double *data, const int num, double *b, double *nullp, double *logL);

double
gamma_fit_guess(const double *data, const int num, double *b, double *c, double *logL);

double
gamma_minc_fit(const double *data, const int num, double *b, double *c, const double minc, double *logL);

double
gamma_minc_opt_fit(const double *data, const int num, double *b, double *c, const double minc, double *logL);

double
gamma_histfit(double *data, double *freq, int num, double *b, double *c, double *logL);

#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
#ifndef INVCHISQR_DIST_SEEN
#define INVCHISQR_DIST_SEEN

double
invchisqr_dev(const double nu, const double nullval, const gsl_rng *r2);

double
invchisqr_pdf(const double x, const double nu, const double nullval);

double
invchisqr_lnpdf(const double x, const double nu, const double nullval);

double
invchisqr_cdf(const double x, const double nu, const double nullval);

double
invchisqr_sdf(const double x, const double nu, const double nullval);

double
invchisqr_int(const double x, const double y, const double nu, const double nullval);

void
evalinvchisqrML(const double logterm, const double nu, double *fx, double *dfx);

double
invchisqr_fit(const double *data, const int num, double *nu, double *nullp, double *prob);

#endif
#ifndef INVGAMMA_DIST_SEEN
#define INVGAMMA_DIST_SEEN

double
invgamma_dev(const double b, const double c, const gsl_rng *r2);

double
invgamma_pdf(const double x, const double b, const double c);

double
invgamma_lnpdf(const double x, const double b, const double c);

double
invgamma_cdf(const double x, const double b, const double c);

double
invgamma_sdf(const double x, const double b, const double c);

double
invgamma_int(const double x, const double y, const double b, const double c);

double
invgamma_logL(const double *data, const int num, const double b, const double c);

double
invgamma_fit(const double *data, const int num, double *b, double *c, double *logL);

double
ExpXn(const double b, const double c, const double n);

double
ExpLogXn(const double b, const double c, const double n);

double
ExpInvXn(const double b, const double c, const double xn1);

double
invgamma_EMsmall_fit(const double *data, const int num, const int missing, double *b, double *c, double *logL);

double
invgamma_bayes_fit(const double *data, const int num, double *b, double *c, double *logL);

double
invgamma1_fit(const double *data, const int num, double *b, double *nullp, double *logL);

double
invgamma_fixed_c_EM_fit(const double *data, const int num, const int missing, double *b, const double c, double *logL);

double
invgamma_fixed_c_ML_fit(const double *data, const int num, const int missing, double *b, const double c, double *logL);

double
invgamma_fixed_c_EM_fit_bayes(const double *data, const int num, const int missing, double *b, const double c, double *logL);

double
invgamma_fit_guess(const double *data, const int num, double *b, double *c, double *logL);

double
invgamma_minc_fit(const double *data, const int num, double *b, double *c, const double minc, double *logL);

double
invgamma_minc_opt_fit(const double *data, const int num, double *b, double *c, const double minc, double *logL);

double
invgamma_mode_fit(const double *data, const int num, double *b, double *c, const double mode, double *logL);

double
invgamma_eq_bc_fit(const double *data, const int num, double *b, double *c, double *logL, int init);

#endif
#ifndef INVGAUSS_SEEN
#define INVGAUSS_SEEN

double
invgauss_dev(const double h, const double b, const gsl_rng *r2);

double
invgauss_pdf(const double x, const double ave, const double lambda);

double
invgauss_lnpdf(const double x, const double ave, const double lambda);

double
invgauss_cdf(const double x, const double ave, const double lambda);

double
invgauss_sdf(const double x, const double ave, const double lambda);

double
invgauss_int(const double x, const double y, const double ave, const double lambda);

double
invgauss_fit(const double *data, const int num, double *ave, double *lambda, double *prob);

#endif
#ifndef LAPLACE_DIST_SEEN
#define LAPLACE_DIST_SEEN

double
laplace_dev(const double mean, const double scale, const gsl_rng *r2);

double
laplace_pdf(const double x, const double mean, const double scale);

double
laplace_lnpdf(const double x, const double mean, const double scale);

double
laplace_cdf(const double x, const double mean, const double scale);

double
laplace_sdf(const double x, const double mean, const double scale);

double
laplace_int(const double x, const double y, const double mean, const double scale);

double
laplace_logL(const double mean, const double scale);

double
laplace_fit(const double *x, const int n, double *mean, double *scale, double *prob);

#endif
#ifndef LOGISTIC_SEEN
#define LOGISTIC_SEEN

double
logistic_dev(const double a, const double b, const gsl_rng *r2);

double
logistic_pdf(const double x, const double a, const double b);

double
logistic_lnpdf(const double x, const double a, const double b);

double
logistic_cdf(const double x, const double a, const double b);

double
logistic_sdf(const double x, const double a, const double b);

double
logistic_int(const double x, const double y, const double a, const double b);

double
logistic_logL(const double a, const double b);

double
logistic_fit(const double *x, const int n, double *ra, double *rb, double *logL);

void
evallogisticML(const double *x, const int n, double *params, double *fvec, double **fjac);

void
mnewt_logisticML(const int ntrials, const double *x, const int n,
                 double *params, const double tolx, const double tolf);

double
sech(const double d);

#endif
#ifndef LOGNORMAL_SEEN
#define LOGNORMAL_SEEN

#if defined(__linux__) || defined(__GLIBC__)
    extern double erf(double x);
#endif

double
lognormal_dev(const double zeta, const double sigma, const gsl_rng *r2);

double
lognormal_pdf(const double x, const double zeta, const double sigma);

double
lognormal_lnpdf(const double x, const double zeta, const double sigma);

double
lognormal_cdf(const double x, const double zeta, const double sigma);

double
lognormal_sdf(const double x, const double zeta, const double sigma);

double
lognormal_int(const double x, const double y, const double zeta, const double sigma);

double
lognormal_logL(const double zeta, const double sigma);

double
lognormal_fit(const double *data, const int num, double *zeta, double *sigma, double *prob);

#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 MAXWELL_SEEN
#define MAXWELL_SEEN

double
maxwell_dev(const double alpha, const double nullv, const gsl_rng *r2);

double
maxwell_pdf(const double x, const double alpha, const double nullv);

double
maxwell_lnpdf(const double x, const double alpha, const double nullv);

double
maxwell_cdf(const double x, const double alpha, const double nullv);

double
maxwell_sdf(const double x, const double alpha, const double nullv);

double
maxwell_int(const double x, const double y, const double alpha, const double nullv);

double
maxwell_logL(const double alpha, const double nullv);

double
maxwell_fit(const double *data, const int num, double *alpha, double *nullv, double *prob);

#endif
#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 NEGBINOM_DIST_SEEN
#define NEGBINOM_DIST_SEEN

double
negbinom_dev(const double a, const double p, const gsl_rng *r2);

double
negbinom_pdf(const double x, const double a, const double p);

double
negbinom_lnpdf(const double x, const double a, const double p);

double
negbinom_cdf(const double x, const double a, const double p);

double
negbinom_sdf(const double x, const double a, const double p);

double
negbinom_int(const double x, const double y, const double a, const double p);

double
negbinom_logL(const double a, const double p);

double
negbinom_fit(const double *x, const int num, double *a, double *p, double *prob);

#endif
#ifndef NORMAL_DIST_SEEN
#define NORMAL_DIST_SEEN

double
normal_dev(const double mu, const double var, const gsl_rng *r2);

double
normal_pdf(const double x, const double mean, const double var);

double
normal_lnpdf(const double x, const double mean, const double var);

double
normal_cdf(const double x, const double mean, const double var);

double
normal_sdf(const double x, const double mean, const double var);

double
normal_int(const double x, const double y, const double mean, const double var);

double
normal_logL(const double mean, const double var);

double
normal_fit(const double *x, const int n, double *mean, double *var, double *prob);

double
normal_fit_w(const double *x, const int n, const double *wts, double *mean,
             double *var, double *logL);

void
normal_init_mix_params(const double *x, const int n, const int mixn,
                       double *mean, double *var);

#endif
#ifndef PARETO_DIST_SEEN
#define PARETO_DIST_SEEN

double
pareto_dev(const double a, const double c, const gsl_rng *r2);

double
pareto_pdf(const double x, const double a, const double c);

double
pareto_lnpdf(const double x, const double a, const double c);

double
pareto_cdf(const double x, const double a, const double c);

double
pareto_sdf(const double x, const double a, const double c);

double
pareto_int(const double x, const double y, const double a, const double c);

double
pareto_logL(const double a, const double c);

double
pareto_fit(const double *data, const int num, double *a, double *c, double *prob);

#endif
#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
#ifndef RECINVGAUSS_SEEN
#define RECINVGAUSS_SEEN

double
recinvgauss_pdf(const double x, const double mean, const double lambda);

double
recinvgauss_lnpdf(const double x, const double mean, const double lambda);

double
recinvgauss_cdf(const double x, const double mean, const double lambda);

double
recinvgauss_sdf(const double x, const double mean, const double lambda);

double
recinvgauss_int(const double x, const double y, const double mean, const double lambda);

double
recinvgauss_dev(const double mu, const double lam, const gsl_rng *r2);

double
recinvgauss_fit(const double *data, const int num, double *mean, double *lambda, double *logL);

#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
#ifndef STATISTICS_SEEN
#define STATISTICS_SEEN


double
average(const double *data, const int dim);

double
Variance(const double *data, const int dim, const double mean);

double
VarVariance(const double *data, const int ddim, const int sdim);

int
moments(const double *data, const int dim,
        double *ave, double *median,
        double *adev, double *mdev,
        double *sdev, double *var,
        double *skew, double *kurt,
        double *hrange, double *lrange);

double
chi_sqr_adapt(const double *data, const int num, int nbins, double *logL,
              const double ave, const double lambda,
              double (*dist_pdf)(double x, double param1, double param2),
              double (*dist_lnpdf)(double x, double param1, double param2),
              double (*dist_int)(double x, double y, double param1, double param2));

double
chi_sqr_adapt_mix(const double *data, const int num, int nbins, double *logL,
                  const double *p1, const double *p2, const double *mixp, const int nmix,
                  double (*dist_pdf)(double x, double param1, double param2),
                  double (*dist_lnpdf)(double x, double param1, double param2),
                  double (*dist_int)(double x, double y, double param1, double param2));

double
dist_logL(double (*dist_lnpdf)(const double x, const double param1, const double param2),
          const double param1, const double param2,
          const double *data, const int num);

double
chi_sqr_hist(double *data, double *freq, int num, double *logL, double ave, double lambda,
             double (*dist_pdf)(double x, double param1, double param2),
             double (*dist_lnpdf)(double x, double param1, double param2),
             double (*dist_int)(double x, double y, double param1, double param2));

double
chi_sqr_one(double *data, int num, int nbins, double *prob, double ave, double lambda,
            double (*dist)(double x, double param1, double param2));

int
dblcmp(const void *dbl1, const void *dbl2);

int
dblcmp_rev(const void *dbl1, const void *dbl2);

double
normal_dist(double x);

double
probks(double alam);

double
kstwo(double *data1, int n1, double *data2, int n2);

double
ksone(double *data, int n, double (*func)(double));

double
probks_dw(double ksd, int em);

void
mMultiply(double *A, double *B, double *C, int m);

void
mPower(double *A, int eA, double *V, int *eV, int m, int n);

double
KS(double d, int n);

double
F_prob(int dn, int dd, double fr);

double
L504(int a, double f, int b, int iv);

double
L401(int a, double f, int b, int iv);

double
nlogn(double n);

double
Factorial(long unsigned int N);

double
Combination(double N, double M);

double
LnCombinationStirling(double N, double M);

double
MultinomCoeff(long unsigned int tries, long unsigned int *wins, int nclasses);

double
LnMultinomCoeff(long unsigned int tries, long unsigned int *wins, int nclasses);

double
Binomial_P(long unsigned int n, long unsigned int m, double p);

double
Multinomial_P(long unsigned int tries, long unsigned int *wins, double *p, int classes);

double
Multinomial_UpTail(long unsigned int tries, long unsigned int *wins, double *p, int classes);

void
insort_multinom(double *rank, double *prob, long unsigned int *wins, int nclasses);

double
Binomial_sum(long unsigned int n, long unsigned int m, double p);

double
student_t(double t, double df);

double
stdnormal(void);

#endif

#ifndef RAYLEIGH_DIST_SEEN
#define RAYLEIGH_DIST_SEEN

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

double
rayleigh_dev(const double a, const double b, const gsl_rng *r2);

double
rayleigh_pdf(const double x, const double a, const double b);

double
rayleigh_lnpdf(const double x, const double a, const double b);

double
rayleigh_cdf(const double x, const double a, const double b);

double
rayleigh_sdf(const double x, const double a, const double b);

double
rayleigh_int(const double x, const double y, const double a, const double b);

double
rayleigh_logL(const double a, const double b);

double
rayleigh_fit(const double *x, const int n, double *eta, double *beta, double *prob);

#endif


#ifndef UNIFORM_DIST_SEEN
#define UNIFORM_DIST_SEEN

double
uniform_dev(const double alpha, const double beta, const gsl_rng *r2);

double
uniform_pdf(const double x, const double alpha, const double beta);

double
uniform_lnpdf(const double x, const double alpha, const double beta);

double
uniform_cdf(const double x, const double alpha, const double beta);

double
uniform_sdf(const double x, const double alpha, const double beta);

double
uniform_int(const double x, const double y, const double alpha, const double beta);

double
uniform_logL(const double alpha, const double beta);

double
uniform_fit(const double *x, const int n, double *alpha, double *beta, double *prob);

#endif
#ifndef VONMISES_DIST_SEEN
#define VONMISES_DIST_SEEN

#if defined(__linux__) || defined(__GLIBC__)
    extern double jn(int n, double x);
#endif

double
pseudo_vonmises_met(const double a, const double b, const double x);

double
mardia_gadsden_met(const double a, const double b, const double x);

double
vonmises_dev(const double a, const double b, const gsl_rng *r2);

double
vonmises_pdf(const double x, const double a, const double b);

double
vonmises_lnpdf(const double x, const double a, const double b);

double
vonmises_cdf(const double x, const double a, const double b);

double
vonmises_sdf(const double x, const double a, const double b);

double
vonmises_int(const double x, const double y, const double nu, const double nullval);

double
vonmises_fit(const double *data, const int num, double *a, double *b, double *prob);

#endif
#ifndef WEIBULL_DIST_SEEN
#define WEIBULL_DIST_SEEN

double
weibull_dev(const double a, const double b, const gsl_rng *r2);

double
weibull_pdf(const double x, const double a, const double b);

double
weibull_lnpdf(const double x, const double a, const double b);

double
weibull_cdf(const double x, const double a, const double b);

double
weibull_sdf(const double x, const double a, const double b);

double
weibull_int(const double x, const double y, const double a, const double b);

double
weibull_logL(const double a, const double b);

double
weibull_fit(const double *x, const int n, double *eta, double *beta, double *prob);

void
evalweibullML(const double *x, const int nx,
              double *params, double *fvec, double **fjac);

int
mnewt_weibullML(const double *data, const int ndata, const int ntrial,
                double *params, const double tolx, const double tolf);

double
weibull_histfit(double *x, double *freq, int nx, double *eta, double *beta, double *logL);

int
mnewt_hist_weibullML(const double *data, double *freq,
                     const int ndata, const int ntrial,
                     double *params, const double tolx, const double tolf);

void
eval_hist_weibullML(const double *x, double *freq, const int nx,
                    double *params, double *fvec, double **fjac);

#endif

#ifndef RICE_DIST_SEEN
#define RICE_DIST_SEEN

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

double
rice_dev(const double mu, const double var, const gsl_rng *r2);

double
rice_pdf(const double x, const double mean, const double var);

double
rice_lnpdf(const double x, const double mean, const double var);

double
rice_cdf(const double x, const double mean, const double var);

double
rice_sdf(const double x, const double mean, const double var);

double
rice_int(const double x, const double y, const double mean, const double var);

double
rice_logL(const double mean, const double var);

double
rice_fit(const double *x, const int n, double *mean, double *var, double *prob);

double
rice_fit_w(const double *x, const int n, const double *wts, double *mean,
             double *var, double *logL);

void
rice_init_mix_params(const double *x, const int n, const int mixn,
                       double *mean, double *var);

#endif

