|
Packit |
67cb25 |
static int
|
|
Packit |
67cb25 |
set (void *vstate, const gsl_vector * swts, gsl_multifit_function_fdf * fdf,
|
|
Packit |
67cb25 |
gsl_vector * x, gsl_vector * f, gsl_vector * dx, int scale)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
lmder_state_t *state = (lmder_state_t *) vstate;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix *r = state->r;
|
|
Packit |
67cb25 |
gsl_vector *tau = state->tau;
|
|
Packit |
67cb25 |
gsl_vector *qtf = state->qtf;
|
|
Packit |
67cb25 |
gsl_vector *diag = state->diag;
|
|
Packit |
67cb25 |
gsl_vector *work1 = state->work1;
|
|
Packit |
67cb25 |
gsl_permutation *perm = state->perm;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int signum;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* start counting function and Jacobian evaluations */
|
|
Packit |
67cb25 |
fdf->nevalf = 0;
|
|
Packit |
67cb25 |
fdf->nevaldf = 0;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* return immediately if evaluation raised error */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int status;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Evaluate function at x */
|
|
Packit |
67cb25 |
status = gsl_multifit_eval_wf (fdf, x, swts, f);
|
|
Packit |
67cb25 |
if (status)
|
|
Packit |
67cb25 |
return status;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Evaluate Jacobian at x and store in state->r */
|
|
Packit |
67cb25 |
if (fdf->df)
|
|
Packit |
67cb25 |
status = gsl_multifit_eval_wdf (fdf, x, swts, r);
|
|
Packit |
67cb25 |
else /* finite difference approximation */
|
|
Packit |
67cb25 |
status = gsl_multifit_fdfsolver_dif_df(x, swts, fdf, f, r);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_memcpy(state->J, r);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (status)
|
|
Packit |
67cb25 |
return status;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
state->par = 0;
|
|
Packit |
67cb25 |
state->iter = 1;
|
|
Packit |
67cb25 |
state->fnorm = enorm (f);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set_all (dx, 0.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* store column norms in diag */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (scale)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
compute_diag (r, diag);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_vector_set_all (diag, 1.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* set delta to 100 |D x| or to 100 if |D x| is zero */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
state->xnorm = scaled_enorm (diag, x);
|
|
Packit |
67cb25 |
state->delta = compute_delta (diag, x);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Factorize J = Q R P^T */
|
|
Packit |
67cb25 |
gsl_linalg_QRPT_decomp (r, tau, perm, &signum, work1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* compute qtf = Q^T f */
|
|
Packit |
67cb25 |
gsl_vector_memcpy (qtf, f);
|
|
Packit |
67cb25 |
gsl_linalg_QR_QTvec (r, tau, qtf);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set_zero (state->rptdx);
|
|
Packit |
67cb25 |
gsl_vector_set_zero (state->w);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Zero the trial vector, as in the alloc function */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set_zero (state->f_trial);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#ifdef DEBUG
|
|
Packit |
67cb25 |
printf("r = "); gsl_matrix_fprintf(stdout, r, "%g");
|
|
Packit |
67cb25 |
printf("perm = "); gsl_permutation_fprintf(stdout, perm, "%d");
|
|
Packit |
67cb25 |
printf("tau = "); gsl_vector_fprintf(stdout, tau, "%g");
|
|
Packit |
67cb25 |
#endif
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|