#ifndef FITLIB_H
#define FITLIB_H

#include "fits.h"
#include "../utils/cmpfit/mpfit.h"

double polyfit1d(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv, const int degree);
int polyroots(Fits &polynomial, Fits &roots, int derivative = 0);
void evaluate_gauss(Fits &y, const Fits &x, const Fits &params);
double evaluate_gauss(const double x, const Fits &params);
double gaussfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
void evaluate_multigauss(Fits &y, const Fits &x, const Fits &params);
double multigaussfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
void evaluate_multifunc(Fits &y, const Fits &x, const Fits &params, const Fits &types);
bool multifuncfit(Fits &result, double *reduced_chisq, const Fits &xv, const Fits &yv, const Fits &errv, const Fits &types);
double gauss2dfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double gauss2dsimplefit(Fits &result, Fits &yv, int x, int y, int w);
double moffat2dfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double moffat2dsimplefit(Fits &result, Fits &yv, int x, int y, int w);
double multigauss2dfit(Fits &result, const Fits &yv, const Fits &errv, const int ngauss);
double sincfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double sinfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double sinfit2(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double fitrotation(double *trafo, double **cov_matrix, const int nstars, const double *xref, const double *yref, const double *xim, const double *yim, const Fits *master_stars);
double sersicfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double sersic2dfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double sersic2dsimplefit(Fits &result, Fits &yv, int x, int y, int w, double fixed_n);
double sersic2dsmoothfit(Fits &result, Fits &yv, Fits &err, double smooth);
double sersic2dsmoothsimplefit(Fits &result, Fits &yv, Fits &err, int x, int y, int w, double smooth, double fixed_n);
double test2dfit(Fits &result, const Fits &xv, const Fits &yv, const Fits &errv);
double polyfit2d(Fits &result, const Fits &f, const Fits &xv, const Fits &yv, const Fits &errv, const int degree);
double straightlinefit(Fits &result, Fits &xv, Fits &yv, Fits &xerr, Fits &yerr);
double mpfit_userfunction(Fits &result, Fits &xv, Fits &yv, Fits &yerr, Fits &estimate, dpString &fname);
double mpfit_functionstring(Fits &result, Fits &xv, Fits &yv, Fits &yerr, Fits &estimate, dpString &funct);
double mpfit_fit_userstring(Fits &result, Fits &xv, Fits &yv, Fits &yerr, Fits &estimate, dpString &funct);
int mpfit_evaluate_userstring(Fits &result, Fits &xv, Fits &parameters, dpString &funct);
int mpfit_evaluate_userfunction(Fits &result, Fits &xv, Fits &parameters, dpString &fname);
dpStringList mpfit_find_variables(const dpString &funct);
dpString mpfit_parse_dpuser(dpString &funct);
dpString mpfit_build_variable_declarations(dpStringList &vars);
dpString mpfit_write_userfunction(const dpString &funct, const dpString &variables);
extern dpString mpfit_compile_output;
extern mp_config dpMpfitConfig;

//void polyfit_blas(Fits &result, const Fits &f, const Fits &xv, const Fits &yv, const Fits &errv, const int degree);
#endif /* FITLIB_H */
