ROL
ROL_SimulatedVector.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#include "ROL_Vector.hpp"
46
47#ifndef ROL_SIMULATED_VECTOR_H
48#define ROL_SIMULATED_VECTOR_H
49
59namespace ROL {
60
61template<class Real>
62class PrimalSimulatedVector;
63
64template<class Real>
65class DualSimulatedVector;
66
67template<class Real>
68class SimulatedVector : public Vector<Real> {
69
70 typedef Vector<Real> V;
71 typedef ROL::Ptr<V> Vp;
72 typedef ROL::Ptr<BatchManager<Real> > VBMp;
74
75private:
76 const std::vector<Vp> vecs_;
77 ROL::Ptr<BatchManager<Real> > bman_;
78 mutable std::vector<Vp> dual_vecs_;
79 mutable ROL::Ptr<PV> dual_pvec_;
80public:
81
82 typedef typename std::vector<PV>::size_type size_type;
83
84 SimulatedVector( const std::vector<Vp> &vecs, const VBMp &bman ) : vecs_(vecs), bman_(bman) {
85 for( size_type i=0; i<vecs_.size(); ++i ) {
86 dual_vecs_.push_back((vecs_[i]->dual()).clone());
87 }
88 }
89
90 void set( const V &x ) {
91
92 const PV &xs = dynamic_cast<const PV&>(x);
93
94 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
95 std::invalid_argument,
96 "Error: Vectors must have the same number of subvectors." );
97
98 for( size_type i=0; i<vecs_.size(); ++i ) {
99 vecs_[i]->set(*xs.get(i));
100 }
101 }
102
103 void plus( const V &x ) {
104
105 const PV &xs = dynamic_cast<const PV&>(x);
106
107 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
108 std::invalid_argument,
109 "Error: Vectors must have the same number of subvectors." );
110
111 for( size_type i=0; i<vecs_.size(); ++i ) {
112 vecs_[i]->plus(*xs.get(i));
113 }
114 }
115
116 void scale( const Real alpha ) {
117 for( size_type i=0; i<vecs_.size(); ++i ) {
118 vecs_[i]->scale(alpha);
119 }
120 }
121
122 void axpy( const Real alpha, const V &x ) {
123
124 const PV &xs = dynamic_cast<const PV&>(x);
125
126 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
127 std::invalid_argument,
128 "Error: Vectors must have the same number of subvectors." );
129
130 for( size_type i=0; i<vecs_.size(); ++i ) {
131 vecs_[i]->axpy(alpha,*xs.get(i));
132 }
133 }
134
135 virtual Real dot( const V &x ) const {
136
137 const PV &xs = dynamic_cast<const PV&>(x);
138
139 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
140 std::invalid_argument,
141 "Error: Vectors must have the same number of subvectors." );
142
143 Real locresult = 0;
144 Real result = 0;
145 for( size_type i=0; i<vecs_.size(); ++i ) {
146 locresult += vecs_[i]->dot(*xs.get(i));
147 }
148
149 bman_->sumAll(&locresult, &result, 1);
150
151 return result;
152 }
153
154 Real norm() const {
155 return std::sqrt(dot(*this));
156 }
157
158 virtual Vp clone() const {
159
160
161
162 std::vector<Vp> clonevec;
163 for( size_type i=0; i<vecs_.size(); ++i ) {
164 clonevec.push_back(vecs_[i]->clone());
165 }
166 return ROL::makePtr<PV>(clonevec, bman_);
167 }
168
169 virtual const V& dual(void) const {
170
171
172 for( size_type i=0; i<vecs_.size(); ++i ) {
173 dual_vecs_[i]->set(vecs_[i]->dual());
174 }
175 dual_pvec_ = ROL::makePtr<PV>( dual_vecs_, bman_ );
176 return *dual_pvec_;
177 }
178
179 Vp basis( const int i ) const { // this must be fixed for distributed batching
180
181 ROL_TEST_FOR_EXCEPTION( i >= dimension() || i<0,
182 std::invalid_argument,
183 "Error: Basis index must be between 0 and vector dimension." );
184 Vp bvec = clone();
185
186 // Downcast
187 PV &eb = dynamic_cast<PV&>(*bvec);
188
189 int begin = 0;
190 int end = 0;
191
192 // Iterate over subvectors
193 for( size_type j=0; j<vecs_.size(); ++j ) {
194
195 end += vecs_[j]->dimension();
196
197 if( begin<= i && i<end ) {
198 eb.set(j, *(vecs_[j]->basis(i-begin)) );
199 }
200 else {
201 eb.zero(j);
202 }
203
204 begin = end;
205
206 }
207 return bvec;
208 }
209
210 int dimension() const { // this must be fixed for distributed batching
211 int total_dim = 0;
212 for( size_type j=0; j<vecs_.size(); ++j ) {
213 total_dim += vecs_[j]->dimension();
214 }
215 return total_dim;
216 }
217
218 void zero() {
219 for( size_type j=0; j<vecs_.size(); ++j ) {
220 vecs_[j]->zero();
221 }
222 }
223
224 // Apply the same unary function to each subvector
225 void applyUnary( const Elementwise::UnaryFunction<Real> &f ) {
226 for( size_type i=0; i<vecs_.size(); ++i ) {
227 vecs_[i]->applyUnary(f);
228 }
229 }
230
231 // Apply the same binary function to each pair of subvectors in this vector and x
232 void applyBinary( const Elementwise::BinaryFunction<Real> &f, const V &x ) {
233 const PV &xs = dynamic_cast<const PV&>(x);
234
235 for( size_type i=0; i<vecs_.size(); ++i ) {
236 vecs_[i]->applyBinary(f,*xs.get(i));
237 }
238 }
239
240 Real reduce( const Elementwise::ReductionOp<Real> &r ) const {
241 Real result = r.initialValue();
242
243 for( size_type i=0; i<vecs_.size(); ++i ) {
244 r.reduce(vecs_[i]->reduce(r),result);
245 }
246 return result;
247 }
248
249 void setScalar(const Real C) {
250 for( size_type i=0; i<vecs_.size(); ++i ) {
251 vecs_[i]->setScalar(C);
252 }
253 }
254
255 void randomize(const Real l=0.0, const Real u=1.0) {
256 for( size_type i=0; i<vecs_.size(); ++i ) {
257 vecs_[i]->randomize(l,u);
258 }
259 }
260
261 // Methods that do not exist in the base class
262
263 // In distributed batching mode, these are understood to take local indices.
264
265 ROL::Ptr<const Vector<Real> > get(size_type i) const {
266 return vecs_[i];
267 }
268
269 ROL::Ptr<Vector<Real> > get(size_type i) {
270 return vecs_[i];
271 }
272
273 void set(size_type i, const V &x) {
274 vecs_[i]->set(x);
275 }
276
277 void zero(size_type i) {
278 vecs_[i]->zero();
279 }
280
282 return vecs_.size();
283 }
284
285};
286
287// Helper methods
288template<class Real>
289ROL::Ptr<Vector<Real> >
291 const ROL::Ptr<BatchManager<Real>> &bman ) {
292
293 typedef ROL::Ptr<Vector<Real> > Vp;
295
296 Vp temp[] = {a};
297 return ROL::makePtr<PV>(std::vector<Vp>(temp, temp+1), bman );
298}
299
300template<class Real>
302private:
303 const std::vector<ROL::Ptr<Vector<Real>>> vecs_;
304 const ROL::Ptr<BatchManager<Real>> bman_;
305 const ROL::Ptr<SampleGenerator<Real>> sampler_;
306 mutable std::vector<ROL::Ptr<Vector<Real>>> dual_vecs_;
307 mutable ROL::Ptr<DualSimulatedVector<Real>> dual_pvec_;
308 mutable bool isDualInitialized_;
309public:
310
311 PrimalSimulatedVector(const std::vector<ROL::Ptr<Vector<Real>>> &vecs,
312 const ROL::Ptr<BatchManager<Real>> &bman,
313 const ROL::Ptr<SampleGenerator<Real>> &sampler)
314 : SimulatedVector<Real>(vecs,bman), vecs_(vecs), bman_(bman), sampler_(sampler),
315 isDualInitialized_(false) {
316 for( int i=0; i<sampler_->numMySamples(); ++i ) {
317 dual_vecs_.push_back((vecs_[i]->dual()).clone());
318 }
319 }
320
321 Real dot(const Vector<Real> &x) const {
322 const SimulatedVector<Real> &xs
323 = dynamic_cast<const SimulatedVector<Real>&>(x);
324
325 ROL_TEST_FOR_EXCEPTION( sampler_->numMySamples() != static_cast<int>(xs.numVectors()),
326 std::invalid_argument,
327 "Error: Vectors must have the same number of subvectors." );
328
329 Real c = 0;
330 Real locresult = 0;
331 Real result = 0;
332 for( int i=0; i<sampler_->numMySamples(); ++i ) {
333 //locresult += sampler_->getMyWeight(i) * vecs_[i]->dot(*xs.get(i));
334 Real y = sampler_->getMyWeight(i) * vecs_[i]->dot(*xs.get(i)) - c;
335 Real t = locresult + y;
336 c = (t - locresult) - y;
337 locresult = t;
338 }
339
340 bman_->sumAll(&locresult, &result, 1);
341
342 return result;
343 }
344
345 ROL::Ptr<Vector<Real> > clone(void) const {
346 std::vector<ROL::Ptr<Vector<Real> > > clonevec;
347 for( int i=0; i<sampler_->numMySamples(); ++i ) {
348 clonevec.push_back(vecs_[i]->clone());
349 }
350 return ROL::makePtr<PrimalSimulatedVector<Real>>(clonevec, bman_, sampler_);
351 }
352
353 const Vector<Real>& dual(void) const {
354 if (!isDualInitialized_) {
355 dual_pvec_ = ROL::makePtr<DualSimulatedVector<Real>>(dual_vecs_, bman_, sampler_);
356 isDualInitialized_ = true;
357 }
358 for( int i=0; i<sampler_->numMySamples(); ++i ) {
359 dual_vecs_[i]->set(vecs_[i]->dual());
360 dual_vecs_[i]->scale(sampler_->getMyWeight(i));
361 }
362 return *dual_pvec_;
363 }
364
365};
366
367template<class Real>
369private:
370 const std::vector<ROL::Ptr<Vector<Real> > > vecs_;
371 const ROL::Ptr<BatchManager<Real> > bman_;
372 const ROL::Ptr<SampleGenerator<Real> > sampler_;
373 mutable std::vector<ROL::Ptr<Vector<Real> > > primal_vecs_;
374 mutable ROL::Ptr<PrimalSimulatedVector<Real> > primal_pvec_;
376public:
377
378 DualSimulatedVector(const std::vector<ROL::Ptr<Vector<Real> > > &vecs,
379 const ROL::Ptr<BatchManager<Real> > &bman,
380 const ROL::Ptr<SampleGenerator<Real> > &sampler)
381 : SimulatedVector<Real>(vecs,bman), vecs_(vecs), bman_(bman), sampler_(sampler),
382 isPrimalInitialized_(false) {
383 for( int i=0; i<sampler_->numMySamples(); ++i ) {
384 primal_vecs_.push_back((vecs_[i]->dual()).clone());
385 }
386 }
387
388 Real dot(const Vector<Real> &x) const {
389 const SimulatedVector<Real> &xs
390 = dynamic_cast<const SimulatedVector<Real>&>(x);
391
392 ROL_TEST_FOR_EXCEPTION( sampler_->numMySamples() != static_cast<Real>(xs.numVectors()),
393 std::invalid_argument,
394 "Error: Vectors must have the same number of subvectors." );
395
396 Real c = 0;
397 Real locresult = 0;
398 Real result = 0;
399 for( int i=0; i<sampler_->numMySamples(); ++i ) {
400 //locresult += vecs_[i]->dot(*xs.get(i)) / sampler_->getMyWeight(i);
401 Real y = vecs_[i]->dot(*xs.get(i)) / sampler_->getMyWeight(i) - c;
402 Real t = locresult + y;
403 c = (t - locresult) - y;
404 locresult = t;
405 }
406
407 bman_->sumAll(&locresult, &result, 1);
408
409 return result;
410 }
411
412 ROL::Ptr<Vector<Real> > clone(void) const {
413 std::vector<ROL::Ptr<Vector<Real> > > clonevec;
414 for( int i=0; i<sampler_->numMySamples(); ++i ) {
415 clonevec.push_back(vecs_[i]->clone());
416 }
417 return ROL::makePtr<DualSimulatedVector<Real>>(clonevec, bman_, sampler_);
418 }
419
420 const Vector<Real>& dual(void) const {
422 primal_pvec_ = ROL::makePtr<PrimalSimulatedVector<Real>>(primal_vecs_, bman_, sampler_);
424 }
425 const Real one(1);
426 for( int i=0; i<sampler_->numMySamples(); ++i ) {
427 primal_vecs_[i]->set(vecs_[i]->dual());
428 primal_vecs_[i]->scale(one/sampler_->getMyWeight(i));
429 }
430 return *primal_pvec_;
431 }
432
433};
434
435template<class Real>
436ROL::Ptr<const Vector<Real> >
437CreateSimulatedVector( const ROL::Ptr<const Vector<Real> > &a,
438 const ROL::Ptr<BatchManager<Real> > &bman ) {
439
440 typedef ROL::Ptr<const Vector<Real> > Vp;
441 typedef const SimulatedVector<Real> PV;
442
443 Vp temp[] = {a};
444 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+1), bman );
445}
446
447template<class Real>
448ROL::Ptr<Vector<Real> >
450 const ROL::Ptr<Vector<Real> > &b,
451 const ROL::Ptr<BatchManager<Real> > &bman ) {
452
453 typedef ROL::Ptr<Vector<Real> > Vp;
455
456 Vp temp[] = {a,b};
457 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+2), bman );
458}
459
460template<class Real>
461ROL::Ptr<const Vector<Real> >
462CreateSimulatedVector( const ROL::Ptr<const Vector<Real> > &a,
463 const ROL::Ptr<const Vector<Real> > &b,
464 const ROL::Ptr<BatchManager<Real> > &bman ) {
465
466
467 typedef ROL::Ptr<const Vector<Real> > Vp;
468 typedef const SimulatedVector<Real> PV;
469
470 Vp temp[] = {a,b};
471 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+2), bman );
472}
473
474template<class Real>
475ROL::Ptr<Vector<Real> >
477 const ROL::Ptr<Vector<Real> > &b,
478 const ROL::Ptr<Vector<Real> > &c,
479 const ROL::Ptr<BatchManager<Real> > &bman ) {
480
481
482 typedef ROL::Ptr<Vector<Real> > Vp;
484
485 Vp temp[] = {a,b,c};
486 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+3), bman );
487}
488
489template<class Real>
490ROL::Ptr<const Vector<Real> >
491CreateSimulatedVector( const ROL::Ptr<const Vector<Real> > &a,
492 const ROL::Ptr<const Vector<Real> > &b,
493 const ROL::Ptr<const Vector<Real> > &c,
494 const ROL::Ptr<BatchManager<Real> > &bman ) {
495
496
497 typedef ROL::Ptr<const Vector<Real> > Vp;
498 typedef const SimulatedVector<Real> PV;
499
500 Vp temp[] = {a,b,c};
501 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+3), bman );
502}
503
504template<class Real>
505ROL::Ptr<Vector<Real> >
507 const ROL::Ptr<Vector<Real> > &b,
508 const ROL::Ptr<Vector<Real> > &c,
509 const ROL::Ptr<Vector<Real> > &d,
510 const ROL::Ptr<BatchManager<Real> > &bman ) {
511
512
513 typedef ROL::Ptr<Vector<Real> > Vp;
515
516 Vp temp[] = {a,b,c,d};
517 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+4), bman );
518}
519
520template<class Real>
521ROL::Ptr<const Vector<Real> >
522CreateSimulatedVector( const ROL::Ptr<const Vector<Real> > &a,
523 const ROL::Ptr<const Vector<Real> > &b,
524 const ROL::Ptr<const Vector<Real> > &c,
525 const ROL::Ptr<const Vector<Real> > &d,
526 const ROL::Ptr<BatchManager<Real> > &bman ) {
527
528
529 typedef ROL::Ptr<const Vector<Real> > Vp;
530 typedef const SimulatedVector<Real> PV;
531
532 Vp temp[] = {a,b,c,d};
533 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+4), bman );
534}
535
536} // namespace ROL
537
538#endif // ROL_SIMULATED_VECTOR_H
539
PartitionedVector< Real > PV
Real dot(const Vector< Real > &x) const
Compute where .
ROL::Ptr< Vector< Real > > clone(void) const
Clone to make a new (uninitialized) vector.
const std::vector< ROL::Ptr< Vector< Real > > > vecs_
const ROL::Ptr< SampleGenerator< Real > > sampler_
const Vector< Real > & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
const ROL::Ptr< BatchManager< Real > > bman_
ROL::Ptr< PrimalSimulatedVector< Real > > primal_pvec_
DualSimulatedVector(const std::vector< ROL::Ptr< Vector< Real > > > &vecs, const ROL::Ptr< BatchManager< Real > > &bman, const ROL::Ptr< SampleGenerator< Real > > &sampler)
std::vector< ROL::Ptr< Vector< Real > > > primal_vecs_
PrimalSimulatedVector(const std::vector< ROL::Ptr< Vector< Real > > > &vecs, const ROL::Ptr< BatchManager< Real > > &bman, const ROL::Ptr< SampleGenerator< Real > > &sampler)
ROL::Ptr< Vector< Real > > clone(void) const
Clone to make a new (uninitialized) vector.
ROL::Ptr< DualSimulatedVector< Real > > dual_pvec_
std::vector< ROL::Ptr< Vector< Real > > > dual_vecs_
const ROL::Ptr< BatchManager< Real > > bman_
Real dot(const Vector< Real > &x) const
Compute where .
const std::vector< ROL::Ptr< Vector< Real > > > vecs_
const ROL::Ptr< SampleGenerator< Real > > sampler_
const Vector< Real > & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
Defines the linear algebra of a vector space on a generic partitioned vector where the individual vec...
ROL::Ptr< BatchManager< Real > > VBMp
void scale(const Real alpha)
Compute where .
std::vector< PV >::size_type size_type
void zero()
Set to zero vector.
ROL::Ptr< BatchManager< Real > > bman_
ROL::Ptr< Vector< Real > > get(size_type i)
Real reduce(const Elementwise::ReductionOp< Real > &r) const
void applyUnary(const Elementwise::UnaryFunction< Real > &f)
ROL::Ptr< const Vector< Real > > get(size_type i) const
size_type numVectors() const
void applyBinary(const Elementwise::BinaryFunction< Real > &f, const V &x)
void randomize(const Real l=0.0, const Real u=1.0)
Set vector to be uniform random between [l,u].
const std::vector< Vp > vecs_
void set(size_type i, const V &x)
SimulatedVector< Real > PV
virtual const V & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
void set(const V &x)
Set where .
void setScalar(const Real C)
Set where .
void axpy(const Real alpha, const V &x)
Compute where .
Real norm() const
Returns where .
std::vector< Vp > dual_vecs_
Vp basis(const int i) const
Return i-th basis vector.
int dimension() const
Return dimension of the vector space.
SimulatedVector(const std::vector< Vp > &vecs, const VBMp &bman)
virtual Vp clone() const
Clone to make a new (uninitialized) vector.
virtual Real dot(const V &x) const
Compute where .
void plus(const V &x)
Compute , where .
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:84
ROL::Ptr< Vector< Real > > CreateSimulatedVector(const ROL::Ptr< Vector< Real > > &a, const ROL::Ptr< BatchManager< Real > > &bman)