19 double, std::string>())
46 sigma_ap, gamma, gamma_last_step_, gamma_initial,
47 residual_, se, k, kt_se_m1_k, dx, fstat));
58 x_i.reference(S.
x_i().copy());
59 x_a.reference(S.
x_a().copy());
62 sigma_ap.reference(S.
sigma_ap().copy());
66 residual_.reference(S.
residual().copy());
67 se.reference(S.
se().copy());
68 k.reference(S.
k().copy());
70 dx.reference(S.
dx().copy());
87 <<
"# apriori_cov_scaled\n" 88 << apriori_cov_scaled <<
"\n\n" 90 << sa_m1_scaled <<
"\n\n" 95 <<
"# gamma_last_step\n" 96 << gamma_last_step_ <<
"\n\n" 98 << gamma_initial <<
"\n\n" 100 << residual_ <<
"\n\n" 106 << kt_se_m1_k <<
"\n\n" 122 >> apriori_cov_scaled
151 const blitz::Array<double, 1>& Apriori,
152 const blitz::Array<double, 2>& Apriori_cov)
155 using namespace blitz;
156 firstIndex i1; secondIndex i2;
159 if(Initial_guess.rows() != Apriori.rows())
160 throw Exception(
"Intitial guess and Apriori must be the same size");
161 if(Apriori.rows() != Apriori_cov.rows() ||
162 Apriori.rows() != Apriori_cov.cols())
163 throw Exception(
"Apriori and Apriori_cov must be the same size");
167 x_i.reference(Initial_guess.copy());
168 x_a.reference(Apriori.copy());
169 sigma_ap.resize(Apriori_cov.rows());
170 sigma_ap = sqrt(Apriori_cov(i1, i1));
171 gamma = gamma_initial;
173 apriori_cov_scaled.resize(Apriori_cov.shape());
174 apriori_cov_scaled = Apriori_cov(i1, i2) / (sigma_ap(i1) * sigma_ap(i2));
178 bool has_converged =
false;
179 convergence_check()->initialize_check();
182 Array<double, 1> x_i_last, se_last, residual_last;
183 Array<double, 2> k_last;
186 while(!has_converged) {
188 cost_function()->cost_function(x_i, residual_, se, k);
190 if(first && save_test_data_ !=
"") {
191 std::ofstream save(save_test_data_.c_str());
198 bool step_diverged, convergence_failed;
199 gamma_last_step_ = gamma;
200 convergence_check()->convergence_check(fstat_last, fstat,
203 gamma, step_diverged);
204 if(convergence_failed) {
206 fstat.fit_succeeded =
false;
207 notify_update_do(*
this);
213 x_i.resize(x_i_last.shape());
214 se.resize(se_last.shape());
215 residual_.resize(residual_last.shape());
216 k.resize(k_last.shape());
217 x_i = x_i_last; se = se_last, residual_ = residual_last, k = k_last;
219 fstat.number_iteration -= 1;
220 fstat.number_divergent += 1;
223 x_i_last.resize(x_i.shape());
224 se_last.resize(se.shape());
225 residual_last.resize(residual_.shape());
226 k_last.resize(k.shape());
227 x_i_last = x_i; se_last = se; residual_last = residual_; k_last = k;
232 notify_update_do(*
this);
234 fstat.fit_succeeded =
true;
235 convergence_check()->evaluate_quality(fstat, residual_, se);
245 blitz::Array<double, 1>& Dx,
246 blitz::Array<double, 2>& Kt_se_m1_k)
248 firstIndex i1; secondIndex i2; thirdIndex i3; fourthIndex i4;
254 Kt_se_m1_k.reference(kt_se_m1_k);
296 using namespace blitz;
297 firstIndex i1; secondIndex i2; thirdIndex i3;
304 kt_se_m1_k.resize(k.cols(), k.cols());
305 kt_se_m1_k = sum(k(i3,i1) / se(i3) * k(i3, i2), i3);
315 Array<double, 1> zero_unused_parm_v = zero_unused_parm();
321 Array<double, 2> lhs(sigma_ap.rows(), sigma_ap.rows());
322 Array<double, 1> rhs(lhs.rows());
323 sa_m1_scaled.resize(apriori_cov_scaled.shape());
324 Array<bool, 1> zero_unused_flag(zero_unused_parm_v.shape());
325 zero_unused_flag = (zero_unused_parm_v < 1e-8);
327 lhs = ( ((1 + gamma) * sa_m1_scaled(i1, i2) +
328 sigma_ap(i1) * kt_se_m1_k(i1, i2) * sigma_ap(i2)) *
329 zero_unused_parm_v(i1) * zero_unused_parm_v(i2));
337 rhs = sigma_ap(i1) * sum(k(i2, i1) * (-residual_(i2)) / se(i2),i2) +
338 sum(sa_m1_scaled(i1, i2) * (x_a(i2) - x_i(i2)) / sigma_ap(i2), i2);
344 dx.resize(lhs.cols());
346 dx = sigma_ap * dxscale;
352 fstat.d_sigma_sq = sum(dxscale * rhs);
356 int d_sigma_sq_numrow = count(max(abs(kt_se_m1_k), i2) > 1e-20);
357 fstat.d_sigma_sq_scaled = fstat.d_sigma_sq / d_sigma_sq_numrow;
358 fstat.chisq_apriori = sum(((x_a - x_i) / sigma_ap(i1) *
359 sum(sa_m1_scaled(i1, i2) *
360 (x_a(i2) - x_i(i2)) / sigma_ap(i2), i2))
361 * zero_unused_parm_v(i1));
362 fstat.chisq_measured = sum(residual_ * residual_ / se);
369 Array<double, 1> residual_fc = residual_.copy();
370 residual_fc += sum(k(i1, i2) * dx(i2), i2);
371 Array<double, 1> x_i_fc = x_i.copy();
374 fstat.chisq_apriori_fc = sum(((x_a - x_i_fc) / sigma_ap(i1) *
375 sum(sa_m1_scaled(i1, i2) *
376 (x_a(i2) - x_i_fc(i2)) / sigma_ap(i2), i2))
377 * zero_unused_parm_v(i1));
378 fstat.chisq_measured_fc = sum(residual_fc * residual_fc / se);
388 firstIndex i1; secondIndex i2;
389 Array<double, 2> t(sa_m1_scaled.shape());
390 Array<double, 1> zero_unused_parm_v = zero_unused_parm();
391 Array<bool, 1> zero_unused_flag(zero_unused_parm_v.shape());
392 zero_unused_flag = (zero_unused_parm_v < 1e-8);
393 t = sa_m1_scaled + sigma_ap(i1) * kt_se_m1_k * sigma_ap(i2);
394 Array<double, 2> res(t.shape());
405 firstIndex i1; secondIndex i2;
406 Array<double, 2> ascale(aposteriori_covariance_scaled());
407 Array<double, 2> res(ascale.shape());
408 res = ascale * sigma_ap(i1) * sigma_ap(i2);
420 Array<double, 1> res(x_i * zero_unused_parm());
430 firstIndex i1; secondIndex i2; thirdIndex i3;
431 Array<double, 2> res(sa_m1_scaled.shape());
433 res = zero_unused_parm()(i1) * sigma_ap(i1) *
434 sum(aposteriori_covariance_scaled()(i1, i3) *
435 sigma_ap(i3) * kt_se_m1_k(i3, i2), i3) * zero_unused_parm()(i2);
446 blitz::Array<double, 2> cov = aposteriori_covariance();
447 blitz::Array<double, 1> res(cov.rows());
448 Array<double, 1> zero_unused_parm_v = zero_unused_parm();
449 for(
int i = 0; i < res.rows(); ++i)
453 res(i) = sqrt(cov(i, i)) * zero_unused_parm_v(i);
465 firstIndex i1; secondIndex i2; thirdIndex i3;
466 Array<double, 1> res(sigma_ap.rows());
467 res = where(max(abs(kt_se_m1_k), i2) <= 1e-20, 0, 1);
477 firstIndex i1; secondIndex i2; thirdIndex i3;
478 Array<double, 2> res(apriori_cov_scaled.shape());
479 res = apriori_cov_scaled * sigma_ap(i1) * sigma_ap(i2);
blitz::Array< double, 1 > zero_unused_parm() const
Array that is 0 where we are not using a parameter, and 1 elsewhere.
const blitz::Array< double, 1 > & x_i() const
const blitz::Array< double, 2 > & kt_se_m1_k() const
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.
virtual bool solve(const blitz::Array< double, 1 > &Initial_guess, const blitz::Array< double, 1 > &Apriori, const blitz::Array< double, 2 > &Apriori_cov)
This solves the least squares problem starting at the initial guess.
boost::shared_ptr< ConnorSolverState > state() const
Save state to a ConnorSolverState object.
const blitz::Array< double, 1 > & sigma_ap() const
const FitStatistic & fstat() const
const blitz::Array< double, 2 > & k() const
Class that saves the state of a ConnorSolver.
const blitz::Array< double, 1 > & residual() const
This is the base of the exception hierarchy for Full Physics code.
void test_do_inversion(const std::string &Fname, blitz::Array< double, 1 > &Dx, blitz::Array< double, 2 > &Kt_se_m1_k)
Restore state previously saved, and run do_inversion.
blitz::Array< double, 1 > x_solution_zero_unused() const
Return the solution to the last problem solved.
#define REGISTER_LUA_CLASS(X)
Apply value function to a blitz array.
virtual blitz::Array< double, 2 > aposteriori_covariance() const
Return a posteriori covariance matrix for last problem solved.
const blitz::Array< double, 2 > & apriori_cov_scaled() const
const blitz::Array< double, 1 > & dx() const
blitz::Array< double, 2 > apriori_covariance() const
Apriori covariance matrix.
double gamma_last_step() const
blitz::Array< double, 2 > generalized_inverse(const blitz::Array< double, 2 > &A, double Rcond=std::numeric_limits< double >::epsilon())
This returns the generalized inverse of the given matrix.
It can be convenient to allow comments in a text data file that are ignored by the program reading it...
void to_stream(std::ostream &os) const
Save state of object.
blitz::Array< double, 1 > x_solution_uncertainty() const
Return the uncertainty of x_solution, this is just the sqrt of the diagonal of the full aposteriori_c...
virtual blitz::Array< double, 2 > aposteriori_covariance_scaled() const
Return a scaled a posteriori covariance matrix for last problem solved.
double gamma_initial() const
const blitz::Array< double, 1 > & x_a() const
void from_stream(std::istream &is)
Restore state of object previous saved with "to_stream".
Contains classes to abstract away details in various Spurr Radiative Transfer software.
#define REGISTER_LUA_END()
static double rcond
Factor to determine if we treat a singular factor as 0.
virtual blitz::Array< double, 2 > averaging_kernel() const
Return averaging kernel for last problem solved.
int number_iteration
Number of iterations.
const blitz::Array< double, 2 > & sa_m1_scaled() const
void do_inversion()
This does an inversion step.
const blitz::Array< double, 1 > & se() const