⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lmblec_core.c

📁 A sparse variant of the Levenberg-Marquardt algorithm implemented by levmar has been applied to bund
💻 C
📖 第 1 页 / 共 2 页
字号:
                      *                                 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. This is a user error                      * info[7]= # function evaluations                      * info[8]= # Jacobian evaluations                      * info[9]= # linear systems solved, i.e. # attempts for reducing error                      */  LM_REAL *work,     /* working memory at least LM_BLEC_DER_WORKSZ() reals large, allocated if NULL */  LM_REAL *covar,    /* O: Covariance matrix corresponding to LS solution; mxm. Set to NULL if not needed. */  void *adata)       /* pointer to possibly additional data, passed uninterpreted to func & jacf.                      * Set to NULL if not needed                      */{  struct LMBLEC_DATA data;  int ret;  LM_REAL locinfo[LM_INFO_SZ];  register int i;  if(!jacf){    fprintf(stderr, RCAT("No function specified for computing the Jacobian in ", LEVMAR_BLEC_DER)      RCAT("().\nIf no such function is available, use ", LEVMAR_BLEC_DIF) RCAT("() rather than ", LEVMAR_BLEC_DER) "()\n");    return LM_ERROR;  }  if(!lb && !ub){    fprintf(stderr, RCAT(LCAT(LEVMAR_BLEC_DER, "(): lower and upper bounds for box constraints cannot be both NULL, use "),          LEVMAR_LEC_DER) "() in this case!\n");    return LM_ERROR;  }  if(!LEVMAR_BOX_CHECK(lb, ub, m)){    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): at least one lower bound exceeds the upper one\n"));    return LM_ERROR;  }  /* measurement vector needs to be extended by m */  if(x){ /* nonzero x */    data.x=(LM_REAL *)malloc((n+m)*sizeof(LM_REAL));    if(!data.x){      fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #1 failed\n"));      return LM_ERROR;    }    for(i=0; i<n; ++i)      data.x[i]=x[i];    for(i=n; i<n+m; ++i)      data.x[i]=0.0;  }  else    data.x=NULL;  data.w=(LM_REAL *)malloc(m*sizeof(LM_REAL) + m*sizeof(int)); /* should be arranged in that order for proper doubles alignment */  if(!data.w){    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #2 failed\n"));    if(data.x) free(data.x);    return LM_ERROR;  }  data.bctype=(int *)(data.w+m);  /* note: at this point, one of lb, ub are not NULL */  for(i=0; i<m; ++i){    data.w[i]=(!wghts)? __BC_WEIGHT__ : wghts[i];    if(!lb) data.bctype[i]=__BC_HIGH__;    else if(!ub) data.bctype[i]=__BC_LOW__;    else if(ub[i]!=LM_REAL_MAX && lb[i]!=LM_REAL_MIN) data.bctype[i]=__BC_INTERVAL__;    else if(lb[i]!=LM_REAL_MIN) data.bctype[i]=__BC_LOW__;    else data.bctype[i]=__BC_HIGH__;  }  data.lb=lb;  data.ub=ub;  data.func=func;  data.jacf=jacf;  data.adata=adata;  if(!info) info=locinfo; /* make sure that LEVMAR_LEC_DER() is called with non-null info */  ret=LEVMAR_LEC_DER(LMBLEC_FUNC, LMBLEC_JACF, p, data.x, m, n+m, A, b, k, itmax, opts, info, work, covar, (void *)&data);  if(data.x) free(data.x);  free(data.w);  return ret;}/* Similar to the LEVMAR_BLEC_DER() function above, except that the Jacobian is approximated * with the aid of finite differences (forward or central, see the comment for the opts argument) */int LEVMAR_BLEC_DIF(  void (*func)(LM_REAL *p, LM_REAL *hx, int m, int n, void *adata), /* functional relation describing measurements. A p \in R^m yields a \hat{x} \in  R^n */  LM_REAL *p,         /* I/O: initial parameter estimates. On output has the estimated solution */  LM_REAL *x,         /* I: measurement vector. NULL implies a zero vector */  int m,              /* I: parameter vector dimension (i.e. #unknowns) */  int n,              /* I: measurement vector dimension */  LM_REAL *lb,        /* I: vector of lower bounds. If NULL, no lower bounds apply */  LM_REAL *ub,        /* I: vector of upper bounds. If NULL, no upper bounds apply */  LM_REAL *A,         /* I: constraints matrix, kxm */  LM_REAL *b,         /* I: right hand constraints vector, kx1 */  int k,              /* I: number of constraints (i.e. A's #rows) */  LM_REAL *wghts,     /* mx1 weights for penalty terms, defaults used if NULL */  int itmax,          /* I: maximum number of iterations */  LM_REAL opts[5],    /* I: opts[0-3] = minim. options [\mu, \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. Set to NULL for defaults to be used.                       * If \delta<0, the Jacobian is approximated with central differences which are more accurate                       * (but slower!) compared to the forward differences employed by default.                        */  LM_REAL 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. This is a user error                      * info[7]= # function evaluations                      * info[8]= # Jacobian evaluations                      * info[9]= # linear systems solved, i.e. # attempts for reducing error                      */  LM_REAL *work,     /* working memory at least LM_BLEC_DIF_WORKSZ() reals large, allocated if NULL */  LM_REAL *covar,    /* O: Covariance matrix corresponding to LS solution; mxm. Set to NULL if not needed. */  void *adata)       /* pointer to possibly additional data, passed uninterpreted to func.                      * Set to NULL if not needed                      */{  struct LMBLEC_DATA data;  int ret;  register int i;  LM_REAL locinfo[LM_INFO_SZ];  if(!lb && !ub){    fprintf(stderr, RCAT(LCAT(LEVMAR_BLEC_DIF, "(): lower and upper bounds for box constraints cannot be both NULL, use "),          LEVMAR_LEC_DIF) "() in this case!\n");    return LM_ERROR;  }  if(!LEVMAR_BOX_CHECK(lb, ub, m)){    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): at least one lower bound exceeds the upper one\n"));    return LM_ERROR;  }  /* measurement vector needs to be extended by m */  if(x){ /* nonzero x */    data.x=(LM_REAL *)malloc((n+m)*sizeof(LM_REAL));    if(!data.x){      fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #1 failed\n"));      return LM_ERROR;    }    for(i=0; i<n; ++i)      data.x[i]=x[i];    for(i=n; i<n+m; ++i)      data.x[i]=0.0;  }  else    data.x=NULL;  data.w=(LM_REAL *)malloc(m*sizeof(LM_REAL) + m*sizeof(int)); /* should be arranged in that order for proper doubles alignment */  if(!data.w){    fprintf(stderr, LCAT(LEVMAR_BLEC_DER, "(): memory allocation request #2 failed\n"));    if(data.x) free(data.x);    return LM_ERROR;  }  data.bctype=(int *)(data.w+m);  /* note: at this point, one of lb, ub are not NULL */  for(i=0; i<m; ++i){    data.w[i]=(!wghts)? __BC_WEIGHT__ : wghts[i];    if(!lb) data.bctype[i]=__BC_HIGH__;    else if(!ub) data.bctype[i]=__BC_LOW__;    else if(ub[i]!=LM_REAL_MAX && lb[i]!=LM_REAL_MIN) data.bctype[i]=__BC_INTERVAL__;    else if(lb[i]!=LM_REAL_MIN) data.bctype[i]=__BC_LOW__;    else data.bctype[i]=__BC_HIGH__;  }  data.lb=lb;  data.ub=ub;  data.func=func;  data.jacf=NULL;  data.adata=adata;  if(!info) info=locinfo; /* make sure that LEVMAR_LEC_DIF() is called with non-null info */  ret=LEVMAR_LEC_DIF(LMBLEC_FUNC, p, data.x, m, n+m, A, b, k, itmax, opts, info, work, covar, (void *)&data);  if(data.x) free(data.x);  free(data.w);  return ret;}/* undefine all. THIS MUST REMAIN AT THE END OF THE FILE */#undef LEVMAR_BOX_CHECK#undef LMBLEC_DATA#undef LMBLEC_FUNC#undef LMBLEC_JACF#undef LEVMAR_COVAR#undef LEVMAR_LEC_DER#undef LEVMAR_LEC_DIF#undef LEVMAR_BLEC_DER#undef LEVMAR_BLEC_DIF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -