From d9b26d16c063aec32b70287ff861a1f23642a9f2 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 4 Mar 2020 17:10:31 +0100 Subject: Fix frequency measurement simulation --- controller/fw/levmarq/levmarq.c | 272 +++++++++++++++++++++------------------- 1 file changed, 141 insertions(+), 131 deletions(-) (limited to 'controller/fw/levmarq') diff --git a/controller/fw/levmarq/levmarq.c b/controller/fw/levmarq/levmarq.c index bbf00c0..a3a77b5 100644 --- a/controller/fw/levmarq/levmarq.c +++ b/controller/fw/levmarq/levmarq.c @@ -20,6 +20,7 @@ #include #include "levmarq.h" +#include "simulation.h" #define TOL 1e-20f /* smallest value allowed in cholesky_decomp() */ @@ -28,18 +29,20 @@ /* set parameters required by levmarq() to default values */ void levmarq_init(LMstat *lmstat) { - lmstat->max_it = 10000; - lmstat->init_lambda = 0.0001f; - lmstat->up_factor = 10.0f; - lmstat->down_factor = 10.0f; - lmstat->target_derr = 1e-12f; + lmstat->max_it = 10000; + lmstat->init_lambda = 0.0001f; + lmstat->up_factor = 10.0f; + lmstat->down_factor = 10.0f; + lmstat->target_derr = 1e-12f; } +#ifndef SIMULATION float sqrtf(float arg) { float out=NAN; arm_sqrt_f32(arg, &out); return out; } +#endif /* perform least-squares minimization using the Levenberg-Marquardt algorithm. The arguments are as follows: @@ -49,140 +52,147 @@ float sqrtf(float arg) { ny number of measurements to be fit y array of measurements dysq array of error in measurements, squared - (set dysq=NULL for unweighted least-squares) + (set dysq=NULL for unweighted least-squares) func function to be fit grad gradient of "func" with respect to the input parameters fdata pointer to any additional data required by the function lmstat pointer to the "status" structure, where minimization parameters - are set and the final status is returned. + are set and the final status is returned. Before calling levmarq, several of the parameters in lmstat must be set. For default values, call levmarq_init(lmstat). - */ + */ int levmarq(int npar, float *par, int ny, float *y, float *dysq, - float (*func)(float *, int, void *), - void (*grad)(float *, float *, int, void *), - void *fdata, LMstat *lmstat) + float (*func)(float *, int, void *), + void (*grad)(float *, float *, int, void *), + void *fdata, LMstat *lmstat) { - int x,i,j,it,nit,ill; - float lambda,up,down,mult,weight,err,newerr,derr,target_derr; - float h[npar][npar],ch[npar][npar]; - float g[npar],d[npar],delta[npar],newpar[npar]; - - nit = lmstat->max_it; - lambda = lmstat->init_lambda; - up = lmstat->up_factor; - down = 1/lmstat->down_factor; - target_derr = lmstat->target_derr; - weight = 1; - derr = newerr = 0; /* to avoid compiler warnings */ - - /* calculate the initial error ("chi-squared") */ - err = error_func(par, ny, y, dysq, func, fdata); - - /* main iteration */ - for (it=0; it 0); - } - if (ill) { - mult = (1 + lambda*up)/(1 + lambda); - lambda *= up; - it++; - } + int x,i,j,it,nit,ill; + float lambda,up,down,mult,weight,err,newerr,derr,target_derr; + float h[npar][npar],ch[npar][npar]; + float g[npar],d[npar],delta[npar],newpar[npar]; + + nit = lmstat->max_it; + lambda = lmstat->init_lambda; + up = lmstat->up_factor; + down = 1/lmstat->down_factor; + target_derr = lmstat->target_derr; + weight = 1; + derr = newerr = 0; /* to avoid compiler warnings */ + + /* calculate the initial error ("chi-squared") */ + err = error_func(par, ny, y, dysq, func, fdata); + + /* main iteration */ + for (it=0; it 0); + } + if (ill) { + mult = (1 + lambda*up)/(1 + lambda); + lambda *= up; + it++; + } + } + for (i=0; ifinal_it = it; + lmstat->final_err = err; + lmstat->final_derr = derr; - lmstat->final_it = it; - lmstat->final_err = err; - lmstat->final_derr = derr; + if (it == nit) { + DEBUG_PRINT("did not converge"); + return -1; + } - return (it==nit); + return it; } /* calculate the error function (chi-squared) */ float error_func(float *par, int ny, float *y, float *dysq, - float (*func)(float *, int, void *), void *fdata) + float (*func)(float *, int, void *), void *fdata) { - int x; - float res,e=0; - - for (x=0; x=0; i--) { - sum = 0; - for (j=i+1; j=0; i--) { + sum = 0; + for (j=i+1; j