#ifndef __MATMATH_H__
#define __MATMATH_H__
/*   matmath.h

     This is the declaration file for the matmath functions.
*/

/*  This is the datatype used for the math and non-type specific ops.  */

//typedef double double;

/*************     Vector math routines    ****************/

/*  vector B = vector A, of size nudoubleents   */
extern void vec_copy( double *src, double *dst, int nudoubleents );

/*  vector C = vector A + vector B , both of size n   */
extern void vec_add( double *A, double *B, double *C, int n );

/*  vector C = vector A - vector B , both of size n   */
extern void vec_sub( double *A, double *B, double *C, int n );

extern void print_vector( char *str, double *x, int n );

/*************   Some matrix math routines  **************/

/*  matrix B = matrix A, of size num_rows x num_cols   */
extern void mat_copy( double **A, double **B, int num_rows,
			int num_cols );

/*  matrix C = matrix A + matrix B , both of size m x n   */
extern void mat_add( double **A, double **B, double **C, int m, int n );

/*  matrix C = matrix A - matrix B , all of size m x n  */
extern void mat_sub( double **A, double **B, double **C, int m, int n );

/*  matrix C = matrix A x matrix B , A(a_rows x a_cols), B(a_cols x b_cols) */
extern void mat_mult( double **A, double **B, double **C,
		     int a_rows, int a_cols, int b_cols );

/*  matrix C = matrix A x vector B , A(a_rows x a_cols), B(a_cols x 1) */
extern void mat_mult_vector( double **A, double *B, double *C,
			    int a_rows, int a_cols );

/*  C = matrix A x trans( matrix B ), A(a_rows x a_cols), B(b_cols x a_cols) */
extern void mat_mult_transpose( double **A, double **B, double **C,
			   int a_rows, int a_cols, int b_cols );

/*  C = trans( matrix A ) x matrix B, A(a_cols x a_rows), B(a_cols x b_cols) */
extern void mat_transpose_mult( double **A, double **B, double **C,
			   int a_rows, int a_cols, int b_cols );


extern void print_matrix( char *str, double **A, int m, int n );


int gaussj( double **A, int n, double **B, int m );

extern void mrqmin( double x[], double y[], double sig[], int ndata,
		   double a[], int ia[], int ma, double **covar,
		   double **alpha, double *chisq,
		   void (*funcs)(double, double [], double *, double [], int),
		   double *alamda);

/*  quaternion routines  */

#define QUATERNION_SIZE    4
#define MIN_QUATERNION_MAGNITUDE   0.000001


extern double *quaternion( void );
extern void quaternion_update( double *quat, double wx,
		       double wy, double wz );
extern void quaternion_to_rotation( double *quat, double **rot );
extern void print_quaternion( char *str, double *quat );

/*   Vector allocation routines   */

extern double *vector(long nl, long nh);
extern int *ivector(long nl, long nh);
extern unsigned char *cvector(long nl, long nh);
extern unsigned long *lvector(long nl, long nh);
extern float *fvector(long nl, long nh);
extern double *dvector(long nl, long nh);

/*   Matrix allocation routines    */

extern double **matrix(long nrl, long nrh, long ncl, long nch);
extern float **fmatrix(long nrl, long nrh, long ncl, long nch);
extern double **dmatrix(long nrl, long nrh, long ncl, long nch);
extern int **imatrix(long nrl, long nrh, long ncl, long nch);

extern double **submatrix(double **a,
			 long oldrl, long oldrh, long oldcl, long oldch,
			 long newrl, long newcl);
extern double **convert_matrix( double *a, long nrl, long nrh,
			      long ncl, long nch);

/*   Deallocation routines   */

extern void free_vector(double *v, long nl, long nh);
extern void free_fvector(float *v, long nl, long nh);
extern void free_ivector(int *v, long nl, long nh);
extern void free_cvector(unsigned char *v, long nl, long nh);
extern void free_lvector(unsigned long *v, long nl, long nh);
extern void free_dvector(double *v, long nl, long nh);

extern void free_matrix(double **m, long nrl, long nrh, long ncl, long nch);
extern void free_fmatrix(float **m, long nrl, long nrh, long ncl, long nch);
extern void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch);
extern void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch);
extern void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch);
extern void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch);
extern void nrerror(char error_text[]);   /*  internal error handler */

#endif

double mean(double *data, int n);
double sigma(double *data, int n, double mean_val);
double max(double a, double b);
int imax(int a, int b);
int min2power(int n);
int mean_loop(double *data, int n, int n_loop, int n_sigma, double *mean_out, double *sigma_out);
float fmean(float *data, int n);
float fsigma(float *data, int n, float mean_val);
