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