8 #ifndef OOPS_ASSIMILATION_MINIMIZERUTILS_H_
9 #define OOPS_ASSIMILATION_MINIMIZERUTILS_H_
14 #include "eckit/config/Configuration.h"
18 #include "oops/util/Logger.h"
28 const double & costJoJc);
32 template<
typename MODEL,
typename OBS>
37 if (config.has(
"online diagnostics")) {
38 const eckit::LocalConfiguration onlineDiag(config,
"online diagnostics");
39 bool writeinc = onlineDiag.getBool(
"write increment",
false);
43 Log::info() <<
"Write Increment - starting: " << loop << std::endl << std::endl;
45 const eckit::LocalConfiguration incConf(onlineDiag,
"increment");
51 Log::info() << std::endl <<
"Write Increment: done." << std::endl;
58 template<
typename MODEL,
typename OBS>
63 if (config.has(
"online diagnostics")) {
64 eckit::LocalConfiguration diagConf(config,
"online diagnostics");
65 bool writeinc = diagConf.getBool(
"write basis",
false);
69 Log::info() <<
"Write Krylov Basis: starting: " << loop << std::endl;
71 eckit::LocalConfiguration basisConf(diagConf,
"krylov basis");
72 basisConf.set(
"iteration", loop);
78 Log::info() <<
"Write Krylov Basis: done." << std::endl;
84 template<
typename MODEL,
typename OBS>
86 const std::vector<double> & diag,
87 const std::vector<double> & sub,
88 const std::vector<double> & rhs,
95 if (diagConf.has(
"online diagnostics")) {
96 int maxEigen = diagConf.getInt(
"online diagnostics.max eigenvectors", 0);
98 const double nn = rhs.size();
99 Eigen::MatrixXd TT = Eigen::MatrixXd::Zero(nn, nn);
101 for (
int ii = 0; ii < nn; ++ii) {
102 TT(ii, ii) = diag[ii];
103 if (ii > 0) TT(ii-1, ii) = sub[ii-1];
104 if (ii < nn - 1) TT(ii+1, ii) = sub[ii];
107 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> soluce(TT);
108 Eigen::MatrixXd eigenvecT = soluce.eigenvectors().real();
109 Eigen::VectorXd eigenvalT = soluce.eigenvalues().real();
112 for (
int ii = 0; ii < maxEigen && ii < nn; ++ii) {
115 for (
unsigned int jj = 0; jj < nn; ++jj) {
118 temp *= eigenvecT(jj, nn - 1 - ii);
122 temp *= eigenvecT(jj, nn - 1 - ii);
126 eckit::LocalConfiguration basisConf(diagConf,
"online diagnostics.eigenvector");
127 basisConf.set(
"iteration", ii);
128 eigenz.
write(basisConf);
135 eigenv *= eigenvalT(nn - 1 - ii);
137 Log::info() <<
"Eigenvalue " << ii+1 <<
" : " << eigenvalT(nn - 1 - ii) << std::endl;
138 Log::info() <<
"Norm A*y-lambda*y = " << dot_product(temp, temp) << std::endl;
140 Log::test() <<
"Eigenvalue " << ii+1 <<
" : " << eigenvalT(nn - 1 - ii) << std::endl;
141 Log::test() <<
"Norm eigenvector = " << dot_product(eigenz, eigenz) << std::endl;
void zero()
Linear algebra operators.
void write(const eckit::Configuration &) const
void multiply(const CtrlInc_ &dx, CtrlInc_ &dz) const
The namespace for the main oops code.
void writeKrylovBasis(const eckit::Configuration &config, const ControlIncrement< MODEL, OBS > &dx, const int &loop)
void printQuadraticCostFunction(int iteration, const double &costJ, const double &costJb, const double &costJoJc)
void writeIncrement(const eckit::Configuration &config, const ControlIncrement< MODEL, OBS > &dx, const int &loop)
void writeEigenvectors(const eckit::Configuration &diagConf, const std::vector< double > &diag, const std::vector< double > &sub, const std::vector< double > &rhs, std::vector< std::unique_ptr< ControlIncrement< MODEL, OBS >>> &zvecs, std::vector< std::unique_ptr< ControlIncrement< MODEL, OBS >>> &hvecs, const HtRinvHMatrix< MODEL, OBS > &HtRinvH, ControlIncrement< MODEL, OBS > &temp, ControlIncrement< MODEL, OBS > &eigenv, ControlIncrement< MODEL, OBS > &eigenz)
void printNormReduction(int iteration, const double &grad, const double &norm)