ROL
ROL_Vector.hpp
Go to the documentation of this file.
1 
2 // @HEADER
3 // *****************************************************************************
4 // Rapid Optimization Library (ROL) Package
5 //
6 // Copyright 2014 NTESS and the ROL contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef ROL_VECTOR_H
12 #define ROL_VECTOR_H
13 
14 #define ROL_UNUSED(x) (void) x
15 
16 #include <ostream>
17 #include <vector>
18 #include <algorithm>
19 
20 #include "ROL_Elementwise_Function.hpp"
21 
22 #include "ROL_Ptr.hpp"
23 #include "ROL_Stream.hpp"
24 
43 namespace ROL {
44 
45 template <class Real>
46 class Vector
47 #ifdef ENABLE_PYROL
48  : public std::enable_shared_from_this<Vector<Real>>
49 #endif
50 {
51 public:
52 
53  virtual ~Vector() {}
54 
55 
64  virtual void plus( const Vector &x ) = 0;
65 
66 
75  virtual void scale( const Real alpha ) = 0;
76 
77 
85  virtual Real dot( const Vector &x ) const = 0;
86 
87 
94  virtual Real norm() const = 0;
95 
96 
105  virtual ROL::Ptr<Vector> clone() const = 0;
106 
107 
119  virtual void axpy( const Real alpha, const Vector &x ) {
120  ROL::Ptr<Vector> ax = x.clone();
121  ax->set(x);
122  ax->scale(alpha);
123  this->plus(*ax);
124  }
125 
133  virtual void zero() {
134  this->scale( (Real)0 );
135  }
136 
137 
148  virtual ROL::Ptr<Vector> basis( const int i ) const {
149  ROL_UNUSED(i);
150  return ROL::nullPtr;
151  }
152 
153 
162  virtual int dimension() const {return 0;}
163 
164 
175  virtual void set( const Vector &x ) {
176  this->zero();
177  this->plus(x);
178  }
179 
180 
192  virtual const Vector & dual() const {
193  return *this;
194  }
195 
204  virtual Real apply(const Vector<Real> &x) const {
205  return this->dot(x.dual());
206  }
207 
208  virtual void applyUnary( const Elementwise::UnaryFunction<Real> &f ) {
209  ROL_UNUSED(f);
210  ROL_TEST_FOR_EXCEPTION( true, std::logic_error,
211  "The method applyUnary was called, but not implemented" << std::endl);
212  }
213 
214  virtual void applyBinary( const Elementwise::BinaryFunction<Real> &f, const Vector &x ) {
215  ROL_UNUSED(f);
216  ROL_UNUSED(x);
217  ROL_TEST_FOR_EXCEPTION( true, std::logic_error,
218  "The method applyBinary was called, but not implemented" << std::endl);
219  }
220 
221  virtual Real reduce( const Elementwise::ReductionOp<Real> &r ) const {
222  ROL_UNUSED(r);
223  ROL_TEST_FOR_EXCEPTION( true, std::logic_error,
224  "The method reduce was called, but not implemented" << std::endl);
225  }
226 
227  virtual void print( std::ostream &outStream ) const {
228  outStream << "The method print was called, but not implemented" << std::endl;
229  }
230 
241  virtual void setScalar( const Real C ) {
242  this->applyUnary(Elementwise::Fill<Real>(C));
243  }
244 
258  virtual void randomize( const Real l = 0.0, const Real u = 1.0 ) {
259  Elementwise::UniformlyRandom<Real> ur(l,u);
260  this->applyUnary(ur);
261  }
262 
291  virtual std::vector<Real> checkVector( const Vector<Real> &x,
292  const Vector<Real> &y,
293  const bool printToStream = true,
294  std::ostream & outStream = std::cout ) const {
295  Real zero = 0.0;
296  Real one = 1.0;
297  Real a = 1.234;
298  Real b = -0.4321;
299  int width = 94;
300  std::vector<Real> vCheck;
301 
302  ROL::nullstream bhs; // outputs nothing
303 
304  ROL::Ptr<std::ostream> pStream;
305  if (printToStream) {
306  pStream = ROL::makePtrFromRef(outStream);
307  } else {
308  pStream = ROL::makePtrFromRef(bhs);
309  }
310 
311  // Save the format state of the original pStream.
312  ROL::nullstream oldFormatState, headerFormatState;
313  oldFormatState.copyfmt(*pStream);
314 
315  ROL::Ptr<Vector> v = this->clone();
316  ROL::Ptr<Vector> vtmp = this->clone();
317  ROL::Ptr<Vector> xtmp = x.clone();
318  ROL::Ptr<Vector> ytmp = y.clone();
319 
320  *pStream << "\n" << std::setw(width) << std::left << std::setfill('*') << "********** Begin verification of linear algebra. " << "\n\n";
321  headerFormatState.copyfmt(*pStream);
322 
323  // Commutativity of addition.
324  v->set(*this); xtmp->set(x); ytmp->set(y);
325  v->plus(x); xtmp->plus(*this); v->axpy(-one, *xtmp); vCheck.push_back(v->norm());
326  *pStream << std::scientific << std::setprecision(12) << std::setfill('>');
327  *pStream << std::setw(width) << std::left << "Commutativity of addition. Consistency error: " << " " << vCheck.back() << "\n";
328 
329  // Associativity of addition.
330  v->set(*this); xtmp->set(x); ytmp->set(y);
331  ytmp->plus(x); v->plus(*ytmp); xtmp->plus(*this); xtmp->plus(y); v->axpy(-one, *xtmp); vCheck.push_back(v->norm());
332  *pStream << std::setw(width) << std::left << "Associativity of addition. Consistency error: " << " " << vCheck.back() << "\n";
333 
334  // Identity element of addition.
335  v->set(*this); xtmp->set(x); ytmp->set(y);
336  v->zero(); v->plus(x); v->axpy(-one, x); vCheck.push_back(v->norm());
337  *pStream << std::setw(width) << std::left << "Identity element of addition. Consistency error: " << " " << vCheck.back() << "\n";
338 
339  // Inverse elements of addition.
340  v->set(*this); xtmp->set(x); ytmp->set(y);
341  v->scale(-one); v->plus(*this); vCheck.push_back(v->norm());
342  *pStream << std::setw(width) << std::left << "Inverse elements of addition. Consistency error: " << " " << vCheck.back() << "\n";
343 
344  // Identity element of scalar multiplication.
345  v->set(*this); xtmp->set(x); ytmp->set(y);
346  v->scale(one); v->axpy(-one, *this); vCheck.push_back(v->norm());
347  *pStream << std::setw(width) << std::left << "Identity element of scalar multiplication. Consistency error: " << " " << vCheck.back() << "\n";
348 
349  // Consistency of scalar multiplication with field multiplication.
350  v->set(*this); vtmp->set(*this);
351  v->scale(b); v->scale(a); vtmp->scale(a*b); v->axpy(-one, *vtmp); vCheck.push_back(v->norm());
352  *pStream << std::setw(width) << std::left << "Consistency of scalar multiplication with field multiplication. Consistency error: " << " " << vCheck.back() << "\n";
353 
354  // Distributivity of scalar multiplication with respect to field addition.
355  v->set(*this); vtmp->set(*this);
356  v->scale(a+b); vtmp->scale(a); vtmp->axpy(b, *this); v->axpy(-one, *vtmp); vCheck.push_back(v->norm());
357  *pStream << std::setw(width) << std::left << "Distributivity of scalar multiplication with respect to field addition. Consistency error: " << " " << vCheck.back() << "\n";
358 
359  // Distributivity of scalar multiplication with respect to vector addition.
360  v->set(*this); xtmp->set(x); ytmp->set(y);
361  v->plus(x); v->scale(a); xtmp->scale(a); xtmp->axpy(a, *this); v->axpy(-one, *xtmp); vCheck.push_back(v->norm());
362  *pStream << std::setw(width) << std::left << "Distributivity of scalar multiplication with respect to vector addition. Consistency error: " << " " << vCheck.back() << "\n";
363 
364  // Commutativity of dot (inner) product over the field of reals.
365  vCheck.push_back(std::abs(this->dot(x) - x.dot(*this)));
366  *pStream << std::setw(width) << std::left << "Commutativity of dot (inner) product over the field of reals. Consistency error: " << " " << vCheck.back() << "\n";
367 
368  // Additivity of dot (inner) product.
369  xtmp->set(x);
370  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}));
371  *pStream << std::setw(width) << std::left << "Additivity of dot (inner) product. Consistency error: " << " " << vCheck.back() << "\n";
372 
373  // Consistency of scalar multiplication and norm.
374  v->set(*this);
375  Real vnorm = v->norm();
376  if (vnorm == zero) {
377  v->scale(a);
378  vCheck.push_back(std::abs(v->norm() - zero));
379  } else {
380  v->scale(one/vnorm);
381  vCheck.push_back(std::abs(v->norm() - one));
382  }
383  *pStream << std::setw(width) << std::left << "Consistency of scalar multiplication and norm. Consistency error: " << " " << vCheck.back() << "\n";
384 
385  // Reflexivity.
386  v->set(*this);
387  xtmp = ROL::constPtrCast<Vector>(ROL::makePtrFromRef(this->dual()));
388  ytmp = ROL::constPtrCast<Vector>(ROL::makePtrFromRef(xtmp->dual()));
389  v->axpy(-one, *ytmp); vCheck.push_back(v->norm());
390  *pStream << std::setw(width) << std::left << "Reflexivity. Consistency error: " << " " << vCheck.back() << "\n";
391 
392  // Consistency of apply and dual.
393  v->set(*this);
394  xtmp = x.dual().clone(); xtmp->set(x.dual());
395  Real vx = v->apply(*xtmp);
396  Real vxd = v->dot(xtmp->dual());
397  Real vdx = xtmp->dot(v->dual());
398  if (vx == zero) {
399  vCheck.push_back(std::max(std::abs(vx-vxd),std::abs(vx-vdx)));
400  }
401  else {
402  vCheck.push_back(std::max(std::abs(vx-vxd),std::abs(vx-vdx))/std::abs(vx));
403  }
404  *pStream << std::setw(width) << std::left << "Consistency of apply and dual:" << " " << vCheck.back() << "\n\n";
405 
406  //*pStream << "************ End verification of linear algebra.\n\n";
407 
408  // Restore format state of pStream used for the header info.
409  pStream->copyfmt(headerFormatState);
410  *pStream << std::setw(width) << std::left << "********** End verification of linear algebra. " << "\n\n";
411 
412  // Restore format state of the original pStream.
413  pStream->copyfmt(oldFormatState);
414 
415  return vCheck;
416  }
417 
418 }; // class Vector
419 
420 } // namespace ROL
421 
422 #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:192
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:162
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
Definition: ROL_Vector.hpp:204
virtual ROL::Ptr< Vector > basis(const int i) const
Return i-th basis vector.
Definition: ROL_Vector.hpp:148
virtual void plus(const Vector &x)=0
Compute , where .
virtual void print(std::ostream &outStream) const
Definition: ROL_Vector.hpp:227
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:119
virtual Real reduce(const Elementwise::ReductionOp< Real > &r) const
Definition: ROL_Vector.hpp:221
virtual void applyBinary(const Elementwise::BinaryFunction< Real > &f, const Vector &x)
Definition: ROL_Vector.hpp:214
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:258
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:291
virtual void zero()
Set to zero vector.
Definition: ROL_Vector.hpp:133
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
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:14
basic_nullstream< char, std::char_traits< char >> nullstream
Definition: ROL_Stream.hpp:36
virtual ~Vector()
Definition: ROL_Vector.hpp:53
virtual void setScalar(const Real C)
Set where .
Definition: ROL_Vector.hpp:241
virtual void applyUnary(const Elementwise::UnaryFunction< Real > &f)
Definition: ROL_Vector.hpp:208
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
virtual Real norm() const =0
Returns where .