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

📄 multifit.texi

📁 GNU Scientific Library,C语言开发的数值方面的函数库
💻 TEXI
📖 第 1 页 / 共 2 页
字号:
the decrease in the function falls below machine precision@item GSL_ETOLXthe change in the position vector falls below machine precision@item GSL_ETOLGthe norm of the gradient, relative to the norm of the function, fallsbelow machine precision@end table@noindentThese error codes indicate that further iterations will be unlikely tochange the solution from its current value.@end deffn@deffn {Derivative Solver} gsl_multifit_fdfsolver_lmderThis is an unscaled version of the @sc{lmder} algorithm.  The elements of thediagonal scaling matrix @math{D} are set to 1.  This algorithm may beuseful in circumstances where the scaled version of @sc{lmder} converges tooslowly, or the function is already scaled appropriately.@end deffn@node Minimization Algorithms without Derivatives@section Minimization Algorithms without DerivativesThere are no algorithms implemented in this section at the moment.@node Computing the covariance matrix of best fit parameters@section Computing the covariance matrix of best fit parameters@cindex covariance of best-fit parameters@cindex best-fit parameters, covariance@cindex least-squares, covariance of best-fit parameters@deftypefun int gsl_multifit_covar (const gsl_matrix * @var{J}, double @var{epsrel}, gsl_matrix * @var{covar})This function uses the Jacobian matrix @var{J} to compute the covariancematrix of the best-fit parameters, @var{covar}.  The parameter@var{epsrel} is used to remove linear-dependent columns when @var{J} isrank deficient.The covariance matrix is given by,@tex\beforedisplay$$C = (J^T J)^{-1}$$\afterdisplay@end tex@ifinfo@examplecovar = (J^T J)^@{-1@}@end example@end ifinfo@noindentand is computed by QR decomposition of J with column-pivoting.  Anycolumns of @math{R} which satisfy @tex\beforedisplay$$|R_{kk}| \leq epsrel |R_{11}|$$\afterdisplay@end tex@ifinfo@example|R_@{kk@}| <= epsrel |R_@{11@}|@end example@end ifinfo@noindentare considered linearly-dependent and are excluded from the covariancematrix (the corresponding rows and columns of the covariance matrix areset to zero).@end deftypefun@comment ============================================================@node Example programs for Nonlinear Least-Squares Fitting@section ExamplesThe following example program fits a weighted exponential model withbackground to experimental data, @math{Y = A \exp(-\lambda t) + b}. Thefirst part of the program sets up the functions @code{expb_f} and@code{expb_df} to calculate the model and its Jacobian.  The appropriatefitting function is given by,@tex\beforedisplay$$f_i = ((A \exp(-\lambda t_i) + b) - y_i)/\sigma_i$$\afterdisplay@end tex@ifinfo@examplef_i = ((A \exp(-\lambda t_i) + b) - y_i)/\sigma_i@end example@end ifinfo@noindentwhere we have chosen @math{t_i = i}.  The Jacobian matrix @math{J} isthe derivative of these functions with respect to the three parameters(@math{A}, @math{\lambda}, @math{b}).  It is given by,@tex\beforedisplay$$J_{ij} = {\partial f_i \over \partial x_j}$$\afterdisplay@end tex@ifinfo@exampleJ_@{ij@} = d f_i / d x_j@end example@end ifinfo@noindentwhere @math{x_0 = A}, @math{x_1 = \lambda} and @math{x_2 = b}.@example#include <stdlib.h>#include <stdio.h>#include <gsl/gsl_rng.h>#include <gsl/gsl_randist.h>#include <gsl/gsl_vector.h>#include <gsl/gsl_blas.h>#include <gsl/gsl_multifit_nlin.h>struct data @{  size_t n;  double * y;  double * sigma;@};intexpb_f (const gsl_vector * x, void *params,         gsl_vector * f)@{  size_t n = ((struct data *)params)->n;  double *y = ((struct data *)params)->y;  double *sigma = ((struct data *) params)->sigma;  double A = gsl_vector_get (x, 0);  double lambda = gsl_vector_get (x, 1);  double b = gsl_vector_get (x, 2);  size_t i;  for (i = 0; i < n; i++)    @{      /* Model Yi = A * exp(-lambda * i) + b */      double t = i;      double Yi = A * exp (-lambda * t) + b;      gsl_vector_set (f, i, (Yi - y[i])/sigma[i]);    @}  return GSL_SUCCESS;@}intexpb_df (const gsl_vector * x, void *params,          gsl_matrix * J)@{  size_t n = ((struct data *)params)->n;  double *sigma = ((struct data *) params)->sigma;  double A = gsl_vector_get (x, 0);  double lambda = gsl_vector_get (x, 1);  size_t i;  for (i = 0; i < n; i++)    @{      /* Jacobian matrix J(i,j) = dfi / dxj, */      /* where fi = (Yi - yi)/sigma[i],      */      /*       Yi = A * exp(-lambda * i) + b  */      /* and the xj are the parameters (A,lambda,b) */      double t = i;      double s = sigma[i];      double e = exp(-lambda * t);      gsl_matrix_set (J, i, 0, e/s);       gsl_matrix_set (J, i, 1, -t * A * e/s);      gsl_matrix_set (J, i, 2, 1/s);    @}  return GSL_SUCCESS;@}intexpb_fdf (const gsl_vector * x, void *params,          gsl_vector * f, gsl_matrix * J)@{  expb_f (x, params, f);  expb_df (x, params, J);  return GSL_SUCCESS;@}@end example@noindentThe main part of the program sets up a Levenberg-Marquardt solver andsome simulated random data. The data uses the known parameters(1.0,5.0,0.1) combined with gaussian noise (standard deviation = 0.1)over a range of 40 timesteps. The initial guess for the parameters ischosen as (0.0, 1.0, 0.0).@example#define N 40intmain (void)@{  const gsl_multifit_fdfsolver_type *T;  gsl_multifit_fdfsolver *s;  int status;  size_t i, iter = 0;  const size_t n = N;  const size_t p = 3;  gsl_matrix *covar = gsl_matrix_alloc (p, p);  double y[N], sigma[N];  struct data d = @{ n, y, sigma@};    gsl_multifit_function_fdf f;  double x_init[3] = @{ 1.0, 0.0, 0.0 @};  gsl_vector_view x = gsl_vector_view_array (x_init, p);  const gsl_rng_type * type;  gsl_rng * r;  gsl_rng_env_setup();  type = gsl_rng_default;  r = gsl_rng_alloc (type);  f.f = &expb_f;  f.df = &expb_df;  f.fdf = &expb_fdf;  f.n = n;  f.p = p;  f.params = &d;  /* This is the data to be fitted */  for (i = 0; i < n; i++)    @{      double t = i;      y[i] = 1.0 + 5 * exp (-0.1 * t)                  + gsl_ran_gaussian (r, 0.1);      sigma[i] = 0.1;      printf ("data: %d %g %g\n", i, y[i], sigma[i]);    @};  T = gsl_multifit_fdfsolver_lmsder;  s = gsl_multifit_fdfsolver_alloc (T, n, p);  gsl_multifit_fdfsolver_set (s, &f, &x.vector);  print_state (iter, s);  do    @{      iter++;      status = gsl_multifit_fdfsolver_iterate (s);      printf ("status = %s\n", gsl_strerror (status));      print_state (iter, s);      if (status)        break;      status = gsl_multifit_test_delta (s->dx, s->x,                                        1e-4, 1e-4);    @}  while (status == GSL_CONTINUE && iter < 500);  gsl_multifit_covar (s->J, 0.0, covar);#define FIT(i) gsl_vector_get(s->x, i)#define ERR(i) sqrt(gsl_matrix_get(covar,i,i))  printf ("A      = %.5f +/- %.5f\n", FIT(0), ERR(0));  printf ("lambda = %.5f +/- %.5f\n", FIT(1), ERR(1));  printf ("b      = %.5f +/- %.5f\n", FIT(2), ERR(2));  @{     double chi = gsl_blas_dnrm2(s->f);    printf("chisq/dof = %g\n",  pow(chi, 2.0)/ (n - p));  @}  printf ("status = %s\n", gsl_strerror (status));  gsl_multifit_fdfsolver_free (s);  return 0;@}voidprint_state (size_t iter, gsl_multifit_fdfsolver * s)@{  printf ("iter: %3u x = % 15.8f % 15.8f % 15.8f "          "|f(x)| = %g\n",          iter,          gsl_vector_get (s->x, 0),           gsl_vector_get (s->x, 1),          gsl_vector_get (s->x, 2),           gsl_blas_dnrm2 (s->f));@}@end example@noindentThe iteration terminates when the change in x is smaller than 0.0001, asboth an absolute and relative change.  Here are the results of runningthe program:@smallexampleiter: 0 x = 1.00000000 0.00000000 0.00000000 |f(x)| = 118.574iter: 1 x = 1.64919392 0.01780040 0.64919392 |f(x)| = 77.2068iter: 2 x = 2.86269020 0.08032198 1.45913464 |f(x)| = 38.0579iter: 3 x = 4.97908864 0.11510525 1.06649948 |f(x)| = 10.1548iter: 4 x = 5.03295496 0.09912462 1.00939075 |f(x)| = 6.4982iter: 5 x = 5.05811477 0.10055914 0.99819876 |f(x)| = 6.33121iter: 6 x = 5.05827645 0.10051697 0.99756444 |f(x)| = 6.33119iter: 7 x = 5.05828006 0.10051819 0.99757710 |f(x)| = 6.33119A      = 5.05828 +/- 0.05983lambda = 0.10052 +/- 0.00309b      = 0.99758 +/- 0.03944chisq/dof = 1.08335status = success@end smallexample@noindentThe approximate values of the parameters are found correctly, and thechi-squared value indicates a good fit (the chi-squared per degree offreedom is approximately 1).  In this case the errors on the parameterscan be estimated from the square roots of the diagonal elements of thecovariance matrix.  If the chi-squared value indicates a poor fit thenerror estimates obtained from the covariance matrix are not valid, sincethe Gaussian approximation would not apply.@iftex@sp 1@center @image{fit-exp,3.4in}@end iftex@node References and Further Reading for Nonlinear Least-Squares Fitting@section References and Further ReadingThe @sc{minpack} algorithm is described in the following article,@itemize @asis@itemJ.J. Mor@'e, @cite{The Levenberg-Marquardt Algorithm: Implementation andTheory}, Lecture Notes in Mathematics, v630 (1978), ed G. Watson.@end itemize@noindentThe following paper is also relevant to the algorithms described in thissection,@itemize @asis@item J.J. Mor@'e, B.S. Garbow, K.E. Hillstrom, "Testing UnconstrainedOptimization Software", ACM Transactions on Mathematical Software, Vol7, No 1 (1981), p 17-41.@end itemize

⌨️ 快捷键说明

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