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,
typename OBS>
103 hvecs_(), vvecs_(), zvecs_(), alphas_(), betas_() {}
107 template<
typename MODEL,
typename OBS>
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;
152 Log::info() << std::endl;
153 for (
int jiter = 0; jiter < maxiter; ++jiter) {
154 Log::info() <<
"DRPLanczos Starting Iteration " << jiter+1 << std::endl;
161 vv.
axpy(-beta, vvecs_[jiter-1]);
165 double alpha = dot_product(zz, vv);
168 vv.
axpy(-alpha, vvecs_[jiter]);
171 for (
int jj = 0; jj < jiter; ++jj) {
172 double proj = dot_product(vv, zvecs_[jj]);
173 vv.
axpy(-proj, vvecs_[jj]);
177 lmp_.multiply(vv, pr);
181 beta = sqrt(dot_product(zz, vv));
197 alphas_.push_back(alpha);
200 ss.push_back(beta0/alpha);
204 dd.push_back(beta0*dot_product(zvecs_[0], vv));
208 betas_.push_back(beta);
213 double costJ = costJ0;
215 double costJb = costJ0Jb;
216 for (
int jj = 0; jj < jiter+1; ++jj) {
217 costJ -= 0.5 * ss[jj] * dot_product(zvecs_[jj], rr);
218 costJb += 0.5 * ss[jj] * dot_product(vvecs_[jj], zvecs_[jj]) * ss[jj];
220 double costJoJc = costJ - costJb;
223 double rznorm = beta*std::abs(ss[jiter]);
224 normReduction = rznorm/beta0;
226 Log::info() <<
"DRPLanczos end of iteration " << jiter+1 << std::endl
227 <<
" Norm reduction (" << std::setw(2) << jiter+1 <<
") = "
228 << util::full_precision(normReduction) << std::endl
229 <<
" Quadratic cost function: J (" << std::setw(2) << jiter+1 <<
") = "
230 << util::full_precision(costJ) << std::endl
231 <<
" Quadratic cost function: Jb (" << std::setw(2) << jiter+1 <<
") = "
232 << util::full_precision(costJb) << std::endl
233 <<
" Quadratic cost function: JoJc(" << std::setw(2) << jiter+1 <<
") = "
234 << util::full_precision(costJoJc) << std::endl << std::endl;
236 if (normReduction < tolerance) {
237 Log::info() <<
"DRPLanczos: Achieved required reduction in residual norm." << std::endl;
246 for (
unsigned int jj = 0; jj < ss.size(); ++jj) {
247 dx.
axpy(ss[jj], zvecs_[jj]);
248 dxh.
axpy(ss[jj], hvecs_[jj]);
251 return normReduction;
258 #endif // OOPS_ASSIMILATION_DRPLANCZOSMINIMIZER_H_