ROL
ROL_Vector.hpp
Go to the documentation of this file.
1 
2 // @HEADER
3 // ************************************************************************
4 //
5 // Rapid Optimization Library (ROL) Package
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact lead developers:
39 // Drew Kouri (dpkouri@sandia.gov) and
40 // Denis Ridzal (dridzal@sandia.gov)
41 //
42 // ************************************************************************
43 // @HEADER
44 
45 #ifndef ROL_VECTOR_H
46 #define ROL_VECTOR_H
47 
48 #define ROL_UNUSED(x) (void) x
49 
50 #include <ostream>
51 #include <vector>
52 #include <algorithm>
53 
54 #include "ROL_Elementwise_Function.hpp"
55 
56 #include "ROL_Ptr.hpp"
57 #include "ROL_Stream.hpp"
58 
77 namespace ROL {
78 
79 template <class Real>
80 class Vector
81 #ifdef ENABLE_PYROL
82  : public std::enable_shared_from_this<Vector<Real>>
83 #endif
84 {
85 public:
86 
87  virtual ~Vector() {}
88 
89 
98  virtual void plus( const Vector &x ) = 0;
99 
100 
109  virtual void scale( const Real alpha ) = 0;
110 
111 
119  virtual Real dot( const Vector &x ) const = 0;
120 
121 
128  virtual Real norm() const = 0;
129 
130 
139  virtual ROL::Ptr<Vector> clone() const = 0;
140 
141 
153  virtual void axpy( const Real alpha, const Vector &x ) {
154  ROL::Ptr<Vector> ax = x.clone();
155  ax->set(x);
156  ax->scale(alpha);
157  this->plus(*ax);
158  }
159 
167  virtual void zero() {
168  this->scale( (Real)0 );
169  }
170 
171 
182  virtual ROL::Ptr<Vector> basis( const int i ) const {
183  ROL_UNUSED(i);
184  return ROL::nullPtr;
185  }
186 
187 
196  virtual int dimension() const {return 0;}
197 
198 
209  virtual void set( const Vector &x ) {
210  this->zero();
211  this->plus(x);
212  }
213 
214 
226  virtual const Vector & dual() const {
227  return *this;
228  }
229 
238  virtual Real apply(const Vector<Real> &x) const {
239  return this->dot(x.dual());
240  }
241 
242  virtual void applyUnary( const Elementwise::UnaryFunction<Real> &f ) {
243  ROL_UNUSED(f);
244  ROL_TEST_FOR_EXCEPTION( true, std::logic_error,
245  "The method applyUnary was called, but not implemented" << std::endl);
246  }
247 
248  virtual void applyBinary( const Elementwise::BinaryFunction<Real> &f, const Vector &x ) {
249  ROL_UNUSED(f);
250  ROL_UNUSED(x);
251  ROL_TEST_FOR_EXCEPTION( true, std::logic_error,
252  "The method applyBinary was called, but not implemented" << std::endl);
253  }
254 
255  virtual Real reduce( const Elementwise::ReductionOp<Real> &r ) const {
256  ROL_UNUSED(r);
257  ROL_TEST_FOR_EXCEPTION( true, std::logic_error,
258  "The method reduce was called, but not implemented" << std::endl);
259  }
260 
261  virtual void print( std::ostream &outStream ) const {
262  outStream << "The method print was called, but not implemented" << std::endl;
263  }
264 
275  virtual void setScalar( const Real C ) {
276  this->applyUnary(Elementwise::Fill<Real>(C));
277  }
278 
292  virtual void randomize( const Real l = 0.0, const Real u = 1.0 ) {
293  Elementwise::UniformlyRandom<Real> ur(l,u);
294  this->applyUnary(ur);
295  }
296 
325  virtual std::vector<Real> checkVector( const Vector<Real> &x,
326  const Vector<Real> &y,
327  const bool printToStream = true,
328  std::ostream & outStream = std::cout ) const {
329  Real zero = 0.0;
330  Real one = 1.0;
331  Real a = 1.234;
332  Real b = -0.4321;
333  int width = 94;
334  std::vector<Real> vCheck;
335 
336  ROL::nullstream bhs; // outputs nothing
337 
338  ROL::Ptr<std::ostream> pStream;
339  if (printToStream) {
340  pStream = ROL::makePtrFromRef(outStream);
341  } else {
342  pStream = ROL::makePtrFromRef(bhs);
343  }
344 
345  // Save the format state of the original pStream.
346  ROL::nullstream oldFormatState, headerFormatState;
347  oldFormatState.copyfmt(*pStream);
348 
349  ROL::Ptr<Vector> v = this->clone();
350  ROL::Ptr<Vector> vtmp = this->clone();
351  ROL::Ptr<Vector> xtmp = x.clone();
352  ROL::Ptr<Vector> ytmp = y.clone();
353 
354  *pStream << "\n" << std::setw(width) << std::left << std::setfill('*') << "********** Begin verification of linear algebra. " << "\n\n";
355  headerFormatState.copyfmt(*pStream);
356 
357  // Commutativity of addition.
358  v->set(*this); xtmp->set(x); ytmp->set(y);
359  v->plus(x); xtmp->plus(*this); v->axpy(-one, *xtmp); vCheck.push_back(v->norm());
360  *pStream << std::scientific << std::setprecision(12) << std::setfill('>');
361  *pStream << std::setw(width) << std::left << "Commutativity of addition. Consistency error: " << " " << vCheck.back() << "\n";
362 
363  // Associativity of addition.
364  v->set(*this); xtmp->set(x); ytmp->set(y);
365  ytmp->plus(x); v->plus(*ytmp); xtmp->plus(*this); xtmp->plus(y); v->axpy(-one, *xtmp); vCheck.push_back(v->norm());
366  *pStream << std::setw(width) << std::left << "Associativity of addition. Consistency error: " << " " << vCheck.back() << "\n";
367 
368  // Identity element of addition.
369  v->set(*this); xtmp->set(x); ytmp->set(y);
370  v->zero(); v->plus(x); v->axpy(-one, x); vCheck.push_back(v->norm());
371  *pStream << std::setw(width) << std::left << "Identity element of addition. Consistency error: " << " " << vCheck.back() << "\n";
372 
373  // Inverse elements of addition.
374  v->set(*this); xtmp->set(x); ytmp->set(y);
375  v->scale(-one); v->plus(*this); vCheck.push_back(v->norm());
376  *pStream << std::setw(width) << std::left << "Inverse elements of addition. Consistency error: " << " " << vCheck.back() << "\n";
377 
378  // Identity element of scalar multiplication.
379  v->set(*this); xtmp->set(x); ytmp->set(y);
380  v->scale(one); v->axpy(-one, *this); vCheck.push_back(v->norm());
381  *pStream << std::setw(width) << std::left << "Identity element of scalar multiplication. Consistency error: " << " " << vCheck.back() << "\n";
382 
383  // Consistency of scalar multiplication with field multiplication.
384  v->set(*this); vtmp->set(*this);
385  v->scale(b); v->scale(a); vtmp->scale(a*b); v->axpy(-one, *vtmp); vCheck.push_back(v->norm());
386  *pStream << std::setw(width) << std::left << "Consistency of scalar multiplication with field multiplication. Consistency error: " << " " << vCheck.back() << "\n";
387 
388  // Distributivity of scalar multiplication with respect to field addition.
389  v->set(*this); vtmp->set(*this);
390  v->scale(a+b); vtmp->scale(a); vtmp->axpy(b, *this); v->axpy(-one, *vtmp); vCheck.push_back(v->norm());
391  *pStream << std::setw(width) << std::left << "Distributivity of scalar multiplication with respect to field addition. Consistency error: " << " " << vCheck.back() << "\n";
392 
393  // Distributivity of scalar multiplication with respect to vector addition.
394  v->set(*this); xtmp->set(x); ytmp->set(y);
395  v->plus(x); v->scale(a); xtmp->scale(a); xtmp->axpy(a, *this); v->axpy(-one, *xtmp); vCheck.push_back(v->norm());
396  *pStream << std::setw(width) << std::left << "Distributivity of scalar multiplication with respect to vector addition. Consistency error: " << " " << vCheck.back() << "\n";
397 
398  // Commutativity of dot (inner) product over the field of reals.
399  vCheck.push_back(std::abs(this->dot(x) - x.dot(*this)));
400  *pStream << std::setw(width) << std::left << "Commutativity of dot (inner) product over the field of reals. Consistency error: " << " " << vCheck.back() << "\n";
401 
402  // Additivity of dot (inner) product.
403  xtmp->set(x);
404  xtmp->plus(y); vCheck.push_back(std::abs(this->dot(*xtmp) - this->dot(x) - this->dot(y))/std::max({static_cast<Real>(std::abs(this->dot(*xtmp))), static_cast<Real>(std::abs(this->dot(x))), static_cast<Real>(std::abs(this->dot(y))), one}));
405  *pStream << std::setw(width) << std::left << "Additivity of dot (inner) product. Consistency error: " << " " << vCheck.back() << "\n";
406 
407  // Consistency of scalar multiplication and norm.
408  v->set(*this);
409  Real vnorm = v->norm();
410  if (vnorm == zero) {
411  v->scale(a);
412  vCheck.push_back(std::abs(v->norm() - zero));
413  } else {
414  v->scale(one/vnorm);
415  vCheck.push_back(std::abs(v->norm() - one));
416  }
417  *pStream << std::setw(width) << std::left << "Consistency of scalar multiplication and norm. Consistency error: " << " " << vCheck.back() << "\n";
418 
419  // Reflexivity.
420  v->set(*this);
421  xtmp = ROL::constPtrCast<Vector>(ROL::makePtrFromRef(this->dual()));
422  ytmp = ROL::constPtrCast<Vector>(ROL::makePtrFromRef(xtmp->dual()));
423  v->axpy(-one, *ytmp); vCheck.push_back(v->norm());
424  *pStream << std::setw(width) << std::left << "Reflexivity. Consistency error: " << " " << vCheck.back() << "\n";
425 
426  // Consistency of apply and dual.
427  v->set(*this);
428  xtmp = x.dual().clone(); xtmp->set(x.dual());
429  Real vx = v->apply(*xtmp);
430  Real vxd = v->dot(xtmp->dual());
431  Real vdx = xtmp->dot(v->dual());
432  if (vx == zero) {
433  vCheck.push_back(std::max(std::abs(vx-vxd),std::abs(vx-vdx)));
434  }
435  else {
436  vCheck.push_back(std::max(std::abs(vx-vxd),std::abs(vx-vdx))/std::abs(vx));
437  }
438  *pStream << std::setw(width) << std::left << "Consistency of apply and dual:" << " " << vCheck.back() << "\n\n";
439 
440  //*pStream << "************ End verification of linear algebra.\n\n";
441 
442  // Restore format state of pStream used for the header info.
443  pStream->copyfmt(headerFormatState);
444  *pStream << std::setw(width) << std::left << "********** End verification of linear algebra. " << "\n\n";
445 
446  // Restore format state of the original pStream.
447  pStream->copyfmt(oldFormatState);
448 
449  return vCheck;
450  }
451 
452 }; // class Vector
453 
454 } // namespace ROL
455 
456 #endif
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Definition: ROL_Vector.hpp:226
virtual void scale(const Real alpha)=0
Compute where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual int dimension() const
Return dimension of the vector space.
Definition: ROL_Vector.hpp:196
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
Definition: ROL_Vector.hpp:238
virtual ROL::Ptr< Vector > basis(const int i) const
Return i-th basis vector.
Definition: ROL_Vector.hpp:182
virtual void plus(const Vector &x)=0
Compute , where .
virtual void print(std::ostream &outStream) const
Definition: ROL_Vector.hpp:261
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:153
virtual Real reduce(const Elementwise::ReductionOp< Real > &r) const
Definition: ROL_Vector.hpp:255
virtual void applyBinary(const Elementwise::BinaryFunction< Real > &f, const Vector &x)
Definition: ROL_Vector.hpp:248
virtual void randomize(const Real l=0.0, const Real u=1.0)
Set vector to be uniform random between [l,u].
Definition: ROL_Vector.hpp:292
virtual std::vector< Real > checkVector(const Vector< Real > &x, const Vector< Real > &y, const bool printToStream=true, std::ostream &outStream=std::cout) const
Verify vector-space methods.
Definition: ROL_Vector.hpp:325
virtual void zero()
Set to zero vector.
Definition: ROL_Vector.hpp:167
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
virtual Real dot(const Vector &x) const =0
Compute where .
#define ROL_UNUSED(x)
Definition: ROL_Vector.hpp:48
virtual ~Vector()
Definition: ROL_Vector.hpp:87
virtual void setScalar(const Real C)
Set where .
Definition: ROL_Vector.hpp:275
virtual void applyUnary(const Elementwise::UnaryFunction< Real > &f)
Definition: ROL_Vector.hpp:242
basic_nullstream< char, char_traits< char >> nullstream
Definition: ROL_Stream.hpp:72
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:209
virtual Real norm() const =0
Returns where .