ROL
ROL_Secant.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef ROL_SECANT_H
11 #define ROL_SECANT_H
12 
17 #include "ROL_ParameterList.hpp"
18 #include "ROL_LinearOperator.hpp"
19 #include "ROL_Types.hpp"
20 
21 namespace ROL {
22 
27 };
28 
29 template<class Real>
30 struct SecantState {
31  Ptr<Vector<Real>> iterate;
32  std::vector<Ptr<Vector<Real>>> iterDiff; // Step Storage
33  std::vector<Ptr<Vector<Real>>> gradDiff; // Gradient Storage
34  std::vector<Real> product; // Step-Gradient Inner Product Storage
35  std::vector<Real> product2; // Step-Gradient Inner Product Storage
36  int storage; // Storage Size
37  int current; // Current Storage Size
38  int iter; // Current Optimization Iteration
39  ESecantMode mode; // Intended application mode
40 
41  SecantState(int M, ESecantMode sm) : storage(M), current(-1), iter(0), mode(sm) {}
42 };
43 
44 template<class Real>
45 class Secant : public LinearOperator<Real> {
46 protected:
47 
48  const Ptr<SecantState<Real>> state_; // Secant State
49  Ptr<Vector<Real>> y_;
51  Real Bscaling_;
52 
53 private:
54 
56 
57 public:
58 
59  virtual ~Secant() {}
60 
61  // Constructor
62  Secant( int M = 10, bool useDefaultScaling = true, Real Bscaling = Real(1), ESecantMode mode = SECANTMODE_BOTH )
63  : state_(makePtr<SecantState<Real>>(M,mode)),
64  useDefaultScaling_(useDefaultScaling), Bscaling_(Bscaling),
65  isInitialized_(false) {}
66 
67  Ptr<SecantState<Real>>& get_state() { return state_; }
68  const Ptr<SecantState<Real>>& get_state() const { return state_; }
69 
70  // Update Secant Approximation
71  virtual void updateStorage( const Vector<Real> &x, const Vector<Real> &grad,
72  const Vector<Real> &gp, const Vector<Real> &s,
73  const Real snorm, const int iter ) {
74  const Real one(1);
75  if ( !isInitialized_ ) {
76  state_->iterate = x.clone();
77  y_ = grad.clone();
78  isInitialized_ = true;
79  }
80  state_->iterate->set(x);
81  state_->iter = iter;
82  y_->set(grad);
83  y_->axpy(-one,gp);
84 
85  //Real sy = s.dot(y_->dual());
86  Real sy = s.apply(*y_);
87  if (sy > ROL_EPSILON<Real>()*snorm*snorm) {
88  if (state_->current < state_->storage-1) {
89  state_->current++; // Increment Storage
90  state_->iterDiff.push_back(s.clone()); // Create new memory
91  state_->gradDiff.push_back(grad.clone()); // Create new memory
92  }
93  else {
94  state_->iterDiff.push_back(state_->iterDiff[0]); // Move first element to the last
95  state_->gradDiff.push_back(state_->gradDiff[0]); // Move first element to the last
96  state_->iterDiff.erase(state_->iterDiff.begin()); // Remove first element of s list
97  state_->gradDiff.erase(state_->gradDiff.begin()); // Remove first element of y list
98  state_->product.erase(state_->product.begin()); // Remove first element of rho list
99  }
100  state_->iterDiff[state_->current]->set(s); // s=x_{k+1}-x_k
101  state_->gradDiff[state_->current]->set(*y_); // y=g_{k+1}-g_k
102  state_->product.push_back(sy); // ys=1/rho
103  }
104  }
105 
106  // Apply Secant Approximate Inverse Hessian
107  virtual void applyH( Vector<Real> &Hv, const Vector<Real> &v ) const = 0;
108 
109  // Apply Initial Secant Approximate Inverse Hessian
110  virtual void applyH0( Vector<Real> &Hv, const Vector<Real> &v ) const {
111  Hv.set(v.dual());
112  if (useDefaultScaling_) {
113  if (state_->iter != 0 && state_->current != -1) {
114  Real yy = state_->gradDiff[state_->current]->dot(*(state_->gradDiff[state_->current]));
115  Hv.scale(state_->product[state_->current]/yy);
116  }
117  }
118  else {
119  Hv.scale(static_cast<Real>(1)/Bscaling_);
120  }
121  }
122 
123  // Apply Secant Approximate Hessian
124  virtual void applyB( Vector<Real> &Bv, const Vector<Real> &v ) const = 0;
125 
126  // Apply Initial Secant Approximate Hessian
127  virtual void applyB0( Vector<Real> &Bv, const Vector<Real> &v ) const {
128  Bv.set(v.dual());
129  if (useDefaultScaling_) {
130  if (state_->iter != 0 && state_->current != -1) {
131  Real yy = state_->gradDiff[state_->current]->dot(*(state_->gradDiff[state_->current]));
132  Bv.scale(yy/state_->product[state_->current]);
133  }
134  }
135  else {
136  Bv.scale(Bscaling_);
137  }
138  }
139 
140  // Test Secant Approximations
141  void test(std::ostream &stream = std::cout ) const {
142  if (isInitialized_) {
143  Ptr<Vector<Real>> v = state_->iterate->clone();
144  Ptr<Vector<Real>> Hv = state_->iterate->clone();
145  Ptr<Vector<Real>> Bv = state_->iterate->dual().clone();
146  const Real one(1);
147 
148  // Print BHv -> Should be v
149  v->randomize(-one,one);
150  applyH(*Hv,*v);
151  applyB(*Bv,*Hv);
152  v->axpy(-one,*Bv);
153  stream << " ||BHv-v|| = " << v->norm() << std::endl;
154 
155  // Print HBv -> Should be v
156  v->randomize(-one,one);
157  applyB(*Bv,*v);
158  applyH(*Hv,*Bv);
159  v->axpy(-one,*Hv);
160  stream << " ||HBv-v|| = " << v->norm() << std::endl;
161  }
162  }
163 
164  void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
165  applyB(Hv,v);
166  }
167 
168  void applyInverse(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
169  applyH(Hv,v);
170  }
171 
172 };
173 
174 }
175 
176 #include "ROL_SecantFactory.hpp"
177 
178 #endif
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Definition: ROL_Vector.hpp:192
virtual void scale(const Real alpha)=0
Compute where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
Definition: ROL_Vector.hpp:204
SecantState(int M, ESecantMode sm)
Definition: ROL_Secant.hpp:41
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply linear operator.
Definition: ROL_Secant.hpp:164
Contains definitions of custom data types in ROL.
virtual void applyH(Vector< Real > &Hv, const Vector< Real > &v) const =0
bool useDefaultScaling_
Definition: ROL_Secant.hpp:50
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
bool isInitialized_
Definition: ROL_Secant.hpp:55
Ptr< Vector< Real > > iterate
Definition: ROL_Secant.hpp:31
Ptr< Vector< Real > > y_
Definition: ROL_Secant.hpp:49
std::vector< Ptr< Vector< Real > > > iterDiff
Definition: ROL_Secant.hpp:32
virtual void applyB0(Vector< Real > &Bv, const Vector< Real > &v) const
Definition: ROL_Secant.hpp:127
ESecantMode mode
Definition: ROL_Secant.hpp:39
ESecantMode
Definition: ROL_Secant.hpp:23
Provides interface for and implements limited-memory secant operators.
Definition: ROL_Secant.hpp:45
virtual void updateStorage(const Vector< Real > &x, const Vector< Real > &grad, const Vector< Real > &gp, const Vector< Real > &s, const Real snorm, const int iter)
Definition: ROL_Secant.hpp:71
std::vector< Real > product2
Definition: ROL_Secant.hpp:35
const Ptr< SecantState< Real > > & get_state() const
Definition: ROL_Secant.hpp:68
virtual void applyB(Vector< Real > &Bv, const Vector< Real > &v) const =0
Provides the interface to apply a linear operator.
const Ptr< SecantState< Real > > state_
Definition: ROL_Secant.hpp:48
virtual void applyH0(Vector< Real > &Hv, const Vector< Real > &v) const
Definition: ROL_Secant.hpp:110
virtual ~Secant()
Definition: ROL_Secant.hpp:59
std::vector< Ptr< Vector< Real > > > gradDiff
Definition: ROL_Secant.hpp:33
void applyInverse(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply inverse of linear operator.
Definition: ROL_Secant.hpp:168
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
Real Bscaling_
Definition: ROL_Secant.hpp:51
Ptr< SecantState< Real > > & get_state()
Definition: ROL_Secant.hpp:67
std::vector< Real > product
Definition: ROL_Secant.hpp:34
void test(std::ostream &stream=std::cout) const
Definition: ROL_Secant.hpp:141