ROL
ROL_PartitionedVector.hpp
Go to the documentation of this file.
1// @HEADER
2// ************************************************************************
3//
4// Rapid Optimization Library (ROL) Package
5// Copyright (2014) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact lead developers:
38// Drew Kouri (dpkouri@sandia.gov) and
39// Denis Ridzal (dridzal@sandia.gov)
40//
41// ************************************************************************
42// @HEADER
43
44#include "ROL_Vector.hpp"
45
46#include <initializer_list>
47
48#ifndef ROL_PARTITIONED_VECTOR_H
49#define ROL_PARTITIONED_VECTOR_H
50
57namespace ROL {
58
59template<class Real>
60class PartitionedVector : public Vector<Real> {
61
62 typedef Vector<Real> V;
63 typedef ROL::Ptr<V> Vp;
65
66private:
67 const std::vector<Vp> vecs_;
68 mutable std::vector<Vp> dual_vecs_;
69 mutable ROL::Ptr<PV> dual_pvec_;
70public:
71
72 typedef typename std::vector<PV>::size_type size_type;
73
74 PartitionedVector( const std::vector<Vp> &vecs ) : vecs_(vecs) {
75 for( size_type i=0; i<vecs_.size(); ++i ) {
76 dual_vecs_.push_back((vecs_[i]->dual()).clone());
77 }
78 }
79
80 void set( const V &x ) {
81 const PV &xs = dynamic_cast<const PV&>(x);
82 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
83 std::invalid_argument,
84 "Error: Vectors must have the same number of subvectors." );
85 for( size_type i=0; i<vecs_.size(); ++i ) {
86 vecs_[i]->set(*xs.get(i));
87 }
88 }
89
90 void plus( const V &x ) {
91 const PV &xs = dynamic_cast<const PV&>(x);
92 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
93 std::invalid_argument,
94 "Error: Vectors must have the same number of subvectors." );
95 for( size_type i=0; i<vecs_.size(); ++i ) {
96 vecs_[i]->plus(*xs.get(i));
97 }
98 }
99
100 void scale( const Real alpha ) {
101 for( size_type i=0; i<vecs_.size(); ++i ) {
102 vecs_[i]->scale(alpha);
103 }
104 }
105
106 void axpy( const Real alpha, const V &x ) {
107 const PV &xs = dynamic_cast<const PV&>(x);
108 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
109 std::invalid_argument,
110 "Error: Vectors must have the same number of subvectors." );
111
112 for( size_type i=0; i<vecs_.size(); ++i ) {
113 vecs_[i]->axpy(alpha,*xs.get(i));
114 }
115 }
116
117 Real dot( const V &x ) const {
118 const PV &xs = dynamic_cast<const PV&>(x);
119 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
120 std::invalid_argument,
121 "Error: Vectors must have the same number of subvectors." );
122 Real result = 0;
123 for( size_type i=0; i<vecs_.size(); ++i ) {
124 result += vecs_[i]->dot(*xs.get(i));
125 }
126 return result;
127 }
128
129 Real norm() const {
130 Real result = 0;
131 for( size_type i=0; i<vecs_.size(); ++i ) {
132 result += std::pow(vecs_[i]->norm(),2);
133 }
134 return std::sqrt(result);
135 }
136
137 Vp clone() const {
138 std::vector<Vp> clonevec;
139 for( size_type i=0; i<vecs_.size(); ++i ) {
140 clonevec.push_back(vecs_[i]->clone());
141 }
142 return ROL::makePtr<PV>(clonevec);
143 }
144
145 const V& dual(void) const {
146 for( size_type i=0; i<vecs_.size(); ++i ) {
147 dual_vecs_[i]->set(vecs_[i]->dual());
148 }
149 dual_pvec_ = ROL::makePtr<PV>( dual_vecs_ );
150 return *dual_pvec_;
151 }
152
153 Real apply(const Vector<Real> &x) const {
154 const PV &xs = dynamic_cast<const PV&>(x);
155 ROL_TEST_FOR_EXCEPTION( numVectors() != xs.numVectors(),
156 std::invalid_argument,
157 "Error: Vectors must have the same number of subvectors." );
158 Real result = 0;
159 for( size_type i=0; i<vecs_.size(); ++i ) {
160 result += vecs_[i]->apply(*xs.get(i));
161 }
162 return result;
163 }
164
165 Vp basis( const int i ) const {
166 ROL_TEST_FOR_EXCEPTION( i >= dimension() || i<0,
167 std::invalid_argument,
168 "Error: Basis index must be between 0 and vector dimension." );
169 Vp bvec = clone();
170 // Downcast
171 PV &eb = dynamic_cast<PV&>(*bvec);
172
173 // Iterate over subvectors
174 int begin = 0, end = 0;
175 for( size_type j=0; j<vecs_.size(); ++j ) {
176 end += vecs_[j]->dimension();
177 if( begin<= i && i<end ) {
178 eb.set(j, *(vecs_[j]->basis(i-begin)) );
179 }
180 else {
181 eb.zero(j);
182 }
183 begin = end;
184 }
185 return bvec;
186 }
187
188 int dimension() const {
189 int total_dim = 0;
190 for( size_type j=0; j<vecs_.size(); ++j ) {
191 total_dim += vecs_[j]->dimension();
192 }
193 return total_dim;
194 }
195
196 void zero() {
197 for( size_type j=0; j<vecs_.size(); ++j ) {
198 vecs_[j]->zero();
199 }
200 }
201
202 // Apply the same unary function to each subvector
203 void applyUnary( const Elementwise::UnaryFunction<Real> &f ) {
204 for( size_type i=0; i<vecs_.size(); ++i ) {
205 vecs_[i]->applyUnary(f);
206 }
207 }
208
209 // Apply the same binary function to each pair of subvectors in this vector and x
210 void applyBinary( const Elementwise::BinaryFunction<Real> &f, const V &x ) {
211 const PV &xs = dynamic_cast<const PV&>(x);
212
213 for( size_type i=0; i<vecs_.size(); ++i ) {
214 vecs_[i]->applyBinary(f,*xs.get(i));
215 }
216 }
217
218 Real reduce( const Elementwise::ReductionOp<Real> &r ) const {
219 Real result = r.initialValue();
220
221 for( size_type i=0; i<vecs_.size(); ++i ) {
222 r.reduce(vecs_[i]->reduce(r),result);
223 }
224 return result;
225 }
226
227 void setScalar( const Real C ) {
228 for (size_type i=0; i<vecs_.size(); ++i) {
229 vecs_[i]->setScalar(C);
230 }
231 }
232
233 void randomize( const Real l = 0.0, const Real u = 1.0 ) {
234 for (size_type i=0; i<vecs_.size(); ++i) {
235 vecs_[i]->randomize(l,u);
236 }
237 }
238
239 void print( std::ostream &outStream ) const {
240 for( size_type i=0; i<vecs_.size(); ++i ) {
241 outStream << "V[" << i << "]: ";
242 vecs_[i]->print(outStream);
243 }
244 }
245
246 // Methods that do not exist in the base class
248 return *(vecs_[i]);
249 }
250
252 return *(vecs_[i]);
253 }
254
255 ROL::Ptr<const Vector<Real> > get(size_type i) const {
256 return vecs_[i];
257 }
258
259 ROL::Ptr<Vector<Real> > get(size_type i) {
260 return vecs_[i];
261 }
262
263 void set(size_type i, const V &x) {
264 vecs_[i]->set(x);
265 }
266
267 void zero(size_type i) {
268 vecs_[i]->zero();
269 }
270
272 return vecs_.size();
273 }
274
275public:
276
277 // Make a new PartitionedVector from an initializer_list of pointers to vectors
278 static Ptr<PartitionedVector> create( std::initializer_list<Vp> vs ) {
279 std::vector<Vp> subvecs{vs};
280 return ROL::makePtr<PartitionedVector>( subvecs );
281 }
282
283 // Make a new PartitionedVector by cloning the given vector N times
284 static Ptr<PartitionedVector> create( const V& x, size_type N ) {
285 std::vector<Vp> subvecs(N);
286 for( size_type i=0; i<N; ++i ) subvecs.at(i) = x.clone();
287 return ROL::makePtr<PartitionedVector>( subvecs );
288 }
289
290};
291
292// Helper methods
293
294template<typename Real>
296 return static_cast<PartitionedVector<Real>&>(x);
297}
298
299template<typename Real>
301 return static_cast<const PartitionedVector<Real>&>(x);
302}
303
304template<typename Real>
305inline Ptr<PartitionedVector<Real>> partition( const Ptr<Vector<Real>>& x ) {
306 return staticPtrCast<PartitionedVector<Real>>(x);
307}
308
309template<typename Real>
310inline Ptr<const PartitionedVector<Real>> partition( const Ptr<const Vector<Real>>& x ) {
311 return staticPtrCast<const PartitionedVector<Real>>(x);
312}
313
314
315
316template<class Real>
317ROL::Ptr<Vector<Real>>
318CreatePartitionedVector( const ROL::Ptr<Vector<Real>> &a ) {
319
320 using Vp = ROL::Ptr<Vector<Real>>;
322
323 Vp temp[] = {a};
324 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+1) );
325}
326
327template<class Real>
328ROL::Ptr<const Vector<Real> >
329CreatePartitionedVector( const ROL::Ptr<const Vector<Real>> &a ) {
330
331 using Vp = ROL::Ptr<const Vector<Real>>;
332 using PV = const PartitionedVector<Real>;
333
334 Vp temp[] = {a};
335 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+1) );
336}
337
338template<class Real>
339ROL::Ptr<Vector<Real>>
341 const ROL::Ptr<Vector<Real>> &b ) {
342 using Vp = ROL::Ptr<Vector<Real>>;
344
345 Vp temp[] = {a,b};
346 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+2) );
347}
348
349template<class Real>
350ROL::Ptr<const Vector<Real> >
351CreatePartitionedVector( const ROL::Ptr<const Vector<Real>> &a,
352 const ROL::Ptr<const Vector<Real>> &b ) {
353 using Vp = ROL::Ptr<const Vector<Real>>;
354 using PV = const PartitionedVector<Real>;
355
356 Vp temp[] = {a,b};
357 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+2) );
358}
359
360
361template<class Real>
362ROL::Ptr<Vector<Real>>
364 const ROL::Ptr<Vector<Real>> &b,
365 const ROL::Ptr<Vector<Real>> &c ) {
366
367 using Vp = ROL::Ptr<Vector<Real>>;
369
370 Vp temp[] = {a,b,c};
371 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+3) );
372}
373
374template<class Real>
375ROL::Ptr<const Vector<Real> >
376CreatePartitionedVector( const ROL::Ptr<const Vector<Real>> &a,
377 const ROL::Ptr<const Vector<Real>> &b,
378 const ROL::Ptr<const Vector<Real>> &c ) {
379
380 using Vp = ROL::Ptr<const Vector<Real>>;
381 using PV = const PartitionedVector<Real>;
382
383 Vp temp[] = {a,b,c};
384 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+3) );
385}
386
387template<class Real>
388ROL::Ptr<Vector<Real> >
390 const ROL::Ptr<Vector<Real>> &b,
391 const ROL::Ptr<Vector<Real>> &c,
392 const ROL::Ptr<Vector<Real>> &d ) {
393
394
395 typedef ROL::Ptr<Vector<Real> > Vp;
397
398 Vp temp[] = {a,b,c,d};
399 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+4) );
400}
401
402template<class Real>
403ROL::Ptr<const Vector<Real> >
404CreatePartitionedVector( const ROL::Ptr<const Vector<Real>> &a,
405 const ROL::Ptr<const Vector<Real>> &b,
406 const ROL::Ptr<const Vector<Real>> &c,
407 const ROL::Ptr<const Vector<Real>> &d ) {
408
409
410 using Vp = ROL::Ptr<const Vector<Real>>;
411 using PV = const PartitionedVector<Real>;
412
413 Vp temp[] = {a,b,c,d};
414 return ROL::makePtr<PV>( std::vector<Vp>(temp, temp+4) );
415}
416
417} // namespace ROL
418
419#endif // ROL_PARTITIONED_VECTOR_H
420
PartitionedVector< Real > PV
Defines the linear algebra of vector space on a generic partitioned vector.
void print(std::ostream &outStream) const
Vp basis(const int i) const
Return i-th basis vector.
std::vector< PV >::size_type size_type
Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
Vector< Real > & operator[](size_type i)
ROL::Ptr< const Vector< Real > > get(size_type i) const
void applyUnary(const Elementwise::UnaryFunction< Real > &f)
Real norm() const
Returns where .
void set(size_type i, const V &x)
static Ptr< PartitionedVector > create(std::initializer_list< Vp > vs)
void applyBinary(const Elementwise::BinaryFunction< Real > &f, const V &x)
void plus(const V &x)
Compute , where .
Real dot(const V &x) const
Compute where .
Vp clone() const
Clone to make a new (uninitialized) vector.
void randomize(const Real l=0.0, const Real u=1.0)
Set vector to be uniform random between [l,u].
const V & dual(void) const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
void scale(const Real alpha)
Compute where .
void setScalar(const Real C)
Set where .
PartitionedVector(const std::vector< Vp > &vecs)
const std::vector< Vp > vecs_
const Vector< Real > & operator[](size_type i) const
void axpy(const Real alpha, const V &x)
Compute where .
void set(const V &x)
Set where .
PartitionedVector< Real > PV
Real reduce(const Elementwise::ReductionOp< Real > &r) const
static Ptr< PartitionedVector > create(const V &x, size_type N)
ROL::Ptr< Vector< Real > > get(size_type i)
void zero()
Set to zero vector.
int dimension() const
Return dimension of the vector space.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:84
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
ROL::Ptr< Vector< Real > > CreatePartitionedVector(const ROL::Ptr< Vector< Real > > &a)
PartitionedVector< Real > & partition(Vector< Real > &x)