ReFRACtor
cost_minimizer_gsl.cc
Go to the documentation of this file.
1 #include <fp_gsl_matrix.h>
2 #include <fp_exception.h>
3 #include <gsl_mdm.h>
4 #include <cost_minimizer_gsl.h>
5 #include<cmath>
6 
7 
8 using namespace FullPhysics;
9 using namespace blitz;
10 
11 
12 
13 
15  const boost::shared_ptr<CostFunc>& cost, int max_cost_function_calls,
16  double size_tol, const Array<double,1>& init_step_size, bool vrbs)
17 {
18  return boost::shared_ptr<IterativeSolver>(new CostMinimizerGSL( cost, max_cost_function_calls, size_tol, init_step_size, vrbs ));
19 }
20 
21 #ifdef HAVE_LUA
22 #include "register_lua.h"
24 .def(luabind::constructor< const boost::shared_ptr<CostFunc>&, int, double, const Array<double,1>&, bool >())
25 .def(luabind::constructor< const boost::shared_ptr<CostFunc>&, int, double, const Array<double,1>& >())
26 .def(luabind::constructor< const boost::shared_ptr<CostFunc>&, int, double >())
27 .def(luabind::constructor< const boost::shared_ptr<CostFunc>&, int >())
28 .scope
29 [
31 ]
33 #endif
34 
35 
36 
37 
38 void print_state( unsigned int iter, gsl_multimin_fminimizer * s, int status)
39 {
40  printf( "Solver '%s'; iter = %3u; c(x) = %g; gsl status = %s\n",
41  gsl_multimin_fminimizer_name(s), iter,
42  gsl_multimin_fminimizer_minimum(s), gsl_strerror((int)status) );
43 
44  printf( "Where x is\n" );
45  (void) gsl_vector_fprintf(stdout, gsl_multimin_fminimizer_x(s), "%25.14lf");
46 
47  printf( "Average distance from the simplex center to its vertices = %25.10lf\n",
48  gsl_multimin_fminimizer_size(s) );
49 
50  printf( "\n" );
51 }
52 
53 
54 
56  int max_cost_function_calls, double size_tol,
57  const Array<double,1>& init_step_size,
58  bool vrbs)
59  : CostMinimizer(p, max_cost_function_calls, vrbs),
60  Size_tol(size_tol), Initial_step_size(init_step_size)
61 {
62  if( (init_step_size.size() > 0) && (init_step_size.size() != p->expected_parameter_size())) {
63  Exception e;
64  e << "If initial-step-size provided, its size must be equal to the expected-parameter-size:\n"
65  << " Initial-step-size: " << init_step_size.size() << "\n"
66  << " Expected-parameter-size: " << p->expected_parameter_size() << "\n";
67  throw e;
68  }
69 }
70 
71 
73 {
74  // Selecting a problem
75  gsl_multimin_function f = gsl_get_mdm(&(*P));
76 
77  // select the solver
78  const gsl_multimin_fminimizer_type * T = get_gsl_multimin_fminimizer();
79 
80  // for gsl status
81  int gsl_status = GSL_FAILURE;
82  int gsl_status_s = GSL_CONTINUE;
83 
84  gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, f.n);
85 
86  blitz::Array<double, 1> X(P->parameters());
87 
88  gsl_vector *ss = gsl_vector_alloc(f.n);
89  bool ss_initialized = false;
90  //
91  if( ss ) {
92  // Choosing a good initial step-size is in itself a
93  // research topic.
94 
95  if(Initial_step_size.size() > 0) {
96  ss_initialized = (gsl_vector_memcpy(ss, GslVector(Initial_step_size).gsl()) == GSL_SUCCESS);
97  } else {
98 
99  // Here is a simple choice.
100  //
101  gsl_vector_set_all(ss, 1.0);
102 
103  // Another common choice.
104  //
105 // for( size_t i=0; i<f.n; i++ )
106 // gsl_vector_set( ss, i, (X(i)==0.0)?0.00025:0.05 );
107 
108  ss_initialized = true;
109  }
110  }
111 
112  int num_step = 0;
113  stat = UNTRIED;
114  if( s && ss_initialized )
115  if( !(gsl_status = gsl_multimin_fminimizer_set(s, &f, GslVector(X).gsl(), ss)) ) {
116  stat = CONTINUE;
117  do {
118  num_step++;
119 
120  // The following two lines are only for recording purpose.
121  // They record info at the initial guess (the starting point).
122  //
124  record_accepted_point(P->parameters());
125 
126  // A return status of GSL_ENOPROG by the following function
127  // does not suggest convergence, and it only means that the
128  // function call did not encounter an error. However, a
129  // return status of GSL_ENOPROG means that the function call
130  // did not make any progress. Stalling can happen at a true
131  // minimum or some other reason.
132  //
133  gsl_status = gsl_multimin_fminimizer_iterate(s);
134  if( (gsl_status != GSL_SUCCESS) && (gsl_status != GSL_ENOPROG) ) {
135  stat = ERROR;
136  break;
137  }
138 
139  gsl_status_s = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), Size_tol);
140  if(gsl_status_s == GSL_SUCCESS) {
141  stat = SUCCESS;
142  break;
143  }
144 
145  if(gsl_status == GSL_ENOPROG) {
146  stat = STALLED;
147  break;
148  }
149 
150  if( verbose ) print_state(num_step, s, gsl_status_s);
151  } while (gsl_status_s == GSL_CONTINUE && P->num_cost_evaluations() < max_cost_f_calls);
152  }
153 
154  // The following two lines are only for recording purpose.
155  //
157  record_accepted_point(P->parameters());
158 
159  if( verbose && (stat != CONTINUE) )
160  print_state( num_step, s, ((stat == ERROR)?gsl_status:gsl_status_s) );
161 
162  if( ss ) gsl_vector_free(ss);
163  if( s ) gsl_multimin_fminimizer_name(s);
164 }
solve method called but an error was encountered
const Unit s("s", 1.0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
void record_cost_at_accepted_point(double cost)
Called to record the cost function value at an accepted point.
solve method called and a solution found
blitz::Array< double, 1 > Initial_step_size
solve method was called but stalled
virtual void solve()
The method that solves the optimization problem.
CostMinimizerGSL(const boost::shared_ptr< CostFunc > &p, int max_cost_function_calls, double size_tol=0.001, const blitz::Array< double, 1 > &init_step_size=blitz::Array< double, 1 >(), bool vrbs=false)
Initializes the minimizer.
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
The base class for all iterative cost minimizers that do not require derivatives of any order...
#define REGISTER_LUA_DERIVED_CLASS(X, Y)
Definition: register_lua.h:136
gsl_multimin_function gsl_get_mdm(const FullPhysics::CostFunc *cost)
Definition: gsl_mdm.cc:21
Apply value function to a blitz array.
virtual const gsl_multimin_fminimizer_type * get_gsl_multimin_fminimizer()
solve method called but did not converge to a solution
solve method not called yet
void record_accepted_point(const blitz::Array< double, 1 > &point)
Called to record an accepted point.
boost::shared_ptr< IterativeSolver > cost_minimizer_gsl_create(const boost::shared_ptr< CostFunc > &cost, int max_cost_function_calls, double size_tol, const Array< double, 1 > &init_step_size, bool vrbs)
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.
boost::shared_ptr< CostFunc > P
This provides thin wrapper around the GNU Scientific Library gsl_vector.
Definition: fp_gsl_matrix.h:96
void print_state(unsigned int iter, gsl_multimin_fminimizer *s, int status)

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