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"
45 #include "ROL_SampleGenerator.hpp"
46 
47 #ifndef ROL_SIMULATED_VECTOR_H
48 #define ROL_SIMULATED_VECTOR_H
49 
59 namespace ROL {
60 
61 template<class Real>
63 
64 template<class Real>
66 
67 template<class Real>
68 class SimulatedVector : public Vector<Real> {
69 
70  typedef Vector<Real> V;
71  typedef ROL::Ptr<V> Vp;
72  typedef ROL::Ptr<BatchManager<Real> > VBMp;
74 
75 private:
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_;
80 public:
81 
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
288 template<class Real>
289 ROL::Ptr<Vector<Real> >
290 CreateSimulatedVector( const ROL::Ptr<Vector<Real>> &a,
291  const ROL::Ptr<BatchManager<Real>> &bman ) {
292 
293  typedef ROL::Ptr<Vector<Real> > Vp;
294  typedef SimulatedVector<Real> PV;
295 
296  Vp temp[] = {a};
297  return ROL::makePtr<PV>(std::vector<Vp>(temp, temp+1), bman );
298 }
299 
300 template<class Real>
301 class PrimalSimulatedVector : public SimulatedVector<Real> {
302 private:
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_;
309 public:
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 
367 template<class Real>
368 class DualSimulatedVector : public SimulatedVector<Real> {
369 private:
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_;
375  mutable bool isPrimalInitialized_;
376 public:
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 {
421  if (!isPrimalInitialized_) {
422  primal_pvec_ = ROL::makePtr<PrimalSimulatedVector<Real>>(primal_vecs_, bman_, sampler_);
423  isPrimalInitialized_ = true;
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 
435 template<class Real>
436 ROL::Ptr<const Vector<Real> >
437 CreateSimulatedVector( 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 
447 template<class Real>
448 ROL::Ptr<Vector<Real> >
449 CreateSimulatedVector( const ROL::Ptr<Vector<Real> > &a,
450  const ROL::Ptr<Vector<Real> > &b,
451  const ROL::Ptr<BatchManager<Real> > &bman ) {
452 
453  typedef ROL::Ptr<Vector<Real> > Vp;
454  typedef SimulatedVector<Real> PV;
455 
456  Vp temp[] = {a,b};
457  return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+2), bman );
458 }
459 
460 template<class Real>
461 ROL::Ptr<const Vector<Real> >
462 CreateSimulatedVector( 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 
474 template<class Real>
475 ROL::Ptr<Vector<Real> >
476 CreateSimulatedVector( const ROL::Ptr<Vector<Real> > &a,
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;
483  typedef SimulatedVector<Real> PV;
484 
485  Vp temp[] = {a,b,c};
486  return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+3), bman );
487 }
488 
489 template<class Real>
490 ROL::Ptr<const Vector<Real> >
491 CreateSimulatedVector( 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 
504 template<class Real>
505 ROL::Ptr<Vector<Real> >
506 CreateSimulatedVector( const ROL::Ptr<Vector<Real> > &a,
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;
514  typedef SimulatedVector<Real> PV;
515 
516  Vp temp[] = {a,b,c,d};
517  return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+4), bman );
518 }
519 
520 template<class Real>
521 ROL::Ptr<const Vector<Real> >
522 CreateSimulatedVector( 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
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:80
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_