ReFRACtor
nlls_solver_gsl.cc
Go to the documentation of this file.
1 #include <gsl/gsl_blas.h>
2 #include <fp_gsl_matrix.h>
3 #include <gsl_lsp.h>
4 #include <nlls_solver_gsl.h>
5 
6 using namespace FullPhysics;
7 using namespace blitz;
8 
9 
10 
12  const boost::shared_ptr<CostFunc>& NLLS,
13  int max_cost_function_calls,
14  double dx_tol_abs, double dx_tol_rel, double g_tol,
15  bool vrbs)
16 {
17  const boost::shared_ptr<NLLSProblem> nlls(boost::dynamic_pointer_cast<NLLSProblem>(NLLS));
18  return boost::shared_ptr<IterativeSolver>(new NLLSSolverGSL(nlls, max_cost_function_calls, dx_tol_abs, dx_tol_rel, g_tol, vrbs));
19 }
20 
21 #ifdef HAVE_LUA
22 #include "register_lua.h"
24 .scope
25 [
27 ]
29 #endif
30 
31 
32 
33 void print_state( unsigned int iter, gsl_multifit_fdfsolver * s, int status)
34 {
35  double c = gsl_blas_dnrm2( gsl_multifit_fdfsolver_residual(s) );
36  printf( "Solver '%s'; iter = %3u; (|f(x)|^2)/2 = %g; status = %s\n",
37  gsl_multifit_fdfsolver_name(s), iter, c*c/2.0, gsl_strerror(status) );
38 
39  printf( "Where x is\n" );
40  (void) gsl_vector_fprintf(stdout, gsl_multifit_fdfsolver_position(s), "%25.14lf");
41 
42 // printf( "The step dx is\n");
43 // (void) gsl_vector_fprintf(stdout, s->dx, "%25.14lf");
44 
45  printf( "The gradient g(x) is\n");
46  (void) gsl_vector_fprintf(stdout, s->g, "%25.14lf");
47 
48  printf( "\n" );
49 }
50 
51 
53 {
54  // Selecting a problem
55  gsl_multifit_function_fdf f = gsl_get_lsp_fdf(&(*P));
56 
57  // select the solver
58  const gsl_multifit_fdfsolver_type * T = get_gsl_multifit_fdfsolver();
59 
60  // for gsl status
61  int gsl_status = GSL_FAILURE;
62  int gsl_status_conv = GSL_CONTINUE;
63 
64  gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc (T, f.n, f.p);
65 
66  blitz::Array<double, 1> X(P->parameters());
67 
68  int num_step = 0;
69  stat = UNTRIED;
70  if( s )
71  if( !(gsl_status = gsl_multifit_fdfsolver_set(s, &f, GslVector(X).gsl())) ) {
72  stat = CONTINUE;
73  do {
74  num_step++;
75 
76  // The following three lines are only for recording purpose.
77  // Info at the initial guess (the starting point) is also
78  // recorded here.
79  //
80  record_cost_at_accepted_point(P->cost());
81  record_accepted_point(P->parameters());
82  record_gradient_at_accepted_point(P->gradient());
83 
84  // A return status of GSL_ENOPROG by the following function
85  // does not suggest convergence, and it only means that the
86  // function call did not encounter an error. However, a
87  // return status of GSL_ENOPROG means that the function call
88  // did not make any progress. Stalling can happen at a true
89  // minimum or some other reason.
90  //
91  gsl_status = gsl_multifit_fdfsolver_iterate(s);
92  if( (gsl_status != GSL_SUCCESS) && (gsl_status != GSL_ENOPROG) ) {
93  stat = ERROR;
94  break;
95  }
96 
97  // According to my test (02/11/2018), gsl_multifit_fdfsolver_test
98  // does not work correctly; however, it is necessary to call it
99  // to get the gradient calculated.
100  //
101  int info=0;
102  gsl_status_conv = gsl_multifit_fdfsolver_test(s, 1.0e-4, 1.0e-4, 1.0e-4, &info);
103  //
104  gsl_status_conv = gsl_multifit_test_delta(s->dx, s->x, Dx_tol_abs, Dx_tol_rel);
105  if( gsl_status_conv == GSL_CONTINUE )
106  gsl_status_conv = gsl_multifit_test_gradient(s->g, G_tol);
107 
108  if( gsl_status_conv == GSL_SUCCESS ) {
109  stat = SUCCESS;
110  break;
111  }
112 
113  if(gsl_status == GSL_ENOPROG) {
114  stat = STALLED;
115  break;
116  }
117 
118  if( verbose ) print_state(num_step, s, gsl_status_conv);
119 
120  } while (gsl_status_conv == GSL_CONTINUE && P->num_cost_evaluations() < max_cost_f_calls);
121  }
122 
123  // The following three lines are only for recording purpose.
124  //
125  record_cost_at_accepted_point(P->cost());
126  record_accepted_point(P->parameters());
127  record_gradient_at_accepted_point(P->gradient());
128 
129  if( verbose && (stat != CONTINUE) )
130  print_state( num_step, s, ((stat == ERROR)?gsl_status:gsl_status_conv) );
131 
132  if( s ) gsl_multifit_fdfsolver_free(s);
133 }
const Unit s("s", 1.0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
void print_state(unsigned int iter, gsl_multifit_fdfsolver *s, int status)
#define REGISTER_LUA_DERIVED_CLASS(X, Y)
Definition: register_lua.h:136
Apply value function to a blitz array.
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
#define REGISTER_LUA_END()
Definition: register_lua.h:134
def(luabind::constructor< int >()) .def("rows"
The base class for all iterative optimizers.
gsl_multifit_function_fdf gsl_get_lsp_fdf(const FullPhysics::NLLSProblem *lsp_standard)
Definition: gsl_lsp.cc:39
This provides thin wrapper around the GNU Scientific Library gsl_vector.
Definition: fp_gsl_matrix.h:96
virtual void solve()
The method that solves the optimization problem.
boost::shared_ptr< IterativeSolver > nlls_solver_gsl_create(const boost::shared_ptr< CostFunc > &NLLS, int max_cost_function_calls, double dx_tol_abs, double dx_tol_rel, double g_tol, bool vrbs)

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:10