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
43namespace ROL {
44
45template <class Real>
46class Vector
47#ifdef ENABLE_PYROL
48 : public std::enable_shared_from_this<Vector<Real>>
49#endif
50{
51public:
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
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
#define ROL_UNUSED(x)
Defines the linear algebra or vector space interface.
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
virtual ~Vector()
virtual Real norm() const =0
Returns where .
virtual void set(const Vector &x)
Set where .
virtual void applyUnary(const Elementwise::UnaryFunction< Real > &f)
virtual void setScalar(const Real C)
Set where .
virtual void applyBinary(const Elementwise::BinaryFunction< Real > &f, const Vector &x)
virtual void randomize(const Real l=0.0, const Real u=1.0)
Set vector to be uniform random between [l,u].
virtual void scale(const Real alpha)=0
Compute where .
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.
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
virtual void print(std::ostream &outStream) const
virtual void plus(const Vector &x)=0
Compute , where .
virtual void zero()
Set to zero vector.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual Real reduce(const Elementwise::ReductionOp< Real > &r) const
virtual int dimension() const
Return dimension of the vector space.
virtual ROL::Ptr< Vector > basis(const int i) const
Return i-th basis vector.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
virtual Real dot(const Vector &x) const =0
Compute where .