2 iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale)
4 lmder_state_t *state = (lmder_state_t *) vstate;
6 gsl_matrix *r = state->r;
7 gsl_vector *tau = state->tau;
8 gsl_vector *diag = state->diag;
9 gsl_vector *qtf = state->qtf;
10 gsl_vector *x_trial = state->x_trial;
11 gsl_vector *f_trial = state->f_trial;
12 gsl_vector *rptdx = state->rptdx;
13 gsl_vector *newton = state->newton;
14 gsl_vector *gradient = state->gradient;
15 gsl_vector *sdiag = state->sdiag;
16 gsl_vector *w = state->w;
17 gsl_vector *work1 = state->work1;
18 gsl_permutation *perm = state->perm;
20 double prered, actred;
21 double pnorm, fnorm1, fnorm1p, gnorm;
27 double p1 = 0.1, p25 = 0.25, p5 = 0.5, p75 = 0.75, p0001 = 0.0001;
29 if (state->fnorm == 0.0)
34 /* Compute qtf = Q^T f */
36 gsl_vector_memcpy (qtf, f);
37 gsl_linalg_QR_QTvec (r, tau, qtf);
39 /* Compute norm of scaled gradient */
41 compute_gradient_direction (r, perm, qtf, diag, gradient);
44 size_t iamax = gsl_blas_idamax (gradient);
46 gnorm = fabs(gsl_vector_get (gradient, iamax) / state->fnorm);
49 /* Determine the Levenberg-Marquardt parameter */
56 int status = lmpar (r, perm, qtf, diag, state->delta, &(state->par), newton, gradient, sdiag, dx, w);
61 /* Take a trial step */
63 gsl_vector_scale (dx, -1.0); /* reverse the step to go downhill */
65 compute_trial_step (x, dx, state->x_trial);
67 pnorm = scaled_enorm (diag, dx);
71 if (pnorm < state->delta)
74 printf("set delta = pnorm = %g\n" , pnorm);
80 /* Evaluate function at x + p */
81 /* return immediately if evaluation raised error */
83 int status = GSL_MULTIFIT_FN_EVAL_F (fdf, x_trial, f_trial);
88 fnorm1 = enorm (f_trial);
90 /* Compute the scaled actual reduction */
92 actred = compute_actual_reduction (state->fnorm, fnorm1);
95 printf("lmiterate: fnorm = %g fnorm1 = %g actred = %g\n", state->fnorm, fnorm1, actred);
96 printf("r = "); gsl_matrix_fprintf(stdout, r, "%g");
97 printf("perm = "); gsl_permutation_fprintf(stdout, perm, "%d");
98 printf("dx = "); gsl_vector_fprintf(stdout, dx, "%g");
101 /* Compute rptdx = R P^T dx, noting that |J dx| = |R P^T dx| */
103 compute_rptdx (r, perm, dx, rptdx);
106 printf("rptdx = "); gsl_vector_fprintf(stdout, rptdx, "%g");
109 fnorm1p = enorm (rptdx);
111 /* Compute the scaled predicted reduction = |J dx|^2 + 2 par |D dx|^2 */
114 double t1 = fnorm1p / state->fnorm;
115 double t2 = (sqrt(state->par) * pnorm) / state->fnorm;
117 prered = t1 * t1 + t2 * t2 / p5;
118 dirder = -(t1 * t1 + t2 * t2);
121 /* compute the ratio of the actual to predicted reduction */
125 ratio = actred / prered;
133 printf("lmiterate: prered = %g dirder = %g ratio = %g\n", prered, dirder,ratio);
137 /* update the step bound */
142 printf("ratio > p25\n");
144 if (state->par == 0 || ratio >= p75)
146 state->delta = pnorm / p5;
149 printf("updated step bounds: delta = %g, par = %g\n", state->delta, state->par);
155 double temp = (actred >= 0) ? p5 : p5*dirder / (dirder + p5 * actred);
158 printf("ratio < p25\n");
161 if (p1 * fnorm1 >= state->fnorm || temp < p1 )
166 state->delta = temp * GSL_MIN_DBL (state->delta, pnorm/p1);
170 printf("updated step bounds: delta = %g, par = %g\n", state->delta, state->par);
175 /* test for successful iteration, termination and stringent tolerances */
179 gsl_vector_memcpy (x, x_trial);
180 gsl_vector_memcpy (f, f_trial);
182 /* return immediately if evaluation raised error */
184 int status = GSL_MULTIFIT_FN_EVAL_DF (fdf, x_trial, J);
189 /* wa2_j = diag_j * x_j */
190 state->xnorm = scaled_enorm(diag, x);
191 state->fnorm = fnorm1;
194 /* Rescale if necessary */
198 update_diag (J, diag);
203 gsl_matrix_memcpy (r, J);
204 gsl_linalg_QRPT_decomp (r, tau, perm, &signum, work1);
209 else if (fabs(actred) <= GSL_DBL_EPSILON && prered <= GSL_DBL_EPSILON
210 && p5 * ratio <= 1.0)
214 else if (state->delta <= GSL_DBL_EPSILON * state->xnorm)
218 else if (gnorm <= GSL_DBL_EPSILON)
224 /* Repeat inner loop if unsuccessful */