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_Types.hpp"
52 
53 namespace ROL {
54 
55 template<class Real>
56 class lSR1 : public Secant<Real> {
57 private:
58 
60 
61 public:
62  lSR1(int M) : Secant<Real>(M) {
63  updateIterate_ = true;
64  }
65 
66  // Update Secant Approximation
67  void update( const Vector<Real> &grad, const Vector<Real> &gp, const Vector<Real> &s,
68  const Real snorm, const int iter ) {
69  // Get Generic Secant State
70  Teuchos::RCP<SecantState<Real> >& state = Secant<Real>::get_state();
71 
72  state->iter = iter;
73  Teuchos::RCP<Vector<Real> > gradDiff = grad.clone();
74  gradDiff->set(grad);
75  gradDiff->axpy(-1.0,gp);
76 
77  Real sy = s.dot(gradDiff->dual());
78  if (updateIterate_ || state->current == -1) {
79  if (state->current < state->storage-1) {
80  state->current++; // Increment Storage
81  }
82  else {
83  state->iterDiff.erase(state->iterDiff.begin()); // Remove first element of s list
84  state->gradDiff.erase(state->gradDiff.begin()); // Remove first element of y list
85  state->product.erase(state->product.begin()); // Remove first element of rho list
86  }
87  state->iterDiff.push_back(s.clone());
88  state->iterDiff[state->current]->set(s); // s=x_{k+1}-x_k
89  state->gradDiff.push_back(grad.clone());
90  state->gradDiff[state->current]->set(*gradDiff); // y=g_{k+1}-g_k
91  state->product.push_back(sy); // ys=1/rho
92  }
93  updateIterate_ = true;
94  }
95 
96  // Apply Initial Secant Approximate Inverse Hessian
97  virtual void applyH0( Vector<Real> &Hv, const Vector<Real> &v, const Vector<Real> &x ) {
98  Hv.set(v.dual());
99  }
100 
101 
102  // Apply lSR1 Approximate Inverse Hessian
103  void applyH( Vector<Real> &Hv, const Vector<Real> &v, const Vector<Real> &x ) {
104  // Get Generic Secant State
105  Teuchos::RCP<SecantState<Real> >& state = Secant<Real>::get_state();
106 
107  // Apply initial Hessian approximation to v
108  applyH0(Hv,v,x);
109 
110  std::vector<Teuchos::RCP<Vector<Real> > > a(state->current+1);
111  std::vector<Teuchos::RCP<Vector<Real> > > b(state->current+1);
112  Real byi = 0.0, byj = 0.0, bv = 0.0, normbi = 0.0, normyi = 0.0;
113  for (int i = 0; i <= state->current; i++) {
114  // Compute Hy
115  a[i] = Hv.clone();
116  applyH0(*(a[i]),*(state->gradDiff[i]),x);
117  for (int j = 0; j < i; j++) {
118  byj = b[j]->dot((state->gradDiff[j])->dual());
119  byi = b[j]->dot((state->gradDiff[i])->dual());
120  a[i]->axpy(byi/byj,*(b[j]));
121  }
122  // Compute s - Hy
123  b[i] = Hv.clone();
124  b[i]->set(*(state->iterDiff[i]));
125  b[i]->axpy(-1.0,*(a[i]));
126 
127  // Compute Hv
128  byi = b[i]->dot((state->gradDiff[i])->dual());
129  normbi = b[i]->norm();
130  normyi = (state->gradDiff[i])->norm();
131  if ( i == state->current && std::abs(byi) < sqrt(ROL_EPSILON)*normbi*normyi ) {
132  updateIterate_ = false;
133  }
134  else {
135  updateIterate_ = true;
136  bv = b[i]->dot(v.dual());
137  Hv.axpy(bv/byi,*(b[i]));
138  }
139  }
140  }
141 
142  // Apply Initial Secant Approximate Hessian
143  virtual void applyB0( Vector<Real> &Bv, const Vector<Real> &v, const Vector<Real> &x ) {
144  Bv.set(v.dual());
145  }
146 
147 
148  // Apply lSR1 Approximate Hessian
149  void applyB( Vector<Real> &Bv, const Vector<Real> &v, const Vector<Real> &x ) {
150  // Get Generic Secant State
151  Teuchos::RCP<SecantState<Real> >& state = Secant<Real>::get_state();
152 
153  // Apply initial Hessian approximation to v
154  applyB0(Bv,v,x);
155 
156  std::vector<Teuchos::RCP<Vector<Real> > > a(state->current+1);
157  std::vector<Teuchos::RCP<Vector<Real> > > b(state->current+1);
158  Real bsi = 0.0, bsj = 0.0, bv = 0.0, normbi = 0.0, normsi = 0.0;
159  for (int i = 0; i <= state->current; i++) {
160  // Compute Hy
161  a[i] = Bv.clone();
162  applyB0(*(a[i]),*(state->iterDiff[i]),x);
163  for (int j = 0; j < i; j++) {
164  bsj = (state->iterDiff[j])->dot(b[j]->dual());
165  bsi = (state->iterDiff[i])->dot(b[j]->dual());
166  a[i]->axpy(bsi/bsj,*(b[j]));
167  }
168  // Compute s - Hy
169  b[i] = Bv.clone();
170  b[i]->set(*(state->gradDiff[i]));
171  b[i]->axpy(-1.0,*(a[i]));
172 
173  // Compute Hv
174  bsi = (state->iterDiff[i])->dot(b[i]->dual());
175  normbi = b[i]->norm();
176  normsi = (state->iterDiff[i])->norm();
177  if ( i == state->current && std::abs(bsi) < sqrt(ROL_EPSILON)*normbi*normsi ) {
178  updateIterate_ = false;
179  }
180  else {
181  updateIterate_ = true;
182  bv = b[i]->dot(v.dual());
183  Bv.axpy(bv/bsi,*(b[i]));
184  }
185  }
186  }
187 
188 };
189 
190 }
191 
192 #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:211
virtual void applyH0(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &x)
Definition: ROL_lSR1.hpp:97
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:141
Contains definitions of custom data types in ROL.
Provides definitions for limited-memory SR1 operators.
Definition: ROL_lSR1.hpp:56
void update(const Vector< Real > &grad, const Vector< Real > &gp, const Vector< Real > &s, const Real snorm, const int iter)
Definition: ROL_lSR1.hpp:67
virtual Teuchos::RCP< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:72
void applyB(Vector< Real > &Bv, const Vector< Real > &v, const Vector< Real > &x)
Definition: ROL_lSR1.hpp:149
virtual Real dot(const Vector &x) const =0
Compute where .
lSR1(int M)
Definition: ROL_lSR1.hpp:62
Provides interface for and implements limited-memory secant operators.
Definition: ROL_Secant.hpp:67
bool updateIterate_
Definition: ROL_lSR1.hpp:59
Teuchos::RCP< SecantState< Real > > & get_state()
Definition: ROL_Secant.hpp:84
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:194
virtual void applyB0(Vector< Real > &Bv, const Vector< Real > &v, const Vector< Real > &x)
Definition: ROL_lSR1.hpp:143
void applyH(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &x)
Definition: ROL_lSR1.hpp:103
static const double ROL_EPSILON
Platform-dependent machine epsilon.
Definition: ROL_Types.hpp:115