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"
11 #include "ROL_SampleGenerator.hpp"
12 
13 #ifndef ROL_SIMULATED_VECTOR_H
14 #define ROL_SIMULATED_VECTOR_H
15 
25 namespace ROL {
26 
27 template<class Real>
29 
30 template<class Real>
32 
33 template<class Real>
34 class SimulatedVector : public Vector<Real> {
35 
36  typedef Vector<Real> V;
37  typedef ROL::Ptr<V> Vp;
38  typedef ROL::Ptr<BatchManager<Real> > VBMp;
40 
41 private:
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_;
46 public:
47 
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
254 template<class Real>
255 ROL::Ptr<Vector<Real> >
256 CreateSimulatedVector( const ROL::Ptr<Vector<Real>> &a,
257  const ROL::Ptr<BatchManager<Real>> &bman ) {
258 
259  typedef ROL::Ptr<Vector<Real> > Vp;
260  typedef SimulatedVector<Real> PV;
261 
262  Vp temp[] = {a};
263  return ROL::makePtr<PV>(std::vector<Vp>(temp, temp+1), bman );
264 }
265 
266 template<class Real>
267 class PrimalSimulatedVector : public SimulatedVector<Real> {
268 private:
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_;
275 public:
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 
333 template<class Real>
334 class DualSimulatedVector : public SimulatedVector<Real> {
335 private:
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_;
341  mutable bool isPrimalInitialized_;
342 public:
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 {
387  if (!isPrimalInitialized_) {
388  primal_pvec_ = ROL::makePtr<PrimalSimulatedVector<Real>>(primal_vecs_, bman_, sampler_);
389  isPrimalInitialized_ = true;
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 
401 template<class Real>
402 ROL::Ptr<const Vector<Real> >
403 CreateSimulatedVector( 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 
413 template<class Real>
414 ROL::Ptr<Vector<Real> >
415 CreateSimulatedVector( const ROL::Ptr<Vector<Real> > &a,
416  const ROL::Ptr<Vector<Real> > &b,
417  const ROL::Ptr<BatchManager<Real> > &bman ) {
418 
419  typedef ROL::Ptr<Vector<Real> > Vp;
420  typedef SimulatedVector<Real> PV;
421 
422  Vp temp[] = {a,b};
423  return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+2), bman );
424 }
425 
426 template<class Real>
427 ROL::Ptr<const Vector<Real> >
428 CreateSimulatedVector( 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 
440 template<class Real>
441 ROL::Ptr<Vector<Real> >
442 CreateSimulatedVector( const ROL::Ptr<Vector<Real> > &a,
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;
449  typedef SimulatedVector<Real> PV;
450 
451  Vp temp[] = {a,b,c};
452  return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+3), bman );
453 }
454 
455 template<class Real>
456 ROL::Ptr<const Vector<Real> >
457 CreateSimulatedVector( 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 
470 template<class Real>
471 ROL::Ptr<Vector<Real> >
472 CreateSimulatedVector( const ROL::Ptr<Vector<Real> > &a,
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;
480  typedef SimulatedVector<Real> PV;
481 
482  Vp temp[] = {a,b,c,d};
483  return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+4), bman );
484 }
485 
486 template<class Real>
487 ROL::Ptr<const Vector<Real> >
488 CreateSimulatedVector( 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
ROL::Ptr< BatchManager< Real > > VBMp
typename PV< Real >::size_type size_type
PrimalSimulatedVector(const std::vector< ROL::Ptr< Vector< Real >>> &vecs, const ROL::Ptr< BatchManager< Real >> &bman, const ROL::Ptr< SampleGenerator< Real >> &sampler)
void set(const V &x)
Set where .
ROL::Ptr< Vector< Real > > clone(void) const
Clone to make a new (uninitialized) vector.
int dimension() const
Return dimension of the vector space.
const ROL::Ptr< SampleGenerator< Real > > sampler_
DualSimulatedVector(const std::vector< ROL::Ptr< Vector< Real > > > &vecs, const ROL::Ptr< BatchManager< Real > > &bman, const ROL::Ptr< SampleGenerator< Real > > &sampler)
virtual const V & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
std::vector< PV >::size_type size_type
virtual Vp clone() const
Clone to make a new (uninitialized) vector.
void setScalar(const Real C)
Set where .
void applyBinary(const Elementwise::BinaryFunction< Real > &f, const V &x)
ROL::Ptr< BatchManager< Real > > bman_
const ROL::Ptr< BatchManager< Real > > bman_
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
const ROL::Ptr< BatchManager< Real > > bman_
SimulatedVector(const std::vector< Vp > &vecs, const VBMp &bman)
Defines the linear algebra of a vector space on a generic partitioned vector where the individual vec...
ROL::Ptr< const Vector< Real > > get(size_type i) const
ROL::Ptr< Vector< Real > > CreateSimulatedVector(const ROL::Ptr< Vector< Real >> &a, const ROL::Ptr< BatchManager< Real >> &bman)
void set(size_type i, const V &x)
size_type numVectors() const
const std::vector< ROL::Ptr< Vector< Real > > > vecs_
Real dot(const Vector< Real > &x) const
Compute where .
Vp basis(const int i) const
Return i-th basis vector.
std::vector< ROL::Ptr< Vector< Real > > > dual_vecs_
void zero()
Set to zero vector.
const ROL::Ptr< SampleGenerator< Real > > sampler_
void plus(const V &x)
Compute , where .
Real norm() const
Returns where .
const Vector< Real > & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Real dot(const Vector< Real > &x) const
Compute where .
Real reduce(const Elementwise::ReductionOp< Real > &r) const
virtual Real dot(const V &x) const
Compute where .
SimulatedVector< Real > PV
void scale(const Real alpha)
Compute where .
const std::vector< Vp > vecs_
ROL::Ptr< Vector< Real > > clone(void) const
Clone to make a new (uninitialized) vector.
void axpy(const Real alpha, const V &x)
Compute where .
void applyUnary(const Elementwise::UnaryFunction< Real > &f)
std::vector< Vp > dual_vecs_
std::vector< ROL::Ptr< Vector< Real > > > primal_vecs_
ROL::Ptr< DualSimulatedVector< Real > > dual_pvec_
void randomize(const Real l=0.0, const Real u=1.0)
Set vector to be uniform random between [l,u].
ROL::Ptr< PrimalSimulatedVector< Real > > primal_pvec_
const Vector< Real > & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
const std::vector< ROL::Ptr< Vector< Real > > > vecs_