ROL
ROL_AtomVector.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef ROL_ATOMVECTOR_H
11 #define ROL_ATOMVECTOR_H
12 
13 #include "ROL_BatchStdVector.hpp"
14 
20 namespace ROL {
21 
22 template <class Real>
24 
25 template <class Real>
27 
28 template <class Real>
29 class AtomVector : public BatchStdVector<Real> {
31 private:
32  const int numMySamples_;
33  const int dimension_;
34 
35 public:
36  AtomVector(const ROL::Ptr<std::vector<Real> > &vec,
37  const ROL::Ptr<BatchManager<Real> > &bman,
38  const int numMySamples, const int dimension)
39  : BatchStdVector<Real>(vec,bman),
40  numMySamples_(numMySamples), dimension_(dimension) {}
41 
42  ROL::Ptr<const std::vector<Real> > getAtom(const int i) const {
43  ROL_TEST_FOR_EXCEPTION((i < 0 || i > numMySamples_), std::invalid_argument,
44  ">>> ERROR (ROL::AtomVector): index out of bounds in getAtom!");
45  uint dim = static_cast<uint>(dimension_), I = static_cast<uint>(i);
46  std::vector<Real> pt(dim,0);
47  const std::vector<Real> &yval = *(StdVector<Real>::getVector());
48  for (uint j = 0; j < dim; ++j) {
49  pt[j] = yval[I*dim + j];
50  }
51  return ROL::makePtr<std::vector<Real>>(pt);
52  }
53 
54  void setAtom(const int i, const std::vector<Real> &pt) {
55  ROL_TEST_FOR_EXCEPTION((i < 0 || i > numMySamples_), std::invalid_argument,
56  ">>> ERROR (ROL::AtomVector): index out of bounds in setAtom!");
57  uint dim = static_cast<uint>(dimension_), I = static_cast<uint>(i);
58  std::vector<Real> &yval = *(StdVector<Real>::getVector());
59  for (uint j = 0; j < dim; ++j) {
60  yval[I*dim + j] = pt[j];
61  }
62  }
63 
64  int getNumMyAtoms(void) const {
65  return numMySamples_;
66  }
67 
68  int getDimension(void) const {
69  return dimension_;
70  }
71 };
72 
73 template<class Real>
74 class PrimalAtomVector : public AtomVector<Real> {
76 private:
77  const ROL::Ptr<std::vector<Real> > scale_;
78  mutable ROL::Ptr<DualAtomVector<Real> > dual_vec_;
79  mutable bool isDualInitialized_;
80 
81 public:
82  PrimalAtomVector(const ROL::Ptr<std::vector<Real> > &vec,
83  const ROL::Ptr<BatchManager<Real> > &bman,
84  const int numMySamples, const int dimension,
85  const ROL::Ptr<std::vector<Real> > &scale)
86  : AtomVector<Real>(vec,bman,numMySamples,dimension),
87  scale_(scale), isDualInitialized_(false) {}
88 
89  Real dot(const Vector<Real> &x) const {
90  const std::vector<Real> &xval = *(dynamic_cast<const StdVector<Real>&>(x).getVector());
91  const std::vector<Real> &yval = *(StdVector<Real>::getVector());
92  uint ysize = yval.size();
93  ROL_TEST_FOR_EXCEPTION( xval.size() != ysize, std::invalid_argument,
94  "Error: Vectors must have the same dimension." );
95  uint index = 0;
96  uint numMySamples = static_cast<uint>(AtomVector<Real>::getNumMyAtoms());
98  Real val(0), sum_val(0);
99  for (uint i = 0; i < numMySamples; i++) {
100  for (uint j = 0; j < dimension; j++) {
101  index = i*dimension + j;
102  val += xval[index] * (*scale_)[index] * yval[index];
103  }
104  }
105  // Global sum
106  BatchStdVector<Real>::getBatchManager()->sumAll(&val,&sum_val,1);
107  return sum_val;
108  }
109 
110  ROL::Ptr<Vector<Real> > clone(void) const {
111  uint numMySamples = static_cast<uint>(AtomVector<Real>::getNumMyAtoms());
113  return ROL::makePtr<PrimalAtomVector>(
114  ROL::makePtr<std::vector<Real>>(numMySamples*dimension),
116  numMySamples,dimension,scale_);
117  }
118 
119  const Vector<Real> & dual(void) const {
120  uint numMySamples = static_cast<uint>(AtomVector<Real>::getNumMyAtoms());
122  if ( !isDualInitialized_ ) {
123  dual_vec_ = ROL::makePtr<DualAtomVector<Real>>(
124  ROL::makePtr<std::vector<Real>>(numMySamples*dimension),
126  numMySamples,dimension,scale_);
127  isDualInitialized_ = true;
128  }
129  uint index = 0;
130  for (uint i = 0; i < numMySamples; i++) {
131  for (uint j = 0; j < dimension; j++) {
132  index = i*dimension + j;
133  (*(dual_vec_->getVector()))[index]
134  = (*scale_)[index] * (*(StdVector<Real>::getVector()))[index];
135  }
136  }
137  return *dual_vec_;
138  }
139 };
140 
141 template<class Real>
142 class DualAtomVector : public AtomVector<Real> {
144 private:
145  const ROL::Ptr<std::vector<Real> > scale_;
146  mutable ROL::Ptr<PrimalAtomVector<Real> > primal_vec_;
147  mutable bool isDualInitialized_;
148 
149 public:
150  DualAtomVector(const ROL::Ptr<std::vector<Real> > &vec,
151  const ROL::Ptr<BatchManager<Real> > &bman,
152  const int numMySamples, const int dimension,
153  const ROL::Ptr<std::vector<Real> > &scale)
154  : AtomVector<Real>(vec,bman,numMySamples,dimension),
155  scale_(scale), isDualInitialized_(false) {}
156 
157  Real dot(const Vector<Real> &x) const {
158  const std::vector<Real> &xval = *(dynamic_cast<const StdVector<Real>&>(x).getVector());
159  const std::vector<Real> &yval = *(StdVector<Real>::getVector());
160  uint ysize = yval.size();
161  ROL_TEST_FOR_EXCEPTION( xval.size() != ysize, std::invalid_argument,
162  "Error: Vectors must have the same dimension." );
163  uint index = 0;
164  uint numMySamples = static_cast<uint>(AtomVector<Real>::getNumMyAtoms());
166  Real val(0), sum_val(0);
167  for (uint i = 0; i < numMySamples; i++) {
168  for (uint j = 0; j < dimension; j++) {
169  index = i*dimension + j;
170  val += xval[index] * yval[index] / (*scale_)[index];
171  }
172  }
173  // Global sum
174  BatchStdVector<Real>::getBatchManager()->sumAll(&val,&sum_val,1);
175  return sum_val;
176  }
177 
178  ROL::Ptr<Vector<Real> > clone(void) const {
179  uint numMySamples = static_cast<uint>(AtomVector<Real>::getNumMyAtoms());
181  return ROL::makePtr<DualAtomVector>(
182  ROL::makePtr<std::vector<Real>>(numMySamples*dimension),
184  numMySamples,dimension,scale_);
185  }
186 
187  const Vector<Real> & dual(void) const {
188  uint numMySamples = static_cast<uint>(AtomVector<Real>::getNumMyAtoms());
190  if ( !isDualInitialized_ ) {
191  primal_vec_ = ROL::makePtr<PrimalAtomVector<Real>>(
192  ROL::makePtr<std::vector<Real>>(numMySamples*dimension),
194  numMySamples,dimension,scale_);
195  isDualInitialized_ = true;
196  }
197  uint index = 0;
198  for (uint i = 0; i < numMySamples; i++) {
199  for (uint j = 0; j < dimension; j++) {
200  index = i*dimension + j;
201  (*(primal_vec_->getVector()))[index]
202  = (*(StdVector<Real>::getVector()))[index] / (*scale_)[index];
203  }
204  }
205  return *primal_vec_;
206  }
207 };
208 
209 } // namespace ROL
210 
211 #endif
const ROL::Ptr< std::vector< Real > > scale_
std::vector< Real >::size_type uint
typename PV< Real >::size_type size_type
void scale(const Real alpha)
Compute where .
Provides the std::vector implementation of the ROL::Vector interface.
int getDimension(void) const
ROL::Ptr< const std::vector< Real > > getAtom(const int i) const
Provides the std::vector implementation of the ROL::Vector interface.
void setAtom(const int i, const std::vector< Real > &pt)
Real dot(const Vector< Real > &x) const
Compute where .
Ptr< const std::vector< Element > > getVector() const
ROL::Ptr< Vector< Real > > clone(void) const
Clone to make a new (uninitialized) vector.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
const Vector< Real > & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
std::vector< Real >::size_type uint
AtomVector(const ROL::Ptr< std::vector< Real > > &vec, const ROL::Ptr< BatchManager< Real > > &bman, const int numMySamples, const int dimension)
ROL::Ptr< Vector< Real > > clone(void) const
Clone to make a new (uninitialized) vector.
const Vector< Real > & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Real dot(const Vector< Real > &x) const
Compute where .
const int numMySamples_
const Ptr< BatchManager< Real > > getBatchManager(void) const
int getNumMyAtoms(void) const
DualAtomVector(const ROL::Ptr< std::vector< Real > > &vec, const ROL::Ptr< BatchManager< Real > > &bman, const int numMySamples, const int dimension, const ROL::Ptr< std::vector< Real > > &scale)
PrimalAtomVector(const ROL::Ptr< std::vector< Real > > &vec, const ROL::Ptr< BatchManager< Real > > &bman, const int numMySamples, const int dimension, const ROL::Ptr< std::vector< Real > > &scale)
const ROL::Ptr< std::vector< Real > > scale_
std::vector< Real >::size_type uint
ROL::Ptr< PrimalAtomVector< Real > > primal_vec_
int dimension(void) const
Return dimension of the vector space.
constexpr auto dim
ROL::Ptr< DualAtomVector< Real > > dual_vec_
const int dimension_