/* numutil.h - header file for numerical methods utilities */

#ifndef _NUMUTIL_H_
#define _NUMUTIL_H_

#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif

/** Non-linear least square fit intermediate data */
struct nlsq_dat {
    size_t a_dim;    /**< number of parameters */
    double *a;       /**< a[a_dim]  - array of parameters */
    int    *ia;      /**< ai[a_dim] - array of fitflags   */
    double **covar;  /**< covar[a_dim][a_dim] - covariance matrix */
    double **alpha;  /**< alpha[a_dim][a_dim] - curvature matrix  */
    /* -- mrqmin intermediate data -- */
    double *atry;    /**< atry[a_dim] */
    double *beta;    /**< beta[a_dim] */
    double *da;      /**< da[a_dim] */
    double **oneda;  /**< oneda[mfit < a_dim][1] */
    /* == mrqcof intermediate data == */
    double *dfda;    /**<  */
};

/** Reformat covariance matrix by inserting zeroes for fixed parameters */
void covsrt(double **covar, int ma, int *ia, int mfit);

/** Gauss-Jordan elimination: a[n][n] is replaced by
 * its inverse and every coloumn in b[n][m]is replaced with corresponding
 * solution  of  a*b[][i] = x[][i] */
int gaussj(double **a, int n, double **b, int m);

/** Linear fit (least square fit) */
int lfit(void * obj, double *sig, int ndat,
	 double *a, int *ia, int ma,
	 double **covar, double *chisq,
	 double (*func)(void*, int, const double *, double *, int));

/** Levenberg-Marquardt method linear approximation of the non-linear
 * least_squar fit
 */
void mrqmin(void *obj, double *sig, int ndata,
	    struct nlsq_dat * nlfd, double *chisq,
	    double (*func)(void*, int, const double *, double *, int),
	    double *alamda);

#if 0
{
#endif
#ifdef __cplusplus
}
#endif

#endif /* _NUMUTIL_H_ */

