ReFRACtor
nlls_solver_gsl_sm.cc
Go to the documentation of this file.
1 #include <gsl/gsl_blas.h>
2 #include <fp_gsl_matrix.h>
3 #include <gsl_sm_lsp.h>
4 #include <nlls_solver_gsl_sm.h>
5 
6 
7 using namespace FullPhysics;
8 using namespace blitz;
9 
10 
11 void print_state( uint32_t iter, gsl_multifit_nlinear_workspace* s, int status )
12 {
13  double c = gsl_blas_dnrm2( gsl_multifit_nlinear_residual(s) );
14  printf( "Solver '%s/%s'; iter = %3u; (|f(x)|^2)/2 = %g; status = %s\n",
15  gsl_multifit_nlinear_name(s), gsl_multifit_nlinear_trs_name(s),
16  iter, c*c/2.0, gsl_strerror(status) );
17 
18  printf( "Where x is\n" );
19  (void) gsl_vector_fprintf(stdout, gsl_multifit_nlinear_position(s), "%25.14lf");
20 
21 // printf( "The gradient g(x) is\n");
22 // (void) gsl_vector_fprintf(stdout, s->g, "%25.14lf");
23 
24  printf( "\n" );
25 }
26 
27 
29 {
30  // Selecting a problem
31  gsl_multifit_nlinear_fdf f = gsl_sm_get_lsp_fdf(&(*P));
32 
33  // select the solver
34  const gsl_multifit_nlinear_type * T = get_gsl_multifit_nlinear_solver();
35 
36  // for gsl status
37  int gsl_status = GSL_FAILURE;
38  int gsl_status_conv = GSL_CONTINUE;
39 
40  gsl_multifit_nlinear_workspace *s = gsl_multifit_nlinear_alloc(T, &FDF_params, f.n, f.p);
41 
42  blitz::Array<double, 1> X(P->parameters());
43 
44  uint32_t num_step = 0;
45  stat = UNTRIED;
46  if( s )
47  if( !(gsl_status = gsl_multifit_nlinear_init(GslVector(X).gsl(), &f, s)) ) {
48  stat = CONTINUE;
49  do {
50  num_step++;
51 
52  // The following three lines are only for recording purpose.
53  // Info at the initial guess (the starting point) is also
54  // recorded here.
55  //
56  record_cost_at_accepted_point(P->cost());
57  record_accepted_point(P->parameters());
58  record_gradient_at_accepted_point(P->gradient());
59 
60  // A return status of GSL_ENOPROG by the following function
61  // does not suggest convergence, and it only means that the
62  // function call did not encounter an error. However, a
63  // return status of GSL_ENOPROG means that the function call
64  // did not make any progress. Stalling can happen at a true
65  // minimum or some other reason.
66  //
67  gsl_status = gsl_multifit_nlinear_iterate(s);
68  if( (gsl_status != GSL_SUCCESS) && (gsl_status != GSL_ENOPROG) ) {
69  stat = ERROR;
70  break;
71  }
72 
73  // The gradient check performed by the following GSL provided
74  // function is a scaled gradient check. First the gradient
75  // is scaled such that it is unitless, and then the convergence
76  // check is performed. Scaling the gradient for convergence
77  // check helps to avoid some problems, but it results in other
78  // problem.
79  //
80  int info=0;
81  gsl_status_conv = gsl_multifit_nlinear_test(X_tol, G_tol, F_tol, &info, s);
82 
83  // This code segment is a temporary fix. The above GSL
84  // provided convergence test routine does not work correctly
85  // when the value of the cost function is very large.
86  // This code segment (if statement) is written such that it
87  // can be deleted without causing error or requiring any
88  // change to the rest of the code. The effect of the code
89  // segment is that both the scaled gradient test (above) and
90  // the unscaled gradient test (below) should satisfy the
91  // gradient-based convergence tests in order to assume
92  // convergence based on gradient test.
93  //
94  if(info == 2) {
95  if(sum(abs(P->gradient())) > G_tol) {
96  gsl_status_conv = GSL_CONTINUE;
97  info = 0;
98  }
99  }
100 
101  if( (info == 1) || (info == 2) ) {
102  stat = SUCCESS;
103  break;
104  }
105 
106  if(gsl_status == GSL_ENOPROG) {
107  stat = STALLED;
108  break;
109  }
110 
111  if( verbose ) print_state(num_step, s, gsl_status_conv);
112  } while ( (gsl_status_conv == GSL_CONTINUE)
113  && (P->num_cost_evaluations() < max_cost_f_calls)
114  && (P->message() == NLLSProblem::NONE) );
115  }
116 
117  // The following three lines are only for recording purpose.
118  //
119  record_cost_at_accepted_point(P->cost());
120  record_accepted_point(P->parameters());
121  record_gradient_at_accepted_point(P->gradient());
122 
123  if( verbose && (stat != CONTINUE) )
124  print_state( num_step, s, ((stat == ERROR)?gsl_status:gsl_status_conv) );
125 
126  if( s ) gsl_multifit_nlinear_free(s);
127 }
const Unit s("s", 1.0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
virtual void solve()
The method that solves the optimization problem.
gsl_multifit_nlinear_fdf gsl_sm_get_lsp_fdf(const FullPhysics::NLLSProblem *lsp)
Definition: gsl_sm_lsp.cc:29
void print_state(uint32_t iter, gsl_multifit_nlinear_workspace *s, int status)
Apply value function to a blitz array.
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
This provides thin wrapper around the GNU Scientific Library gsl_vector.
Definition: fp_gsl_matrix.h:96
There are no messages.
Definition: cost_func.h:39

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