ROL
Toggle main menu visibility
Loading...
Searching...
No Matches
src
step
secant
ROL_lSR1.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_LSR1_H
11
#define ROL_LSR1_H
12
16
17
#include "
ROL_Secant.hpp
"
18
#include "
ROL_Types.hpp
"
19
20
namespace
ROL
{
21
22
template
<
class
Real>
23
class
lSR1
:
public
Secant
<Real> {
24
private
:
25
26
//mutable bool updateIterate_;
27
bool
isInitialized_
;
28
mutable
bool
H0called_
,
B0called_
;
29
Ptr<Vector<Real>>
Bs_
,
Hy_
,
prim_
,
dual_
;
30
31
using
Secant
<Real>
::state_
;
32
using
Secant
<Real>
::y_
;
33
using
Secant
<Real>
::useDefaultScaling_
;
34
using
Secant
<Real>
::Bscaling_
;
35
36
public
:
37
lSR1
(
int
M,
bool
useDefaultScaling =
true
, Real Bscaling = Real(1),
ESecantMode
mode =
SECANTMODE_BOTH
)
38
:
Secant
<Real>(M,useDefaultScaling,Bscaling,mode),
isInitialized_
(false),
39
H0called_
(false),
B0called_
(false) {
40
if
(
useDefaultScaling_
)
Bscaling_
=
static_cast<
Real
>
(1);
41
//updateIterate_ = true;
42
}
43
44
// Update Secant Approximation
45
void
updateStorage
(
const
Vector<Real>
&x,
const
Vector<Real>
&grad,
46
const
Vector<Real>
&gp,
const
Vector<Real>
&s,
47
const
Real snorm,
const
int
iter ) {
48
const
Real one(1), tol(std::sqrt(
ROL_EPSILON<Real>
()));
49
if
( !
isInitialized_
) {
50
state_
->iterate = x.
clone
();
51
y_
= grad.
clone
();
52
if
(
state_
->mode ==
SECANTMODE_FORWARD
) {
53
Bs_
= grad.
clone
();
dual_
= grad.
clone
();
54
}
55
else
if
(
state_
->mode ==
SECANTMODE_INVERSE
) {
56
Hy_
= x.
clone
();
prim_
= x.
clone
();
57
}
58
else
{
59
Bs_
= grad.
clone
();
dual_
= grad.
clone
();
60
Hy_
= x.
clone
();
prim_
= x.
clone
();
61
}
62
isInitialized_
=
true
;
63
}
64
65
// Update iterate
66
state_
->iter = iter;
67
state_
->iterate->set(x);
68
69
// Compute gradient difference
70
y_
->set(grad);
71
y_
->axpy(-one,gp);
72
73
Real dotF(
ROL_INF<Real>
()), tolF(0), dotI(
ROL_INF<Real>
()), tolI(0);
74
if
(
state_
->mode ==
SECANTMODE_FORWARD
||
state_
->mode ==
SECANTMODE_BOTH
) {
75
// Compute y - Bs and <s, y - Bs>
76
applyB
(*
Bs_
,s);
77
Bs_
->scale(-one);
78
Bs_
->plus(*
y_
);
79
//dotF = s.dot(Bs_->dual());
80
dotF = s.
apply
(*
Bs_
);
81
tolF = tol*snorm*
Bs_
->norm();
82
}
83
if
(
state_
->mode ==
SECANTMODE_INVERSE
||
state_
->mode ==
SECANTMODE_BOTH
) {
84
// Compute s - Hy and <y, s - Hy>
85
applyH
(*
Hy_
,*
y_
);
86
Hy_
->scale(-one);
87
Hy_
->plus(s);
88
//dotI = y_->dot(Hy_->dual());
89
dotI =
y_
->apply(*
Hy_
);
90
tolI = tol*
y_
->norm()*
Hy_
->norm();
91
}
92
if
(std::abs(dotF) > tolF && std::abs(dotI) > tolI) {
93
if
(
state_
->current <
state_
->storage-1) {
94
state_
->current++;
95
if
(
state_
->mode ==
SECANTMODE_INVERSE
||
state_
->mode ==
SECANTMODE_BOTH
) {
96
state_
->iterDiff.push_back(x.
clone
());
// Create new memory
97
}
98
if
(
state_
->mode ==
SECANTMODE_FORWARD
||
state_
->mode ==
SECANTMODE_BOTH
) {
99
state_
->gradDiff.push_back(grad.
clone
());
// Create new memory
100
}
101
}
102
else
{
103
if
(
state_
->mode ==
SECANTMODE_INVERSE
||
state_
->mode ==
SECANTMODE_BOTH
) {
104
state_
->iterDiff.push_back(
state_
->iterDiff[0]);
// Move first element to the last
105
state_
->iterDiff.erase(
state_
->iterDiff.begin());
// Remove first element of s list
106
state_
->product2.erase(
state_
->product2.begin());
// Remove first element of rho list
107
}
108
if
(
state_
->mode ==
SECANTMODE_FORWARD
||
state_
->mode ==
SECANTMODE_BOTH
) {
109
state_
->gradDiff.push_back(
state_
->gradDiff[0]);
// Move first element to the last
110
state_
->gradDiff.erase(
state_
->gradDiff.begin());
// Remove first element of y list
111
state_
->product.erase(
state_
->product.begin());
// Remove first element of rho list
112
}
113
}
114
if
(
state_
->mode ==
SECANTMODE_INVERSE
||
state_
->mode ==
SECANTMODE_BOTH
) {
115
state_
->iterDiff[
state_
->current]->set(*
Hy_
);
// s_k - H_k y_k
116
state_
->product2.push_back(dotI);
// (s_k - H_k y_k)' y_k
117
}
118
if
(
state_
->mode ==
SECANTMODE_FORWARD
||
state_
->mode ==
SECANTMODE_BOTH
) {
119
state_
->gradDiff[
state_
->current]->set(*
Bs_
);
// y_k - B_k s_k
120
state_
->product.push_back(dotF);
// (y_k - B_k s_k)' s_k
121
}
122
//if (useDefaultScaling_) Bscaling_ = s.dot(y_->dual())/(snorm*snorm);
123
if
(
useDefaultScaling_
)
Bscaling_
= s.
apply
(*
y_
)/(snorm*snorm);
124
}
125
/*
126
const Real one(1);
127
if ( !isInitialized_ ) {
128
state_->iterate = x.clone();
129
y_ = grad.clone();
130
isInitialized_ = true;
131
}
132
133
state_->iterate->set(x);
134
state_->iter = iter;
135
y_->set(grad);
136
y_->axpy(-one,gp);
137
138
if (updateIterate_ || state_->current == -1) {
139
Real sy = s.dot(y_->dual());
140
if (state_->current < state_->storage-1) {
141
state_->current++; // Increment Storage
142
state_->iterDiff.push_back(s.clone()); // Create new memory
143
state_->gradDiff.push_back(grad.clone()); // Create new memory
144
}
145
else {
146
state_->iterDiff.push_back(state_->iterDiff[0]); // Move first element to the last
147
state_->gradDiff.push_back(state_->gradDiff[0]); // Move first element to the last
148
state_->iterDiff.erase(state_->iterDiff.begin()); // Remove first element of s list
149
state_->gradDiff.erase(state_->gradDiff.begin()); // Remove first element of y list
150
state_->product.erase(state_->product.begin()); // Remove first element of rho list
151
}
152
state_->iterDiff[state_->current]->set(s); // s=x_{k+1}-x_k
153
state_->gradDiff[state_->current]->set(*y_); // y=g_{k+1}-g_k
154
state_->product.push_back(sy); // ys=1/rho
155
}
156
updateIterate_ = true;
157
*/
158
}
159
160
// Apply Initial Secant Approximate Inverse Hessian
161
virtual
void
applyH0
(
Vector<Real>
&Hv,
const
Vector<Real>
&v )
const
{
162
if
(
state_
->current > -1) {
163
prim_
->set(v.
dual
());
164
Hv.
set
(*
prim_
);
165
H0called_
=
true
;
166
}
167
else
{
168
Hv.
set
(v.
dual
());
169
}
170
Hv.
scale
(
static_cast<
Real
>
(1)/
Bscaling_
);
171
}
172
173
// Apply lSR1 Approximate Inverse Hessian
174
void
applyH
(
Vector<Real>
&Hv,
const
Vector<Real>
&v )
const
{
175
if
(
state_
->mode ==
SECANTMODE_INVERSE
||
state_
->mode ==
SECANTMODE_BOTH
) {
176
// Apply initial Hessian approximation to v
177
H0called_
=
false
;
178
applyH0
(Hv,v);
179
// Apply rank one updates
180
if
(
state_
->current > -1) {
181
Real prod(0);
182
if
(!
H0called_
)
prim_
->set(v.
dual
());
183
for
(
int
i = 0; i <=
state_
->current; ++i) {
184
prod =
state_
->iterDiff[i]->dot(*
prim_
);
185
Hv.
axpy
(prod/
state_
->product2[i],*
state_
->iterDiff[i]);
186
}
187
}
188
}
189
else
{
190
throw
Exception::NotImplemented
(
">>> ROL::lSR1::applyH : Not supported in forward mode!"
);
191
}
192
/*
193
std::vector<Ptr<Vector<Real>>> a(state_->current+1);
194
std::vector<Ptr<Vector<Real>>> b(state_->current+1);
195
Real byi(0), byj(0), bv(0), normbi(0), normyi(0), one(1);
196
for (int i = 0; i <= state_->current; i++) {
197
// Compute Hy
198
a[i] = Hv.clone();
199
applyH0(*(a[i]),*(state_->gradDiff[i]));
200
for (int j = 0; j < i; j++) {
201
byj = b[j]->dot((state_->gradDiff[j])->dual());
202
byi = b[j]->dot((state_->gradDiff[i])->dual());
203
a[i]->axpy(byi/byj,*(b[j]));
204
}
205
// Compute s - Hy
206
b[i] = Hv.clone();
207
b[i]->set(*(state_->iterDiff[i]));
208
b[i]->axpy(-one,*(a[i]));
209
210
// Compute Hv
211
byi = b[i]->dot((state_->gradDiff[i])->dual());
212
normbi = b[i]->norm();
213
normyi = (state_->gradDiff[i])->norm();
214
if ( i == state_->current && std::abs(byi) < sqrt(ROL_EPSILON<Real>())*normbi*normyi ) {
215
updateIterate_ = false;
216
}
217
else {
218
updateIterate_ = true;
219
bv = b[i]->dot(v.dual());
220
Hv.axpy(bv/byi,*(b[i]));
221
}
222
}
223
*/
224
}
225
226
// Apply Initial Secant Approximate Hessian
227
virtual
void
applyB0
(
Vector<Real>
&Bv,
const
Vector<Real>
&v )
const
{
228
if
(
state_
->current > -1) {
229
dual_
->set(v.
dual
());
230
Bv.
set
(*
dual_
);
231
B0called_
=
true
;
232
}
233
else
{
234
Bv.
set
(v.
dual
());
235
}
236
Bv.
scale
(
Bscaling_
);
237
}
238
239
// Apply lSR1 Approximate Hessian
240
void
applyB
(
Vector<Real>
&Bv,
const
Vector<Real>
&v )
const
{
241
if
(
state_
->mode ==
SECANTMODE_FORWARD
||
state_
->mode ==
SECANTMODE_BOTH
) {
242
// Apply initial Hessian approximation to v
243
B0called_
=
false
;
244
applyB0
(Bv,v);
245
// Apply rank one updates
246
if
(
state_
->current > -1) {
247
Real prod(0);
248
if
(!
B0called_
)
dual_
->set(v.
dual
());
249
for
(
int
i = 0; i <=
state_
->current; ++i) {
250
prod =
state_
->gradDiff[i]->dot(*
dual_
);
251
Bv.
axpy
(prod/
state_
->product[i],*
state_
->gradDiff[i]);
252
}
253
}
254
}
255
else
{
256
throw
Exception::NotImplemented
(
">>> ROL::lSR1::applyB : Not supported in inverse mode!"
);
257
}
258
/*
259
std::vector<Ptr<Vector<Real>>> a(state_->current+1);
260
std::vector<Ptr<Vector<Real>>> b(state_->current+1);
261
Real bsi(0), bsj(0), bv(0), normbi(0), normsi(0), one(1);
262
for (int i = 0; i <= state_->current; i++) {
263
// Compute Hy
264
a[i] = Bv.clone();
265
applyB0(*(a[i]),*(state_->iterDiff[i]));
266
for (int j = 0; j < i; j++) {
267
bsj = (state_->iterDiff[j])->dot(b[j]->dual());
268
bsi = (state_->iterDiff[i])->dot(b[j]->dual());
269
a[i]->axpy(bsi/bsj,*(b[j]));
270
}
271
// Compute s - Hy
272
b[i] = Bv.clone();
273
b[i]->set(*(state_->gradDiff[i]));
274
b[i]->axpy(-one,*(a[i]));
275
276
// Compute Hv
277
bsi = (state_->iterDiff[i])->dot(b[i]->dual());
278
normbi = b[i]->norm();
279
normsi = (state_->iterDiff[i])->norm();
280
if ( i == state_->current && std::abs(bsi) < sqrt(ROL_EPSILON<Real>())*normbi*normsi ) {
281
updateIterate_ = false;
282
}
283
else {
284
updateIterate_ = true;
285
bv = b[i]->dot(v.dual());
286
Bv.axpy(bv/bsi,*(b[i]));
287
}
288
}
289
*/
290
}
291
};
292
293
}
294
295
#endif
ROL_Secant.hpp
ROL_Types.hpp
Contains definitions of custom data types in ROL.
ROL::Exception::NotImplemented
Definition
ROL_Types.hpp:884
ROL::ROL::Secant::Bscaling_
Real Bscaling_
Definition
ROL_Constraint_SerialSimOpt.hpp:51
ROL::ROL::Secant::state_
const Ptr< SecantState< Real > > state_
Definition
ROL_Constraint_SerialSimOpt.hpp:48
ROL::ROL::Secant::useDefaultScaling_
bool useDefaultScaling_
Definition
ROL_Constraint_SerialSimOpt.hpp:50
ROL::ROL::Secant::y_
Ptr< Vector< Real > > y_
Definition
ROL_Constraint_SerialSimOpt.hpp:49
ROL::ROL::Secant::Secant
Secant(int M=10, bool useDefaultScaling=true, Real Bscaling=Real(1), ESecantMode mode=SECANTMODE_BOTH)
Definition
ROL_Constraint_SerialSimOpt.hpp:62
ROL::Vector
Defines the linear algebra or vector space interface.
Definition
ROL_Vector.hpp:51
ROL::Vector::apply
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
Definition
ROL_Vector.hpp:205
ROL::Vector::set
virtual void set(const Vector &x)
Set where .
Definition
ROL_Vector.hpp:176
ROL::Vector::scale
virtual void scale(const Real alpha)=0
Compute where .
ROL::Vector::dual
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:193
ROL::Vector::clone
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
ROL::Vector::axpy
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition
ROL_Vector.hpp:120
ROL::lSR1::applyB
void applyB(Vector< Real > &Bv, const Vector< Real > &v) const
Definition
ROL_lSR1.hpp:240
ROL::lSR1::Bs_
Ptr< Vector< Real > > Bs_
Definition
ROL_lSR1.hpp:29
ROL::lSR1::Hy_
Ptr< Vector< Real > > Hy_
Definition
ROL_lSR1.hpp:29
ROL::lSR1::dual_
Ptr< Vector< Real > > dual_
Definition
ROL_lSR1.hpp:29
ROL::lSR1::isInitialized_
bool isInitialized_
Definition
ROL_lSR1.hpp:27
ROL::lSR1::applyH
void applyH(Vector< Real > &Hv, const Vector< Real > &v) const
Definition
ROL_lSR1.hpp:174
ROL::lSR1::prim_
Ptr< Vector< Real > > prim_
Definition
ROL_lSR1.hpp:29
ROL::lSR1::B0called_
bool B0called_
Definition
ROL_lSR1.hpp:28
ROL::lSR1::applyH0
virtual void applyH0(Vector< Real > &Hv, const Vector< Real > &v) const
Definition
ROL_lSR1.hpp:161
ROL::lSR1::lSR1
lSR1(int M, bool useDefaultScaling=true, Real Bscaling=Real(1), ESecantMode mode=SECANTMODE_BOTH)
Definition
ROL_lSR1.hpp:37
ROL::lSR1::updateStorage
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:45
ROL::lSR1::applyB0
virtual void applyB0(Vector< Real > &Bv, const Vector< Real > &v) const
Definition
ROL_lSR1.hpp:227
ROL::lSR1::H0called_
bool H0called_
Definition
ROL_lSR1.hpp:28
ROL
Definition
ROL_ElementwiseVector.hpp:27
ROL::ROL_EPSILON
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition
ROL_Types.hpp:57
ROL::ESecantMode
ESecantMode
Definition
ROL_Secant.hpp:23
ROL::SECANTMODE_FORWARD
@ SECANTMODE_FORWARD
Definition
ROL_Secant.hpp:24
ROL::SECANTMODE_INVERSE
@ SECANTMODE_INVERSE
Definition
ROL_Secant.hpp:25
ROL::SECANTMODE_BOTH
@ SECANTMODE_BOTH
Definition
ROL_Secant.hpp:26
ROL::ROL_INF
Real ROL_INF(void)
Definition
ROL_Types.hpp:71
Generated by
1.17.0