11 #ifndef OOPS_ASSIMILATION_RPLANCZOSMINIMIZER_H_
12 #define OOPS_ASSIMILATION_RPLANCZOSMINIMIZER_H_
24 #include "oops/util/dot_product.h"
25 #include "oops/util/formats.h"
26 #include "oops/util/Logger.h"
75 const std::string
classname()
const override {
return "RPLanczosMinimizer";}
82 const int &,
const double &,
Dual_ &,
const double &)
override;
87 template<
typename MODEL,
typename OBS>
90 const int & maxiter,
const double & tolerance,
91 Dual_ & dy,
const double & sigma) {
108 std::vector<Dual_> vVEC;
109 std::vector<Dual_> tVEC;
110 std::vector<Dual_> zVEC;
112 vVEC.reserve(maxiter+1);
113 tVEC.reserve(maxiter+1);
114 zVEC.reserve(maxiter+1);
116 std::vector<double> vpVEC;
117 std::vector<double> tpVEC;
118 std::vector<double> zpVEC;
119 std::vector<double> alphas;
120 std::vector<double> betas;
121 std::vector<double> y;
122 std::vector<double> d;
131 ttp = dot_product(dy, zz) + sigma*zzp;
133 double normReduction = 1.0;
134 double beta0 = sqrt(dot_product(rr, tt) + rrp*ttp);
161 zpVEC.push_back(zzp);
162 tpVEC.push_back(ttp);
165 Log::info() << std::endl;
166 while (jiter < maxiter) {
167 Log::info() <<
"RPLanczos Starting Iteration " << jiter+1 << std::endl;
173 ww.
axpy(-beta, vold);
176 double alpha = dot_product(tt, ww) + ttp*wwp;
182 for (
int iiter = 0; iiter < jiter; ++iiter) {
183 double proj = dot_product(ww, tVEC[iiter]) + wwp * tpVEC[iiter];
184 ww.
axpy(-proj, vVEC[iiter]);
185 wwp -= proj * vpVEC[iiter];
195 ttp = dot_product(dy, zz) + sigma*zzp;
197 beta = sqrt(dot_product(tt, ww) + ttp*wwp);
214 zpVEC.push_back(zzp);
215 tpVEC.push_back(ttp);
217 alphas.push_back(alpha);
221 y.push_back(beta0/alpha);
225 for (
int iiter = 0; iiter <= jiter; ++iiter) {
226 d.push_back(beta0*(dot_product(tVEC[0], vVEC[iiter]) + tpVEC[0]*vpVEC[iiter]));
232 double rznorm = beta*std::abs(y[jiter]);
234 normReduction = rznorm/beta0;
236 betas.push_back(beta);
238 Log::info() <<
"RPLanczos end of iteration " << jiter+1 <<
". Norm reduction= "
239 << util::full_precision(normReduction) << std::endl << std::endl;
243 if (normReduction < tolerance) {
244 Log::info() <<
"RPLanczos: Achieved required reduction in residual norm." << std::endl;
250 for (
int iiter = 0; iiter < jiter; ++iiter) {
251 vv.
axpy(y[iiter], zVEC[iiter]);
252 vvp += y[iiter]*zpVEC[iiter];
255 Log::info() <<
"RPLanczos: end" << std::endl;
257 return normReduction;
264 #endif // OOPS_ASSIMILATION_RPLANCZOSMINIMIZER_H_