ReFRACtor
connor_solver_map.cc
Go to the documentation of this file.
1 #include <connor_solver_map.h>
2 #include <linear_algebra.h>
3 #include <fp_exception.h>
4 #include <logger.h>
5 #include <ifstream_cs.h>
6 #include <fstream>
7 
8 using namespace FullPhysics;
9 using namespace blitz;
10 
11 
13  const boost::shared_ptr<CostFunc>& NLLS_MAP,
14  const boost::shared_ptr<ConvergenceCheck>& Convergence_check,
15  int max_cost_function_calls,
16  double Gamma_initial)
17 {
18  const boost::shared_ptr<NLLSMaxAPosteriori> nlls_map(boost::dynamic_pointer_cast<NLLSMaxAPosteriori>(NLLS_MAP));
19  return boost::shared_ptr<IterativeSolver>(new ConnorSolverMAP(nlls_map, Convergence_check, max_cost_function_calls, Gamma_initial));
20 }
21 
22 #ifdef HAVE_LUA
23 #include "register_lua.h"
25 .scope
26 [
28 ]
30 #endif
31 
32 
33 
34 
35 
36 // Note that we have the various equations here in Latex. This is
37 // fairly unreadable as text comments, but if you view the doxgyen
38 // documentation created by this it gives a nicely formatted output.
39 
40 //-----------------------------------------------------------------------
43 //-----------------------------------------------------------------------
44 
45 double ConnorSolverMAP::rcond = 1e-12;
46 
47 
48 //-----------------------------------------------------------------------
54 //-----------------------------------------------------------------------
55 
57 
58 {
59  scaled_p = boost::shared_ptr<NLLSProblemScaled>(new NLLSProblemScaled(map->param_a_priori_uncertainty(), P));
60  scaled_p->parameters(scaled_p->scale_parameters(map->parameters()));
61 
62  firstIndex i1; secondIndex i2;
63 
64  gamma = gamma_initial;
65 
66 // Do Levenberg-Marquardt solution.
67 
68  stat = ERROR; // IterativeSolver status
69 
70  bool has_converged = false;
71  convergence_check()->initialize_check();
72  FitStatistic fstat_new;
73  FitStatistic fstat_last;
74  fstat = fstat_new;
75 
76  ModelState m_state_last;
77 
78  // The following three lines are only for recording purpose.
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  while(!has_converged) {
85  fstat.number_iteration += 1;
86  do_inversion();
87 
88  bool step_diverged, convergence_failed;
89  gamma_last_step_ = gamma;
90  convergence_check()->convergence_check(fstat_last, fstat,
91  has_converged,
92  convergence_failed,
93  gamma, step_diverged);
94  if(convergence_failed) { // Return failure to converge if check
95  // tells us to.
96  fstat.fit_succeeded = false;
97  stat = CONTINUE; // IterativeSolver status
98  return; // false;
99  }
100  if(step_diverged) {
101  // Redo last step, but with new gamma calculated by
102  // convergence_test
103  scaled_p->parameters(scaled_p->scale_parameters(m_state_last.parameters()));
104  map->set(m_state_last);
105  do_inversion();
106  fstat.number_iteration -= 1;
107  fstat.number_divergent += 1;
108  } else {
109  // Stash data, in case we need to backup the next step.
110  m_state_last.set(*map);
111  fstat_last = fstat;
112  }
113 
114  scaled_p->parameters(scaled_p->scale_parameters( Array<double, 1>(map->parameters()+dx) ));
115  if(!step_diverged) {
116  // The following three lines are only for recording purpose.
117  //
118  record_cost_at_accepted_point(P->cost());
119  record_accepted_point(P->parameters());
120  record_gradient_at_accepted_point(P->gradient());
121  }
122  }
123  stat = SUCCESS; // IterativeSolver status
124  fstat.fit_succeeded = true;
125  convergence_check()->evaluate_quality(fstat, map->model_measure_diff(), map->measurement_error_cov());
126  return; // true;
127 }
128 
129 
130 /****************************************************************/
167 {
168  using namespace blitz;
169  firstIndex i1; secondIndex i2; thirdIndex i3;
170 
171 //-----------------------------------------------------------------------
172 // Calculate the left hand side of the equation.
173 //-----------------------------------------------------------------------
174  Array<double,2> jac(scaled_p->jacobian());
175  Array<double,1> res(scaled_p->residual());
176  Array<double,2> lhs(jac.cols(),jac.cols());
177  Array<double,1> rhs(jac.cols());
178 // Array<double,2> Sa_chol_inv_scaled(map->param_a_priori_uncertainty()(i1)*map->a_priori_cov_chol_inv()(i1,i2));
179 // Array<double,2> lev_mar_term(sum(Sa_chol_inv_scaled(i3,i1) * Sa_chol_inv_scaled(i3, i2), i3) * gamma);
180  Array<double,2> Sa_chol_inv(map->a_priori_cov_chol_inv());
181  Array<double,2> Sa_inv(sum(Sa_chol_inv(i3,i1) * Sa_chol_inv(i3, i2), i3));
182  Array<double,2> lev_mar_term(map->param_a_priori_uncertainty()(i1)*Sa_inv(i1,i2)*map->param_a_priori_uncertainty()(i2) * gamma);
183  lhs = sum(jac(i3,i1) * jac(i3, i2), i3) + lev_mar_term;
184  rhs = -sum(jac(i2,i1) * res(i2), i2);
185 
186 //-----------------------------------------------------------------------
187 // Solve equation, and scale back to give the final answer.
188 //-----------------------------------------------------------------------
189 
190  dx.resize(lhs.cols());
191  Array<double, 1> dxscale = solve_least_squares(lhs, rhs, rcond);
192  dx = scaled_p->unscale_parameters(dxscale);
193 
194 //-----------------------------------------------------------------------
195 // Calculate the fit statistics.
196 //-----------------------------------------------------------------------
197 
198  Array<double,1> temp;
199 
200  fstat.d_sigma_sq = sum(dxscale * rhs);
201  //int d_sigma_sq_numrow = count(max(abs(jac), i2) > 1e-20); // I believe this is wrong
202  //int d_sigma_sq_numrow = count(FM->state_vector()->used_flag() == true); // should be for vanishing levels
203  int d_sigma_sq_numrow = jac.cols();
204  fstat.d_sigma_sq_scaled = fstat.d_sigma_sq / d_sigma_sq_numrow;
205  temp.reference(map->cov_weighted_parameter_a_priori_diff());
206  fstat.chisq_apriori = sum(temp*temp);
207  temp.reference(map->uncert_weighted_model_measure_diff());
208  fstat.chisq_measured = sum(temp*temp);
209 
210 //-----------------------------------------------------------------------
211 // Forecast what residual and state vector will be in next
212 // iteration, assuming cost function is fully linear.
213 //-----------------------------------------------------------------------
214 
215  Array<double, 1> residual_fc = map->model_measure_diff();
216  residual_fc += sum(map->jacobian()(i1, i2) * dx(i2), i2);
217  Array<double, 1> x_i_fc = map->parameters();
218  x_i_fc += dx;
219 
220  temp.resize(x_i_fc.rows());
221  temp = sum(map->a_priori_cov_chol_inv()(i1, i2) * Array<double,1>(x_i_fc-map->a_priori_params())(i2), i2);
222  fstat.chisq_apriori_fc = sum(temp*temp);
223  fstat.chisq_measured_fc = sum(residual_fc * residual_fc / map->measurement_error_cov());
224 }
virtual void parameters(const blitz::Array< double, 1 > &x)
Sets the problem at a new point in the parameter space.
blitz::Array< double, 1 > solve_least_squares(const blitz::Array< double, 2 > &A, const blitz::Array< double, 1 > &B, double Rcond=1e-12)
This solves the least squares system A*x = b, returning the minimum norm solution.
This class holds various parameters describing how good of a fit we have.
The state for a parametrized mathematical model (a vector function) and its Jacobian.
Definition: model_state.h:36
void do_inversion()
This does an inversion step.
#define REGISTER_LUA_DERIVED_CLASS(X, Y)
Definition: register_lua.h:136
void solve()
This solves the least squares problem starting at the initial guess.
Apply value function to a blitz array.
boost::shared_ptr< IterativeSolver > connor_solver_map_create(const boost::shared_ptr< CostFunc > &NLLS_MAP, const boost::shared_ptr< ConvergenceCheck > &Convergence_check, int max_cost_function_calls, double Gamma_initial)
static double rcond
Factor to determine if we treat a singular factor as 0.
bool fit_succeeded
Was the fit successful?
This solves a nonlinear least squares problem using Levenberg-Marquardt.
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.
virtual void set(const ModelState &s)
Makes self a copy of the input state.
Definition: model_state.cc:7

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