void solve_system(const gsl_vector *x0, gsl_multilarge_nlinear_fdf *fdf, gsl_multilarge_nlinear_parameters *params) { const gsl_multilarge_nlinear_type *T = gsl_multilarge_nlinear_trust; const size_t max_iter = 200; const double xtol = 1.0e-8; const double gtol = 1.0e-8; const double ftol = 1.0e-8; const size_t n = fdf->n; const size_t p = fdf->p; gsl_multilarge_nlinear_workspace *work = gsl_multilarge_nlinear_alloc(T, params, n, p); gsl_vector * f = gsl_multilarge_nlinear_residual(work); gsl_vector * x = gsl_multilarge_nlinear_position(work); int info; double chisq0, chisq, rcond, xsq; struct timeval tv0, tv1; gettimeofday(&tv0, NULL); /* initialize solver */ gsl_multilarge_nlinear_init(x0, fdf, work); /* store initial cost */ gsl_blas_ddot(f, f, &chisq0); /* iterate until convergence */ gsl_multilarge_nlinear_driver(max_iter, xtol, gtol, ftol, NULL, NULL, &info, work); gettimeofday(&tv1, NULL); /* store final cost */ gsl_blas_ddot(f, f, &chisq); /* compute final ||x||^2 */ gsl_blas_ddot(x, x, &xsq); /* store cond(J(x)) */ gsl_multilarge_nlinear_rcond(&rcond, work); /* print summary */ fprintf(stderr, "%-25s %-5zu %-4zu %-5zu %-6zu %-4zu %-10.4e %-10.4e %-7.2f %-11.4e %.2f\n", gsl_multilarge_nlinear_trs_name(work), gsl_multilarge_nlinear_niter(work), fdf->nevalf, fdf->nevaldfu, fdf->nevaldf2, fdf->nevalfvv, chisq0, chisq, 1.0 / rcond, xsq, (tv1.tv_sec - tv0.tv_sec) + 1.0e-6 * (tv1.tv_usec - tv0.tv_usec)); gsl_multilarge_nlinear_free(work); }
gsl_multilarge_nlinear_workspace * gsl_multilarge_nlinear_alloc (const gsl_multilarge_nlinear_type * T, const gsl_multilarge_nlinear_parameters * params, const size_t n, const size_t p) { gsl_multilarge_nlinear_workspace * w; if (n < p) { GSL_ERROR_VAL ("insufficient data points, n < p", GSL_EINVAL, 0); } w = calloc (1, sizeof (gsl_multilarge_nlinear_workspace)); if (w == 0) { GSL_ERROR_VAL ("failed to allocate space for multifit workspace", GSL_ENOMEM, 0); } w->n = n; w->p = p; w->type = T; w->fdf = NULL; w->niter = 0; w->params = *params; /* the cgst method uses its own built-in linear solver */ if (w->params.trs == gsl_multilarge_nlinear_trs_cgst) { w->params.solver = gsl_multilarge_nlinear_solver_none; } w->x = gsl_vector_calloc (p); if (w->x == 0) { gsl_multilarge_nlinear_free (w); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } w->f = gsl_vector_calloc (n); if (w->f == 0) { gsl_multilarge_nlinear_free (w); GSL_ERROR_VAL ("failed to allocate space for f", GSL_ENOMEM, 0); } w->dx = gsl_vector_calloc (p); if (w->dx == 0) { gsl_multilarge_nlinear_free (w); GSL_ERROR_VAL ("failed to allocate space for dx", GSL_ENOMEM, 0); } w->g = gsl_vector_alloc (p); if (w->g == 0) { gsl_multilarge_nlinear_free (w); GSL_ERROR_VAL ("failed to allocate space for g", GSL_ENOMEM, 0); } if (w->params.solver == gsl_multilarge_nlinear_solver_cholesky) { w->JTJ = gsl_matrix_alloc (p, p); if (w->JTJ == 0) { gsl_multilarge_nlinear_free (w); GSL_ERROR_VAL ("failed to allocate space for JTJ", GSL_ENOMEM, 0); } } w->sqrt_wts_work = gsl_vector_calloc (n); if (w->sqrt_wts_work == 0) { gsl_multilarge_nlinear_free (w); GSL_ERROR_VAL ("failed to allocate space for weights", GSL_ENOMEM, 0); } w->state = (T->alloc)(&(w->params), n, p); if (w->state == 0) { gsl_multilarge_nlinear_free (w); GSL_ERROR_VAL ("failed to allocate space for multifit state", GSL_ENOMEM, 0); } return w; }
static void test_fdf(const gsl_multilarge_nlinear_type * T, const gsl_multilarge_nlinear_parameters * params, const double xtol, const double gtol, const double ftol, const double epsrel, const double x0_scale, test_fdf_problem *problem, const double *wts) { gsl_multilarge_nlinear_fdf *fdf = problem->fdf; const size_t n = fdf->n; const size_t p = fdf->p; const size_t max_iter = 2500; gsl_vector *x0 = gsl_vector_alloc(p); gsl_vector_view x0v = gsl_vector_view_array(problem->x0, p); gsl_multilarge_nlinear_workspace *w = gsl_multilarge_nlinear_alloc (T, params, n, p); const char *pname = problem->name; char buf[2048]; char sname[2048]; int status, info; sprintf(buf, "%s/%s/solver=%s/scale=%s%s%s", gsl_multilarge_nlinear_name(w), params->trs->name, params->solver->name, params->scale->name, problem->fdf->df ? "" : "/fdjac", problem->fdf->fvv ? "" : "/fdfvv"); strcpy(sname, buf); /* scale starting point x0 */ gsl_vector_memcpy(x0, &x0v.vector); test_scale_x0(x0, x0_scale); if (wts) { gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n); gsl_multilarge_nlinear_winit(x0, &wv.vector, fdf, w); } else gsl_multilarge_nlinear_init(x0, fdf, w); status = gsl_multilarge_nlinear_driver(max_iter, xtol, gtol, ftol, NULL, NULL, &info, w); gsl_test(status, "%s/%s did not converge, status=%s", sname, pname, gsl_strerror(status)); /* check solution */ test_fdf_checksol(sname, pname, epsrel, w, problem); if (wts == NULL) { /* test again with weighting matrix W = I */ gsl_vector *wv = gsl_vector_alloc(n); sprintf(sname, "%s/weighted", buf); gsl_vector_memcpy(x0, &x0v.vector); test_scale_x0(x0, x0_scale); gsl_vector_set_all(wv, 1.0); gsl_multilarge_nlinear_winit(x0, wv, fdf, w); status = gsl_multilarge_nlinear_driver(max_iter, xtol, gtol, ftol, NULL, NULL, &info, w); gsl_test(status, "%s/%s did not converge, status=%s", sname, pname, gsl_strerror(status)); test_fdf_checksol(sname, pname, epsrel, w, problem); gsl_vector_free(wv); } gsl_multilarge_nlinear_free(w); gsl_vector_free(x0); }