SuperBug

博客园 首页 联系 订阅 管理

dlevmar_dif()

*****************************************************************************************************************************

/*
* Similar to dlevmar_der() except that the Jacobian is approximated internally with the aid of finite differences.
* Broyden's rank one updates are used to compute secant approximations to the Jacobian, effectively avoiding to call
* func several times for computing the finite difference approximations.
* If the analytic Jacobian is available, use dlevmar_der() above.
*
* Returns the number of iterations (>=0) if successful, -1 if failed
*
*/
int dlevmar_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata), /* functional relation describing measurements.
                                                                 * A p \in R^m yields a \hat{x} \in  R^n
                                                                 */
double *p,         /* I/O: initial parameter estimates. On output contains the estimated solution */
double *x,         /* I: measurement vector. NULL implies a zero vector */
int m,             /* I: parameter vector dimension (i.e. #unknowns) */
int n,             /* I: measurement vector dimension */
int itmax,         /* I: maximum number of iterations */
double opts[5],    /* I: opts[0-4] = minim. options [\tau, \epsilon1, \epsilon2, \epsilon3, \delta]. Respectively the
                    * scale factor for initial \mu, stopping thresholds for ||J^T e||_inf, ||Dp||_2 and ||e||_2 and the
                    * step used in difference approximation to the Jacobian. If \delta<0, the Jacobian is approximated
                    * with central differences which are more accurate (but slower!) compared to the forward differences
                    * employed by default. Set to NULL for defaults to be used.
                    */
double info[LM_INFO_SZ],
                    /* O: information regarding the minimization. Set to NULL if don't care
                     * info[0]= ||e||_2 at initial p.
                     * info[1-4]=[ ||e||_2, ||J^T e||_inf,  ||Dp||_2, \mu/max[J^T J]_ii ], all computed at estimated p.
                     * info[5]= # iterations,
                     * info[6]=reason for terminating: 1 - stopped by small gradient J^T e
                     *                                 2 - stopped by small Dp
                     *                                 3 - stopped by itmax
                     *                                 4 - singular matrix. Restart from current p with increased \mu
                     *                                 5 - no further error reduction is possible. Restart with increased mu
                     *                                 6 - stopped by small ||e||_2
                     *                                 7 - stopped by invalid (i.e. NaN or Inf) "func" values; a user error
                     * info[7]= # function evaluations
                     * info[8]= # Jacobian evaluations
                     * info[9]= # linear systems solved, i.e. # attempts for reducing error
                     */
double *work,      /* I: working memory, allocated internally if NULL. If !=NULL, it is assumed to point to
                    * a memory chunk at least LM_DIF_WORKSZ(m, n)*sizeof(double) bytes long
                    */
double *covar,     /* O: Covariance matrix corresponding to LS solution; Assumed to point to a mxm matrix.
                    * Set to NULL if not needed.
                    */
void *adata)       /* I: pointer to possibly needed additional data, passed uninterpreted to func.
                    * Set to NULL if not needed
                    */

********************************************以上是官方网站的解释******************************************************************

dlevmar_dif()的作用:总的来说dlevmar_dif()的作用就是拟合。设有初始向量A,用户给定需要拟合的向量B,以及约束向量C,dlevmar_dif()的作用就是使得在满足约束向量C的情况下尽量使得向量A接近向量B。

该拟合过程是一个迭代的过程,大概可以这样描述(不一定准确):

步骤1.初始向量A,和需要拟合的向量B,求的变换T,使得TA更加接近B。

步骤2.求的约束向量C = TA-B。

步骤3.若C不够小则继续步骤1.

 

下面对dlevmar_dif()的参数一一进行介绍:

参数1:void (*func)(double *p, double *hx, int m, int n, void *adata)

该参数是一个函数指针,需要传递一个参数进来。其中,p表示初始化的一个向量,也就是上面说的A,hx存放目标函数,也就是上面说的C,m表示p的维数,n表示hx的维数,adata表示附加的信息,可以为任何你想传进来的参数。该函数需要你自己来写,在函数中最重要的就是填充hx向量,因为dlevmar_dif()每次都会调用该函数,并检测hx的值来判断是否迭代,如果hx的值足够小就dlevmar_dif()就会退出。

参数2:double *p

该参数传递给参数1的第一个参数。

参数3:double *x

该参数一般设置为NULL。至少我暂时不知道它的用途。

参数4:int m

该参数表示参数2的维数。

参数5:int n

该参数表示约束向量的维数

参数6:int itmax

该参数表示最大迭代次数

参数7:double opts[5]

该参数记录一些我不知道的信息,嘿嘿

参数8:double info[LM_INFO_SZ]

该参数表示返回的一些函数信息

参数9:double *work

不知道干啥用的,我设定为null

参数10:double *covar

不知道干啥用的,我设定为null

参数11:void *adata

传递给参数1的最后一个参数。我一般存放用来拟合的向量。

 

总的来说,dlevmar_dif()的作用就是通过迭代,将向量p在使得hx最小的情况下拟合给出的数据。每次迭代都会检测hx中的值是不是比较小(趋向于0)。向量p是个初始向量,是用户自己给出的

posted on 2012-12-04 20:16  SuperBug  阅读(4457)  评论(0编辑  收藏  举报