44#ifndef ROL_BUNDLE_U_DEF_H
45#define ROL_BUNDLE_U_DEF_H
51template<
typename Real>
54 for (
unsigned j = ind.back()+1; j < size_; ++j) {
55 (subgradients_[j-1])->set(*(subgradients_[j]));
56 linearizationErrors_[j-1] = linearizationErrors_[j];
57 distanceMeasures_[j-1] = distanceMeasures_[j];
58 dualVariables_[j-1] = dualVariables_[j];
60 (subgradients_[size_-1])->
zero();
63 dualVariables_[size_-1] =
zero;
64 for (
unsigned i = ind.size()-1; i > 0; --i) {
65 for (
unsigned j = ind[i-1]+1; j < size_; ++j) {
66 (subgradients_[j-1])->set(*(subgradients_[j]));
67 linearizationErrors_[j-1] = linearizationErrors_[j];
68 distanceMeasures_[j-1] = distanceMeasures_[j];
69 dualVariables_[j-1] = dualVariables_[j];
75template<
typename Real>
78 (subgradients_[size_])->set(g);
79 linearizationErrors_[size_] = le;
80 distanceMeasures_[size_] = dm;
81 dualVariables_[size_] =
zero;
85template<
typename Real>
89 const unsigned remSize)
90 : size_(0), maxSize_(maxSize), remSize_(remSize),
91 coeff_(coeff), omega_(omega), isInitialized_(false) {
93 remSize_ = ((remSize_ < 2) ? 2 : ((remSize_ > maxSize_-1) ? maxSize_-1 : remSize_));
94 coeff_ = std::max(
static_cast<Real
>(0),coeff_);
95 omega_ = std::max(
static_cast<Real
>(1),omega_);
96 subgradients_.clear();
97 subgradients_.assign(maxSize,nullPtr);
98 linearizationErrors_.clear();
99 linearizationErrors_.assign(maxSize_,ROL_OVERFLOW<Real>());
100 distanceMeasures_.clear();
101 distanceMeasures_.assign(maxSize_,ROL_OVERFLOW<Real>());
102 dualVariables_.clear();
103 dualVariables_.assign(maxSize_,
zero);
106template<
typename Real>
107void Bundle_U<Real>::initialize(
const Vector<Real> &g) {
108 if ( !isInitialized_ ) {
109 Real
zero(0), one(1);
110 for (
unsigned i = 0; i < maxSize_; ++i) {
111 subgradients_[i] = g.clone();
113 (subgradients_[0])->set(g);
114 linearizationErrors_[0] =
zero;
115 distanceMeasures_[0] =
zero;
116 dualVariables_[0] = one;
118 isInitialized_ =
true;
127template<
typename Real>
128const Real Bundle_U<Real>::linearizationError(
const unsigned i)
const {
129 return linearizationErrors_[i];
132template<
typename Real>
133const Real Bundle_U<Real>::distanceMeasure(
const unsigned i)
const {
134 return distanceMeasures_[i];
137template<
typename Real>
138const Vector<Real> & Bundle_U<Real>::subgradient(
const unsigned i)
const {
139 return *(subgradients_[i]);
142template<
typename Real>
143const Real Bundle_U<Real>::getDualVariable(
const unsigned i)
const {
144 return dualVariables_[i];
147template<
typename Real>
148void Bundle_U<Real>::setDualVariable(
const unsigned i,
const Real val) {
149 dualVariables_[i] = val;
152template<
typename Real>
153void Bundle_U<Real>::resetDualVariables(
void) {
155 dualVariables_.assign(size_,
zero);
158template<
typename Real>
159const Real Bundle_U<Real>::computeAlpha(
const Real dm,
const Real le)
const {
161 if ( coeff_ > ROL_EPSILON<Real>() ) {
162 alpha = std::max(coeff_*std::pow(dm,omega_),le);
167template<
typename Real>
168const Real Bundle_U<Real>::alpha(
const unsigned i)
const {
169 return computeAlpha(distanceMeasures_[i],linearizationErrors_[i]);
172template<
typename Real>
173unsigned Bundle_U<Real>::size(
void)
const {
177template<
typename Real>
178void Bundle_U<Real>::aggregate(Vector<Real> &aggSubGrad, Real &aggLinErr, Real &aggDistMeas)
const {
179 Real
zero(0), one(1);
180 aggSubGrad.zero(); aggLinErr =
zero; aggDistMeas =
zero; eG_->zero();
181 Real eLE(0), eDM(0), yLE(0), yDM(0), tLE(0), tDM(0);
182 for (
unsigned i = 0; i < size_; ++i) {
185 yG_->set(*subgradients_[i]); yG_->scale(dualVariables_[i]); yG_->axpy(-one,*eG_);
186 tG_->set(aggSubGrad); tG_->plus(*yG_);
187 eG_->set(*tG_); eG_->axpy(-one,aggSubGrad); eG_->axpy(-one,*yG_);
188 aggSubGrad.set(*tG_);
191 yLE = dualVariables_[i]*linearizationErrors_[i] - eLE;
192 tLE = aggLinErr + yLE;
193 eLE = (tLE - aggLinErr) - yLE;
197 yDM = dualVariables_[i]*distanceMeasures_[i] - eDM;
198 tDM = aggDistMeas + yDM;
199 eDM = (tDM - aggDistMeas) - yDM;
204template<
typename Real>
205void Bundle_U<Real>::reset(
const Vector<Real> &g,
const Real le,
const Real dm) {
206 if (size_ == maxSize_) {
208 unsigned loc = size_, cnt = 0;
209 std::vector<unsigned> ind(remSize_,0);
210 for (
unsigned i = size_; i > 0; --i) {
211 if ( std::abs(linearizationErrors_[i-1]) < ROL_EPSILON<Real>() ) {
216 for (
unsigned i = 0; i < size_; ++i) {
221 if (cnt == remSize_) {
232template<
typename Real>
233void Bundle_U<Real>::update(
const bool flag,
const Real linErr,
const Real distMeas,
234 const Vector<Real> &g,
const Vector<Real> &s) {
238 for (
unsigned i = 0; i < size_; ++i) {
240 linearizationErrors_[i] += linErr - subgradients_[i]->apply(s);
241 distanceMeasures_[i] += distMeas;
243 linearizationErrors_[size_] =
zero;
244 distanceMeasures_[size_] =
zero;
248 linearizationErrors_[size_] = linErr;
249 distanceMeasures_[size_] = distMeas;
252 (subgradients_[size_])->set(g);
254 dualVariables_[size_] =
zero;
259template<
typename Real>
260const Real Bundle_U<Real>::GiGj(
const unsigned i,
const unsigned j)
const {
261 return subgradient(i).dot(subgradient(j));
264template<
typename Real>
265const Real Bundle_U<Real>::dotGi(
const unsigned i,
const Vector<Real> &x)
const {
266 return x.dot(subgradient(i));
269template<
typename Real>
270void Bundle_U<Real>::addGi(
const unsigned i,
const Real a, Vector<Real> &x)
const {
271 x.axpy(a,subgradient(i));
274template<
typename Real>
275Real Bundle_U<Real>::evaluateObjective(std::vector<Real> &g,
const std::vector<Real> &x,
const Real t)
const {
276 Real one(1), half(0.5);
277 gx_->zero(); eG_->zero();
278 for (
unsigned i = 0; i < size(); ++i) {
281 yG_->set(subgradient(i)); yG_->scale(x[i]); yG_->axpy(-one,*eG_);
282 tG_->set(*gx_); tG_->plus(*yG_);
283 eG_->set(*tG_); eG_->axpy(-one,*gx_); eG_->axpy(-one,*yG_);
286 Real Hx(0), val(0), err(0), tmp(0), y(0);
287 for (
unsigned i = 0; i < size(); ++i) {
292 y = x[i]*(half*Hx + alpha(i)/t) - err;
294 err = (tmp - val) - y;
297 g[i] = Hx + alpha(i)/t;
302template<
typename Real>
303unsigned Bundle_U<Real>::solveDual_dim1(
const Real t,
const unsigned maxit,
const Real tol) {
304 setDualVariable(0,
static_cast<Real
>(1));
309template<
typename Real>
310unsigned Bundle_U<Real>::solveDual_dim2(
const Real t,
const unsigned maxit,
const Real tol) {
311 Real diffg = gx_->dot(*gx_),
zero(0), one(1), half(0.5);
312 gx_->set(subgradient(0)); addGi(1,-one,*gx_);
313 if ( std::abs(diffg) > ROL_EPSILON<Real>() ) {
314 Real diffa = (alpha(0)-alpha(1))/t;
315 Real gdiffg = dotGi(1,*gx_);
316 setDualVariable(0,std::min(one,std::max(
zero,-(gdiffg+diffa)/diffg)));
317 setDualVariable(1,one-getDualVariable(0));
320 if ( std::abs(alpha(0)-alpha(1)) > ROL_EPSILON<Real>() ) {
321 if ( alpha(0) < alpha(1) ) {
322 setDualVariable(0,one); setDualVariable(1,
zero);
324 else if ( alpha(0) > alpha(1) ) {
325 setDualVariable(0,
zero); setDualVariable(1,one);
329 setDualVariable(0,half); setDualVariable(1,half);
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0 zero)()
Contains definitions of custom data types in ROL.
Bundle_U(const unsigned maxSize=10, const Real coeff=0.0, const Real omega=2.0, const unsigned remSize=2)
void add(const Vector< Real > &g, const Real le, const Real dm)
void remove(const std::vector< unsigned > &ind)
Defines the linear algebra or vector space interface.
Real ROL_OVERFLOW(void)
Platform-dependent maximum double.