ROL
ROL_lSR1.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 // Drew Kouri (dpkouri@sandia.gov) and
39 // Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 #ifndef ROL_LSR1_H
45 #define ROL_LSR1_H
46 
51 #include "ROL_Secant.hpp"
52 #include "ROL_Types.hpp"
53 
54 namespace ROL {
55 
56 template<class Real>
57 class lSR1 : public Secant<Real> {
58 private:
59 
60  mutable bool updateIterate_;
62 
63 public:
64  lSR1(int M) : Secant<Real>(M), isInitialized_(false) {
65  updateIterate_ = true;
66  }
67 
68  // Update Secant Approximation
69  void updateStorage( const Vector<Real> &x, const Vector<Real> &grad,
70  const Vector<Real> &gp, const Vector<Real> &s,
71  const Real snorm, const int iter ) {
72  Real one(1);
73  // Get Generic Secant State
74  ROL::Ptr<SecantState<Real> >& state = Secant<Real>::get_state();
75  if ( !isInitialized_ ) {
76  state->iterate = x.clone();
77  isInitialized_ = true;
78  }
79 
80  state->iterate->set(x);
81  state->iter = iter;
82  ROL::Ptr<Vector<Real> > gradDiff = grad.clone();
83  gradDiff->set(grad);
84  gradDiff->axpy(-one,gp);
85 
86  Real sy = s.dot(gradDiff->dual());
87  if (updateIterate_ || state->current == -1) {
88  if (state->current < state->storage-1) {
89  state->current++; // Increment Storage
90  }
91  else {
92  state->iterDiff.erase(state->iterDiff.begin()); // Remove first element of s list
93  state->gradDiff.erase(state->gradDiff.begin()); // Remove first element of y list
94  state->product.erase(state->product.begin()); // Remove first element of rho list
95  }
96  state->iterDiff.push_back(s.clone());
97  state->iterDiff[state->current]->set(s); // s=x_{k+1}-x_k
98  state->gradDiff.push_back(grad.clone());
99  state->gradDiff[state->current]->set(*gradDiff); // y=g_{k+1}-g_k
100  state->product.push_back(sy); // ys=1/rho
101  }
102  updateIterate_ = true;
103  }
104 
105  // Apply Initial Secant Approximate Inverse Hessian
106  virtual void applyH0( Vector<Real> &Hv, const Vector<Real> &v ) const {
107  Hv.set(v.dual());
108  }
109 
110  // Apply lSR1 Approximate Inverse Hessian
111  void applyH( Vector<Real> &Hv, const Vector<Real> &v ) const {
112  // Get Generic Secant State
113  const ROL::Ptr<SecantState<Real> >& state = Secant<Real>::get_state();
114 
115  // Apply initial Hessian approximation to v
116  applyH0(Hv,v);
117 
118  std::vector<ROL::Ptr<Vector<Real> > > a(state->current+1);
119  std::vector<ROL::Ptr<Vector<Real> > > b(state->current+1);
120  Real byi(0), byj(0), bv(0), normbi(0), normyi(0), one(1);
121  for (int i = 0; i <= state->current; i++) {
122  // Compute Hy
123  a[i] = Hv.clone();
124  applyH0(*(a[i]),*(state->gradDiff[i]));
125  for (int j = 0; j < i; j++) {
126  byj = b[j]->dot((state->gradDiff[j])->dual());
127  byi = b[j]->dot((state->gradDiff[i])->dual());
128  a[i]->axpy(byi/byj,*(b[j]));
129  }
130  // Compute s - Hy
131  b[i] = Hv.clone();
132  b[i]->set(*(state->iterDiff[i]));
133  b[i]->axpy(-one,*(a[i]));
134 
135  // Compute Hv
136  byi = b[i]->dot((state->gradDiff[i])->dual());
137  normbi = b[i]->norm();
138  normyi = (state->gradDiff[i])->norm();
139  if ( i == state->current && std::abs(byi) < sqrt(ROL_EPSILON<Real>())*normbi*normyi ) {
140  updateIterate_ = false;
141  }
142  else {
143  updateIterate_ = true;
144  bv = b[i]->dot(v.dual());
145  Hv.axpy(bv/byi,*(b[i]));
146  }
147  }
148  }
149 
150  // Apply Initial Secant Approximate Hessian
151  virtual void applyB0( Vector<Real> &Bv, const Vector<Real> &v ) const {
152  Bv.set(v.dual());
153  }
154 
155  // Apply lSR1 Approximate Hessian
156  void applyB( Vector<Real> &Bv, const Vector<Real> &v ) const {
157  // Get Generic Secant State
158  const ROL::Ptr<SecantState<Real> >& state = Secant<Real>::get_state();
159 
160  // Apply initial Hessian approximation to v
161  applyB0(Bv,v);
162 
163  std::vector<ROL::Ptr<Vector<Real> > > a(state->current+1);
164  std::vector<ROL::Ptr<Vector<Real> > > b(state->current+1);
165  Real bsi(0), bsj(0), bv(0), normbi(0), normsi(0), one(1);
166  for (int i = 0; i <= state->current; i++) {
167  // Compute Hy
168  a[i] = Bv.clone();
169  applyB0(*(a[i]),*(state->iterDiff[i]));
170  for (int j = 0; j < i; j++) {
171  bsj = (state->iterDiff[j])->dot(b[j]->dual());
172  bsi = (state->iterDiff[i])->dot(b[j]->dual());
173  a[i]->axpy(bsi/bsj,*(b[j]));
174  }
175  // Compute s - Hy
176  b[i] = Bv.clone();
177  b[i]->set(*(state->gradDiff[i]));
178  b[i]->axpy(-one,*(a[i]));
179 
180  // Compute Hv
181  bsi = (state->iterDiff[i])->dot(b[i]->dual());
182  normbi = b[i]->norm();
183  normsi = (state->iterDiff[i])->norm();
184  if ( i == state->current && std::abs(bsi) < sqrt(ROL_EPSILON<Real>())*normbi*normsi ) {
185  updateIterate_ = false;
186  }
187  else {
188  updateIterate_ = true;
189  bv = b[i]->dot(v.dual());
190  Bv.axpy(bv/bsi,*(b[i]));
191  }
192  }
193  }
194 };
195 
196 }
197 
198 #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:226
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void applyB0(Vector< Real > &Bv, const Vector< Real > &v) const
Definition: ROL_lSR1.hpp:151
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:153
void applyB(Vector< Real > &Bv, const Vector< Real > &v) const
Definition: ROL_lSR1.hpp:156
void applyH(Vector< Real > &Hv, const Vector< Real > &v) const
Definition: ROL_lSR1.hpp:111
Contains definitions of custom data types in ROL.
Provides definitions for limited-memory SR1 operators.
Definition: ROL_lSR1.hpp:57
virtual void applyH0(Vector< Real > &Hv, const Vector< Real > &v) const
Definition: ROL_lSR1.hpp:106
bool isInitialized_
Definition: ROL_lSR1.hpp:61
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
virtual Real dot(const Vector &x) const =0
Compute where .
lSR1(int M)
Definition: ROL_lSR1.hpp:64
ROL::Ptr< SecantState< Real > > & get_state()
Definition: ROL_Secant.hpp:88
Provides interface for and implements limited-memory secant operators.
Definition: ROL_Secant.hpp:70
bool updateIterate_
Definition: ROL_lSR1.hpp:60
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:209
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_lSR1.hpp:69