OPERA
1.0
Open source echelle spectrograph reduction pipeline
|
Levenberg Marquardt Least Squares Fitting. More...
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#include "libraries/operaLMFit.h"
Defines | |
#define | LM_MACHEP DBL_EPSILON |
#define | LM_DWARF DBL_MIN |
#define | LM_SQRT_DWARF sqrt(DBL_MIN) |
#define | LM_SQRT_GIANT sqrt(DBL_MAX) |
#define | LM_USERTOL 30*LM_MACHEP |
#define | MIN(a, b) (((a)<=(b)) ? (a) : (b)) |
#define | MAX(a, b) (((a)>=(b)) ? (a) : (b)) |
#define | SQR(x) (x)*(x) |
Functions | |
void | lmcurve_evaluate (int n_par, const double *par, int m_dat, const void *data, double *fvec, int *info) |
void | lmcurve_fit (int n_par, double *par, int m_dat, const double *x, const double *y, double(*function)(double x, const double *par, int n_par), lm_control_struct *control, lm_status_struct *status) |
void | lm_printout_std (int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev) |
void | lmmin (int n_par, double *par, int m_dat, const void *data, void(*evaluate)(int n_par, const double *par, int m_dat, const void *data, double *fvec, int *info), const lm_control_struct *control, lm_status_struct *status, void(*printout)(int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev)) |
void | lm_lmpar (int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double delta, double *par, double *x, double *sdiag, double *aux, double *xdi) |
void | lm_qrfac (int m, int n, double *a, int pivot, int *ipvt, double *rdiag, double *acnorm, double *wa) |
void | lm_qrsolv (int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double *x, double *sdiag, double *wa) |
void | lm_lmdif (int m, int n, double *x, double *fvec, double ftol, double xtol, double gtol, int maxfev, double epsfcn, double *diag, int mode, double factor, int *info, int *nfev, double *fjac, int *ipvt, double *qtf, double *wa1, double *wa2, double *wa3, double *wa4, void(*evaluate)(int n_par, const double *par, int m_dat, const void *data, double *fvec, int *info), void(*printout)(int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev), int printflags, const void *data) |
Legacy low-level interface. | |
double | lm_enorm (int n, const double *x) |
Variables | |
const lm_control_struct | lm_control_double |
const lm_control_struct | lm_control_float |
const char * | lm_infmsg [] |
const char * | lm_shortmsg [] |
Levenberg Marquardt Least Squares Fitting.
#define LM_DWARF DBL_MIN |
#define LM_MACHEP DBL_EPSILON |
#define LM_SQRT_DWARF sqrt(DBL_MIN) |
#define LM_SQRT_GIANT sqrt(DBL_MAX) |
#define LM_USERTOL 30*LM_MACHEP |
#define MAX | ( | a, | |
b | |||
) | (((a)>=(b)) ? (a) : (b)) |
#define MIN | ( | a, | |
b | |||
) | (((a)<=(b)) ? (a) : (b)) |
#define SQR | ( | x | ) | (x)*(x) |
double lm_enorm | ( | int | n, |
const double * | x | ||
) |
sum squares.
calculation of norm.
void lm_lmdif | ( | int | m, |
int | n, | ||
double * | x, | ||
double * | fvec, | ||
double | ftol, | ||
double | xtol, | ||
double | gtol, | ||
int | maxfev, | ||
double | epsfcn, | ||
double * | diag, | ||
int | mode, | ||
double | factor, | ||
int * | info, | ||
int * | nfev, | ||
double * | fjac, | ||
int * | ipvt, | ||
double * | qtf, | ||
double * | wa1, | ||
double * | wa2, | ||
double * | wa3, | ||
double * | wa4, | ||
void(*)(int n_par, const double *par, int m_dat, const void *data, double *fvec, int *info) | evaluate, | ||
void(*)(int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev) | printout, | ||
int | printflags, | ||
const void * | data | ||
) |
Legacy low-level interface.
void lm_lmpar | ( | int | n, |
double * | r, | ||
int | ldr, | ||
int * | ipvt, | ||
double * | diag, | ||
double * | qtb, | ||
double | delta, | ||
double * | par, | ||
double * | x, | ||
double * | sdiag, | ||
double * | aux, | ||
double * | xdi | ||
) |
evaluate the function at the current value of par.
if the function is small enough, accept the current value of par. Also test for the exceptional cases where parl is zero or the number of iterations has reached 10.
compute the Newton correction.
depending on the sign of the function, update parl or paru.
compute an improved estimate for par.
void lm_printout_std | ( | int | n_par, |
const double * | par, | ||
int | m_dat, | ||
const void * | data, | ||
const double * | fvec, | ||
int | printflags, | ||
int | iflag, | ||
int | iter, | ||
int | nfev | ||
) |
void lm_qrfac | ( | int | m, |
int | n, | ||
double * | a, | ||
int | pivot, | ||
int * | ipvt, | ||
double * | rdiag, | ||
double * | acnorm, | ||
double * | wa | ||
) |
bring the column of largest norm into the pivot position.
compute the Householder transformation to reduce the j-th column of a to a multiple of the j-th unit vector.
apply the transformation to the remaining columns and update the norms.
void lm_qrsolv | ( | int | n, |
double * | r, | ||
int | ldr, | ||
int * | ipvt, | ||
double * | diag, | ||
double * | qtb, | ||
double * | x, | ||
double * | sdiag, | ||
double * | wa | ||
) |
determine a Givens rotation which eliminates the appropriate element in the current row of d.
compute the modified diagonal element of r and the modified element of ((q transpose)*b,0).
accumulate the tranformation in the row of s.
store the diagonal element of s and restore the corresponding diagonal element of r.
void lmcurve_evaluate | ( | int | n_par, |
const double * | par, | ||
int | m_dat, | ||
const void * | data, | ||
double * | fvec, | ||
int * | info | ||
) |
void lmcurve_fit | ( | int | n_par, |
double * | par, | ||
int | m_dat, | ||
const double * | x, | ||
const double * | y, | ||
double(*)(double x, const double *par, int n_par) | function, | ||
lm_control_struct * | control, | ||
lm_status_struct * | status | ||
) |
void lmmin | ( | int | n_par, |
double * | par, | ||
int | m_dat, | ||
const void * | data, | ||
void(*)(int n_par, const double *par, int m_dat, const void *data, double *fvec, int *info) | evaluate, | ||
const lm_control_struct * | control, | ||
lm_status_struct * | status, | ||
void(*)(int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev) | printout | ||
) |
{ LM_USERTOL, LM_USERTOL, LM_USERTOL, LM_USERTOL, 100., 100, 1, 0 }
{ 1.e-7, 1.e-7, 1.e-7, 1.e-7, 100., 100, 0, 0 }
const char* lm_infmsg[] |
{ "success (sum of squares below underflow limit)", "success (the relative error in the sum of squares is at most tol)", "success (the relative error between x and the solution is at most tol)", "success (both errors are at most tol)", "trapped by degeneracy (fvec is orthogonal to the columns of the jacobian)", "timeout (number of calls to fcn has reached maxcall*(n+1))", "failure (ftol<tol: cannot reduce sum of squares any further)", "failure (xtol<tol: cannot improve approximate solution any further)", "failure (gtol<tol: cannot improve approximate solution any further)", "exception (not enough memory)", "fatal coding error (improper input parameters)", "exception (break requested within function evaluation)" }
const char* lm_shortmsg[] |
{ "success (0)", "success (f)", "success (p)", "success (f,p)", "degenerate", "call limit", "failed (f)", "failed (p)", "failed (o)", "no memory", "invalid input", "user break" }