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

📄 lmder.c

📁 开放gsl矩阵运算
💻 C
字号:
/* multfit/lmder.c *  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <config.h>#include <stddef.h>#include <stdlib.h>#include <stdio.h>#include <math.h>#include <float.h>#include <gsl/gsl_math.h>#include <gsl/gsl_errno.h>#include <gsl/gsl_multifit_nlin.h>#include <gsl/gsl_blas.h>#include <gsl/gsl_linalg.h>#include <gsl/gsl_permutation.h>typedef struct  {    size_t iter;    double xnorm;    double fnorm;    double delta;    double par;    gsl_matrix *q;    gsl_matrix *r;    gsl_vector *tau;    gsl_vector *diag;    gsl_vector *qtf;    gsl_vector *newton;    gsl_vector *gradient;    gsl_vector *x_trial;    gsl_vector *f_trial;    gsl_vector *df;    gsl_vector *sdiag;    gsl_vector *rptdx;    gsl_vector *w;    gsl_vector *work1;    gsl_permutation * perm;  }lmder_state_t;static int lmder_alloc (void *vstate, size_t n, size_t p);static int lmder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx);static int lmsder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx);static int set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale);static int lmder_iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx);static void lmder_free (void *vstate);static int iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale);#include "lmutil.c"#include "lmpar.c"#include "lmset.c"#include "lmiterate.c"static intlmder_alloc (void *vstate, size_t n, size_t p){  lmder_state_t *state = (lmder_state_t *) vstate;  gsl_matrix *q, *r;  gsl_vector *tau, *diag, *qtf, *newton, *gradient, *x_trial, *f_trial,   *df, *sdiag, *rptdx, *w, *work1;  gsl_permutation *perm;  q = gsl_matrix_calloc (n, n);  if (q == 0)    {      GSL_ERROR_VAL ("failed to allocate space for q", GSL_ENOMEM, 0);    }  state->q = q;  r = gsl_matrix_calloc (n, p);  if (r == 0)    {      gsl_matrix_free (q);      GSL_ERROR_VAL ("failed to allocate space for r", GSL_ENOMEM, 0);    }  state->r = r;  tau = gsl_vector_calloc (GSL_MIN(n, p));  if (tau == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      GSL_ERROR_VAL ("failed to allocate space for tau", GSL_ENOMEM, 0);    }  state->tau = tau;  diag = gsl_vector_calloc (p);  if (diag == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      GSL_ERROR_VAL ("failed to allocate space for diag", GSL_ENOMEM, 0);    }  state->diag = diag;  qtf = gsl_vector_calloc (n);  if (qtf == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      GSL_ERROR_VAL ("failed to allocate space for qtf", GSL_ENOMEM, 0);    }  state->qtf = qtf;  newton = gsl_vector_calloc (p);  if (newton == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      GSL_ERROR_VAL ("failed to allocate space for newton", GSL_ENOMEM, 0);    }  state->newton = newton;  gradient = gsl_vector_calloc (p);  if (gradient == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      GSL_ERROR_VAL ("failed to allocate space for gradient", GSL_ENOMEM, 0);    }  state->gradient = gradient;  x_trial = gsl_vector_calloc (p);  if (x_trial == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      GSL_ERROR_VAL ("failed to allocate space for x_trial", GSL_ENOMEM, 0);    }  state->x_trial = x_trial;  f_trial = gsl_vector_calloc (n);  if (f_trial == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      gsl_vector_free (x_trial);      GSL_ERROR_VAL ("failed to allocate space for f_trial", GSL_ENOMEM, 0);    }  state->f_trial = f_trial;  df = gsl_vector_calloc (n);  if (df == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      gsl_vector_free (x_trial);      gsl_vector_free (f_trial);      GSL_ERROR_VAL ("failed to allocate space for df", GSL_ENOMEM, 0);    }  state->df = df;  sdiag = gsl_vector_calloc (p);  if (sdiag == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      gsl_vector_free (x_trial);      gsl_vector_free (f_trial);      gsl_vector_free (df);      GSL_ERROR_VAL ("failed to allocate space for sdiag", GSL_ENOMEM, 0);    }  state->sdiag = sdiag;  rptdx = gsl_vector_calloc (n);  if (rptdx == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      gsl_vector_free (x_trial);      gsl_vector_free (f_trial);      gsl_vector_free (df);      gsl_vector_free (sdiag);      GSL_ERROR_VAL ("failed to allocate space for rptdx", GSL_ENOMEM, 0);    }  state->rptdx = rptdx;  w = gsl_vector_calloc (n);  if (w == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      gsl_vector_free (x_trial);      gsl_vector_free (f_trial);      gsl_vector_free (df);      gsl_vector_free (sdiag);      gsl_vector_free (rptdx);      GSL_ERROR_VAL ("failed to allocate space for w", GSL_ENOMEM, 0);    }  state->w = w;  work1 = gsl_vector_calloc (p);  if (work1 == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      gsl_vector_free (x_trial);      gsl_vector_free (f_trial);      gsl_vector_free (df);      gsl_vector_free (sdiag);      gsl_vector_free (rptdx);      gsl_vector_free (w);      GSL_ERROR_VAL ("failed to allocate space for work1", GSL_ENOMEM, 0);    }  state->work1 = work1;  perm = gsl_permutation_calloc (p);  if (perm == 0)    {      gsl_matrix_free (q);      gsl_matrix_free (r);      gsl_vector_free (tau);      gsl_vector_free (diag);      gsl_vector_free (qtf);      gsl_vector_free (newton);      gsl_vector_free (gradient);      gsl_vector_free (x_trial);      gsl_vector_free (f_trial);      gsl_vector_free (df);      gsl_vector_free (sdiag);      gsl_vector_free (rptdx);      gsl_vector_free (w);      gsl_vector_free (work1);      GSL_ERROR_VAL ("failed to allocate space for perm", GSL_ENOMEM, 0);    }  state->perm = perm;  return GSL_SUCCESS;}static intlmder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx){  int status = set (vstate, fdf, x, f, J, dx, 0);  return status ;}static intlmsder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx){  int status = set (vstate, fdf, x, f, J, dx, 1);  return status ;}static intlmder_iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx){  int status = iterate (vstate, fdf, x, f, J, dx, 0);  return status;}static intlmsder_iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx){  int status = iterate (vstate, fdf, x, f, J, dx, 1);  return status;}static voidlmder_free (void *vstate){  lmder_state_t *state = (lmder_state_t *) vstate;  gsl_permutation_free (state->perm);  gsl_vector_free (state->work1);  gsl_vector_free (state->w);  gsl_vector_free (state->rptdx);  gsl_vector_free (state->sdiag);  gsl_vector_free (state->df);  gsl_vector_free (state->f_trial);  gsl_vector_free (state->x_trial);  gsl_vector_free (state->gradient);  gsl_vector_free (state->newton);  gsl_vector_free (state->qtf);  gsl_vector_free (state->diag);  gsl_vector_free (state->tau);  gsl_matrix_free (state->r);  gsl_matrix_free (state->q);}static const gsl_multifit_fdfsolver_type lmder_type ={  "lmder",			/* name */  sizeof (lmder_state_t),  &lmder_alloc,  &lmder_set,  &lmder_iterate,  &lmder_free};static const gsl_multifit_fdfsolver_type lmsder_type ={  "lmsder",			/* name */  sizeof (lmder_state_t),  &lmder_alloc,  &lmsder_set,  &lmsder_iterate,  &lmder_free};const gsl_multifit_fdfsolver_type *gsl_multifit_fdfsolver_lmder = &lmder_type;const gsl_multifit_fdfsolver_type *gsl_multifit_fdfsolver_lmsder = &lmsder_type;

⌨️ 快捷键说明

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