11 #ifndef OOPS_ASSIMILATION_DRPFOMMINIMIZER_H_
12 #define OOPS_ASSIMILATION_DRPFOMMINIMIZER_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"
74 const std::string
classname()
const override {
return "DRPFOMMinimizer";}
80 const double,
const double,
const int,
const double)
override;
94 template<
typename MODEL,
typename OBS>
98 hvecs_(), vvecs_(), zvecs_(), alphas_(), betas_() {}
102 template<
typename MODEL,
typename OBS>
105 const double costJ0Jb,
const double costJ0JoJc,
106 const int maxiter,
const double tolerance) {
115 std::vector<double> ss;
116 std::vector<double> dd;
117 std::vector< std::vector<double> > Hess;
118 std::vector< std::vector<double> > UpHess;
121 const double costJ0 = costJ0Jb + costJ0JoJc;
135 double beta = sqrt(dot_product(zz, vv));
136 const double beta0 = beta;
153 Hess.resize(maxiter);
154 for (
int ii = 0; ii <= maxiter-1; ii++) {
155 Hess[ii].resize(maxiter + 1);
156 for (
int jj = 0; jj <= maxiter; jj++) {
161 double normReduction = 1.0;
163 Log::info() << std::endl;
164 for (
int jiter = 0; jiter < maxiter; ++jiter) {
165 Log::info() <<
"DRPFOM Starting Iteration " << jiter+1 << std::endl;
171 for (
int jj = 0; jj <= jiter; ++jj) {
172 Hess[jiter][jj] = dot_product(zvecs_[jj], vv);
173 vv.
axpy(-Hess[jiter][jj], vvecs_[jj]);
182 beta = sqrt(dot_product(zz, vv));
184 Hess[jiter][jiter+1] = beta;
201 ss.push_back(beta0/Hess[0][0]);
205 dd.push_back(beta0*dot_product(zvecs_[0], vv));
207 UpHess.resize(jiter+1);
208 for (
int ii = 0; ii <= jiter; ii++) {
209 UpHess[ii].resize(jiter+1);
210 for (
int jj = 0; jj <= jiter; jj++) {
211 UpHess[ii][jj] = Hess[ii][jj];
217 betas_.push_back(beta);
222 double costJ = costJ0;
223 double costJb = costJ0Jb;
224 for (
int jj = 0; jj < jiter+1; ++jj) {
225 costJ -= 0.5 * ss[jj] * dot_product(zvecs_[jj], rr);
226 costJb += 0.5 * ss[jj] * dot_product(vvecs_[jj], zvecs_[jj]) * ss[jj];
228 double costJoJc = costJ - costJb;
231 double rznorm = beta*std::abs(ss[jiter]);
232 normReduction = rznorm/beta0;
234 Log::info() <<
"DRPFOM end of iteration " << jiter+1 << std::endl
235 <<
" Norm reduction (" << std::setw(2) << jiter+1 <<
") = "
236 << util::full_precision(normReduction) << std::endl
237 <<
" Quadratic cost function: J (" << std::setw(2) << jiter+1 <<
") = "
238 << util::full_precision(costJ) << std::endl
239 <<
" Quadratic cost function: Jb (" << std::setw(2) << jiter+1 <<
") = "
240 << util::full_precision(costJb) << std::endl
241 <<
" Quadratic cost function: JoJc(" << std::setw(2) << jiter+1 <<
") = "
242 << util::full_precision(costJoJc) << std::endl << std::endl;
244 if (normReduction < tolerance) {
245 Log::info() <<
"DRPFOM: Achieved required reduction in residual norm." << std::endl;
251 for (
unsigned int jj = 0; jj < ss.size(); ++jj) {
252 dx.
axpy(ss[jj], zvecs_[jj]);
253 dxh.
axpy(ss[jj], hvecs_[jj]);
256 return normReduction;
263 #endif // OOPS_ASSIMILATION_DRPFOMMINIMIZER_H_