11 #ifndef OOPS_ASSIMILATION_PLANCZOS_H_
12 #define OOPS_ASSIMILATION_PLANCZOS_H_
18 #include "oops/util/dot_product.h"
19 #include "oops/util/formats.h"
20 #include "oops/util/Logger.h"
61 template <
typename VECTOR,
typename AMATRIX,
typename PMATRIX>
62 double PLanczos(VECTOR & xx,
const VECTOR & bb,
63 const AMATRIX & A,
const PMATRIX & precond,
64 const int maxiter,
const double tolerance) {
68 std::vector<VECTOR> vVEC;
69 std::vector<VECTOR> zVEC;
71 vVEC.reserve(maxiter+1);
72 zVEC.reserve(maxiter+1);
74 Log::debug() <<
"PLanczos xx = " << xx << std::endl;
75 Log::debug() <<
"PLanczos bb = " << bb << std::endl;
77 std::vector<double> alphas;
78 std::vector<double> betas;
79 std::vector<double> dd;
80 std::vector<double> yy;
84 double xnrm2 = dot_product(xx, xx);
89 Log::debug() <<
"PLanczos rr = " << rr << std::endl;
92 precond.multiply(rr, zz);
93 Log::debug() <<
"PLanczos zz = " << zz << std::endl;
95 double normReduction = 1.0;
96 double beta0 = sqrt(dot_product(rr, zz));
98 Log::debug() <<
"PLanczos beta0 = " << beta0 << std::endl;
107 Log::debug() <<
"PLanczos vv = " << vv << std::endl;
108 Log::debug() <<
"PLanczos zz = " << zz << std::endl;
111 Log::info() << std::endl;
112 while (jiter < maxiter) {
113 Log::info() <<
" PLanczos Starting Iteration " << jiter+1 << std::endl;
117 Log::debug() <<
"PLanczos ww = " << ww << std::endl;
118 if (jiter > 0) ww.axpy(-beta, vVEC[jiter-1]);
120 double alpha = dot_product(zz, ww);
121 Log::debug() <<
"PLanczos alpha = " << alpha << std::endl;
124 Log::debug() <<
"PLanczos ww = " << ww << std::endl;
127 for (
int iiter = 0; iiter < jiter; ++iiter) {
128 double proj = dot_product(ww, zVEC[iiter]);
129 ww.axpy(-proj, vVEC[iiter]);
131 Log::debug() <<
"PLanczos ww = " << ww << std::endl;
133 precond.multiply(ww, zz);
134 Log::debug() <<
"PLanczos zz = " << zz << std::endl;
136 beta = sqrt(dot_product(zz, ww));
137 Log::debug() <<
"PLanczos beta = " << beta << std::endl;
142 Log::debug() <<
"PLanczos vv = " << vv << std::endl;
143 Log::debug() <<
"PLanczos zz = " << zz << std::endl;
148 alphas.push_back(alpha);
151 yy.push_back(beta0/alpha);
155 dd.push_back(beta0*dot_product(zVEC[0], vv));
160 double rznorm = beta*std::abs(yy[jiter]);
161 Log::debug() <<
"PLanczos rznorm = " << rznorm << std::endl;
163 normReduction = rznorm/beta0;
165 betas.push_back(beta);
167 Log::info() <<
"PLanczos end of iteration " << jiter+1 <<
". Norm reduction= "
168 << util::full_precision(normReduction) << std::endl << std::endl;
172 if (normReduction < tolerance) {
173 Log::info() <<
"PLanczos: Achieved required reduction in residual norm." << std::endl;
177 Log::debug() <<
"PLanczos jiter = " << jiter << std::endl;
180 for (
int iiter = 0; iiter < jiter; ++iiter) {
181 xx.axpy(yy[iiter], zVEC[iiter]);
184 Log::info() <<
"PLanczos: end" << std::endl;
186 return normReduction;
191 #endif // OOPS_ASSIMILATION_PLANCZOS_H_