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