/***********************************************************
 Basic statistical, input-output and matrix manipulation

 Author. Peter Mueller, Stephen Morris, David Rossell
 Last modified. 04 2006
***********************************************************/

#if !defined(STAT_H_INCLUDED)
#define STAT_H_INCLUDED

#include <math.h>
#include <stdio.h>

#if !defined(M_PI)
#define M_PI (3.1415926535897932385)
#endif


/* Functions to compute means & variances */

double meani(int *x, int lim);
double wmeani(int *x, int lim, double *w);
double meanx(double *x, int lim);
double wmeanx(double *x, int lim, double *w);
double vari(int *x, int lim, int unb);
double wvari(int *x, int lim, double *w);
double varx(double *x, int lim, int unb);
double wvarx(double *x, int lim, double *w);

/* Input/output functions (interface) */

FILE *openIn(char *);
FILE *openOut(char *);
void scanFloat(char *, float *);
void scanDouble(char *, double *);
void scanInt(char *, int *);
void fscanDouble(FILE *,char *, double *);
void fscanInt(FILE *,char *, int *);
void scanLong(char *, long *);

void scanFloatArray(char *,float *, int);
void scanArray(char *,float *, int);
void scanDoubleArray(char *,double *, int);
void scanString(char *txt, char *s, int n);
void fscanString(FILE *,char *txt, char *s, int n);
void fscanDoubleArray(FILE *,double *, int);
void scanDoubleMatrix(char *, double **, int, int);
void fscanDoubleMatrix(FILE *ifile, double **x,int r,int c);
void scanIntArray(char *,int *, int);
void fscanIntArray(FILE *ifile, int *x, int n);

void writeInt(int);
void writeLong(long i);
void writeFloat(float);
void writeDouble(double);

void writeIntArray(int *,int, int);
void fwriteIntArray(FILE *, int *,int, int);
void fwriteIntMatrix(FILE *f, int **x, int rows, int cols);
void writeIntMatrix(int **x, int rows, int cols);
void writeDoubleArray(double *,int, int);
void writeDoubleMatrix2(double **, int , int);
void fwriteDoubleArray(FILE *, double *,int, int);
void fwriteDoubleMatrix2(FILE *, double **, int , int);
void writeDoubleMatrix(double **, int, int);
void writeFloatArray(float *, int, int);
void writeArray(float *, int, int); 

void fserror(char *proc, char *act, char *what);

/* Debug messages etc. (mess) */
void error(char *,char *, int);
void err_msg(char *fct, char *txt, int n1, int n2, int n3);


/* Memory allocation, from Numerical Recipies (nrutil) */
double  *dvector(int,int);
double  **dmatrix(int,int,int,int);
double  ***darray_3(int, int);
double ***darray3(int n, int p, int q);
int     *ivector(int,int);
int     **imatrix(int,int,int,int);
int ***iarray_3(int lo, int hi);
int ***iarray3(int p1, int p2, int p3);

void free_dvector(double  *,int,int);
void free_ivector(int  *,int,int);
void free_dmatrix(double  **,int,int,int,int);
void free_imatrix(int  **,int,int,int,int);

void nrerror(char *proc, char *act, char *what);


/* Mathematical functions */

double digamma(double x);                          //from S Poetry (by Patrick J. Burns)

/* Vector algebra (vector) */

void grid (double x0, double xn, int n, double *x);
void  rA(double,double **, double **, int, int);
void R_zero(double **, int, int); //set to 0 a double matrix
void R_izero(int **A, int p,int q); //set to 0 an integer matrix
double max_xy(double x, double y);

int dcompare(const void *a, const void *b);               
void dvecsort(double *v, int size);                                    //sorting a vector using qsort from stdlib
void dindexsort(double *x, int *index, int ilo, int ihi, int incr);    //sorting a vector of indexes using self-written quicksort routine


/* Random variate generation (rand) */

void setseed(long, long);
double  runif();
double betadev(double , double );
double gamdev(double );
double	invcdfn (double , double , double );
double	cdfnorm(double , double , double );
int	binomial(int , double );
void multinomial(int, int, double *, int *);

/* More random variate stuff (dcdflib, stolen from CMU statlib "www.stat.cmu.edu") */
double fifdint(double);
void cdfnor(int*,double*,double*,double*,double*,double*,int*,double*);
double spmpar(int*);
void cumnor(double*,double*,double*);
double dinvnr(double *p,double *q);
double stvaln(double*);
double devlpl(double [],int*,double*);
double gamln(double*);
double gamln1(double*);
extern int ipmpar(int*);                      /* code in ipmpar.c */

/*even more stuff (ranlib) */

extern float genunf(float low,float high);
extern float gengam(float a,float r);
extern float sgamma(float a);
extern float snorm(void);
float fsign( float num, float sign );
extern float sexpo(void);
extern long mltmod(long a,long s,long m);
extern float ranf(void);
extern void gscgn(long getset,long *g);
extern void setall(long iseed1,long iseed2);   /* code in com.c */
extern void initgn(long isdtyp);               /* code in com.c */
extern long ignlgi(void);                      /* code in com.c */
extern void inrgcm(void);                      /* code in com.c */


#endif
