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