11 #ifndef OOPS_ASSIMILATION_DRPLANCZOSMINIMIZER_H_ 12 #define OOPS_ASSIMILATION_DRPLANCZOSMINIMIZER_H_ 18 #include <boost/ptr_container/ptr_vector.hpp> 27 #include "oops/util/dot_product.h" 28 #include "oops/util/formats.h" 29 #include "oops/util/Logger.h" 80 const std::string
classname()
const override {
return "DRPLanczosMinimizer";}
86 const double,
const double,
const int,
const double)
override;
99 template<
typename MODEL>
103 hvecs_(), vvecs_(), zvecs_(), alphas_(), betas_() {}
107 template<
typename MODEL>
110 const double costJ0Jb,
const double costJ0JoJc,
111 const int maxiter,
const double tolerance) {
120 std::vector<double> ss;
121 std::vector<double> dd;
124 const double costJ0 = costJ0Jb + costJ0JoJc;
126 lmp_.update(vvecs_, hvecs_, zvecs_, alphas_, betas_);
129 lmp_.multiply(vv,
pr);
133 double beta = sqrt(dot_product(zz, vv));
134 const double beta0 =
beta;
150 double normReduction = 1.0;
153 for (
int jiter = 0; jiter < maxiter; ++jiter) {
154 Log::info() <<
"DRPLanczos Starting Iteration " << jiter+1 << std::endl;
159 if (jiter > 0) vv.
axpy(-
beta, vvecs_[jiter-1]);
162 double alpha = dot_product(zz, vv);
168 for (
int jj = 0; jj < jiter; ++jj) {
169 double proj = dot_product(vv, zvecs_[jj]);
170 vv.
axpy(-proj, vvecs_[jj]);
174 lmp_.multiply(vv,
pr);
178 beta = sqrt(dot_product(zz, vv));
194 alphas_.push_back(
alpha);
197 ss.push_back(beta0/
alpha);
201 dd.push_back(beta0*dot_product(zvecs_[0], vv));
205 betas_.push_back(
beta);
210 double costJ = costJ0;
211 double costJb = costJ0Jb;
212 for (
int jj = 0; jj < jiter+1; ++jj) {
213 costJ -= 0.5 * ss[jj] * dot_product(zvecs_[jj], rr);
214 costJb += 0.5 * ss[jj] * dot_product(vvecs_[jj], zvecs_[jj]) * ss[jj];
216 double costJoJc = costJ - costJb;
219 double rznorm =
beta*std::abs(ss[jiter]);
220 normReduction = rznorm/beta0;
222 Log::info() <<
"DRPLanczos end of iteration " << jiter+1 << std::endl
223 <<
" Norm reduction (" << std::setw(2) << jiter+1 <<
") = " 224 << util::full_precision(normReduction) << std::endl
225 <<
" Quadratic cost function: J (" << std::setw(2) << jiter+1 <<
") = " 226 << util::full_precision(costJ) << std::endl
227 <<
" Quadratic cost function: Jb (" << std::setw(2) << jiter+1 <<
") = " 228 << util::full_precision(costJb) << std::endl
229 <<
" Quadratic cost function: JoJc(" << std::setw(2) << jiter+1 <<
") = " 230 << util::full_precision(costJoJc) << std::endl << std::endl;
233 Log::info() <<
"DRPLanczos: Achieved required reduction in residual norm." << std::endl;
239 for (
unsigned int jj = 0; jj < ss.size(); ++jj) {
240 dx.
axpy(ss[jj], zvecs_[jj]);
241 dxh.
axpy(ss[jj], hvecs_[jj]);
244 return normReduction;
251 #endif // OOPS_ASSIMILATION_DRPLANCZOSMINIMIZER_H_
const std::string classname() const override
real(double_kind), dimension(numint), parameter pr
boost::ptr_vector< CtrlInc_ > vvecs_
CostFunction< MODEL > CostFct_
std::vector< double > betas_
boost::ptr_vector< CtrlInc_ > hvecs_
DRPLanczosMinimizer(const eckit::Configuration &, const CostFct_ &)
void TriDiagSolve(const std::vector< double > &diag, const std::vector< double > &sub, const std::vector< double > &rhs, std::vector< double > &sol)
std::vector< double > alphas_
The solvers represent matrices as objects that implement a "multiply" method.
The namespace for the main oops code.
void multiply(const CtrlInc_ &dx, CtrlInc_ &dz) const
boost::ptr_vector< CtrlInc_ > zvecs_
subroutine, public info(self)
SpectralLMP< CtrlInc_ > lmp_
real(fp), parameter, public tolerance
double solve(CtrlInc_ &, CtrlInc_ &, CtrlInc_ &, const Bmat_ &, const HtRinvH_ &, const double, const double, const int, const double) override
ControlIncrement< MODEL > CtrlInc_
HtRinvHMatrix< MODEL > HtRinvH_
DR (Derber and Rosati) Minimizers.
void axpy(const double, const ControlIncrement &)
void multiply(const CtrlInc_ &x, CtrlInc_ &bx) const