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>
98 hvecs_(), vvecs_(), zvecs_(), alphas_(), betas_() {}
102 template<
typename MODEL>
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;
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;
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_
boost::ptr_vector< CtrlInc_ > vvecs_
const std::string classname() const override
ControlIncrement< MODEL > CtrlInc_
real(double_kind), dimension(numint), parameter pr
double solve(CtrlInc_ &, CtrlInc_ &, CtrlInc_ &, const Bmat_ &, const HtRinvH_ &, const double, const double, const int, const double) override
std::vector< double > betas_
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
void UpHessSolve(std::vector< std::vector< double > > &UpHess, const std::vector< double > &rhs, std::vector< double > &sol)
boost::ptr_vector< CtrlInc_ > zvecs_
subroutine, public info(self)
real(fp), parameter, public tolerance
std::vector< double > alphas_
HtRinvHMatrix< MODEL > HtRinvH_
SpectralLMP< CtrlInc_ > lmp_
boost::ptr_vector< CtrlInc_ > hvecs_
DRPFOMMinimizer(const eckit::Configuration &, const CostFct_ &)
DR (Derber and Rosati) Minimizers.
void axpy(const double, const ControlIncrement &)
void multiply(const CtrlInc_ &x, CtrlInc_ &bx) const
CostFunction< MODEL > CostFct_