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
77namespace ROL {
78
79template <class Real>
80class Vector
81#ifdef ENABLE_PYROL
82 : public std::enable_shared_from_this<Vector<Real>>
83#endif
84{
85public:
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 wass 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 wass 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
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 .