ROL
ROL_MultiVectorDefault.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 
50 #ifndef ROL_MULTIVECTOR_DEFAULT_HPP
51 #define ROL_MULTIVECTOR_DEFAULT_HPP
52 
53 #include "ROL_MultiVector.hpp"
54 
55 namespace ROL {
56 
57 template<class Real>
58 class MultiVectorDefault : public MultiVector<Real> {
59 
60  typedef Vector<Real> V; // Single vector
61  typedef Teuchos::RCP<V> PV; // Pointer to a vector
62  typedef Teuchos::ArrayRCP<PV> APV; // Array of pointers to vectors
63  typedef MultiVector<Real> MV; // Instance of this class
64  typedef Teuchos::RCP<MV> PMV; // Pointer to an instance of this class
65 
66  private:
67  APV mvec_; // Array of pointers to vectors
68  int numVectors_; // number of vectors (elements in the array)
69  int length_; // number of elements in a vector
70 
71  virtual bool dimensionMismatch(const MV &A) const {
72 
73  bool equalWidth = ( A.getNumberOfVectors() != numVectors_ );
74  bool equalLength = ( A.getLength() != length_ );
75  return ( equalWidth | equalLength );
76  }
77 
78  public:
79 
80  // Create a MultiVector from an array of pointers to vectors
81  MultiVectorDefault(APV mvec) : mvec_(mvec),
82  numVectors_(mvec.size()),
83  length_(mvec[0]->dimension()) {}
84 
85  // Create a MultiVector from a pointer to a single vector
86  MultiVectorDefault(PV vec) : mvec_(APV(1,vec)),
87  numVectors_(1),
88  length_(vec->dimension()) {}
89 
90  // Create a MultiVector from a pointer to a constant vector
91 
93 
94  // Make a new MultiVector of the same dimensions
95  PMV clone() const {
96  APV x(numVectors_);
97  for(int i=0;i<numVectors_;++i) {
98  x[i] = mvec_[i]->clone();
99  }
100  return Teuchos::rcp(new MultiVectorDefault<Real>(x));
101  }
102 
103  // Make a new MultiVector of specified dimension
104  PMV clone( const int numvecs ) const {
105  APV x(numvecs);
106 
107  for(int i=0;i<numvecs;++i) {
108  x[i] = mvec_[0]->clone();
109  }
110  return Teuchos::rcp(new MultiVectorDefault<Real>(x));
111  }
112 
113 
114 
115 
116  // Make a deep copy of this MultiVector
117  PMV deepCopy() const {
118  APV x(numVectors_);
119  for(int i=0;i<numVectors_;++i) {
120  x[i] = mvec_[i]->clone();
121  x[i]->set(*mvec_[i]);
122  }
123  return Teuchos::rcp(new MultiVectorDefault<Real>(x));
124  }
125 
126  // Make a deep copy specified vectors in the MultiVector
127  PMV deepCopy(const std::vector<int> &index) const {
128  int n = index.size();
129  APV x(n);
130  for(int i=0;i<n;++i) {
131  int j = index[i];
132  x[i] = mvec_[j]->clone();
133  x[i]->set(*mvec_[j]);
134  }
135  return Teuchos::rcp(new MultiVectorDefault<Real>(x));
136  }
137 
138  // Make a shallow copy specified vectors in the MultiVector
139  PMV shallowCopy(const std::vector<int> &index) {
140  int n = index.size();
141  APV x(n);
142  for(int i=0;i<n;++i) {
143  int j = index[i];
144  x[i] = mvec_[j];
145  }
146  return Teuchos::rcp(new MultiVectorDefault<Real>(x));
147  }
148 
149  // Make a const shallow copy specified vectors in the MultiVector
150  const PMV shallowCopyConst(const std::vector<int> &index) const {
151  int n = index.size();
152  APV x(n);
153  for(int i=0;i<n;++i) {
154  int j = index[i];
155  x[i] = mvec_[j];
156  }
157  return Teuchos::rcp(new MultiVectorDefault<Real>(x));
158  }
159 
160  // Get the number of elements of a vector in the MultiVector
161  ptrdiff_t getLength() const {
162  return length_;
163  }
164 
165  // Get the number of vectors in the MultiVector
166  int getNumberOfVectors() const {
167  return numVectors_;
168  }
169 
170  void axpy(const Real alpha, const MV& x) {
171  for(int i=0;i<numVectors_;++i) {
172  mvec_[i]->axpy(alpha,*(x.getVector(i)));
173  }
174  }
175 
176  // Generic BLAS level 3 matrix multiplication
177  // \f$\text{this}\leftarrow \alpha A B+\beta\text{this}\f$
178  void gemm(const Real alpha,
179  const MV& A,
180  const Teuchos::SerialDenseMatrix<int,Real> &B,
181  const Real beta) {
182 
183  // Scale this by beta
184  this->scale(beta);
185 
186  for(int i=0;i<B.numRows();++i) {
187  for(int j=0;j<B.numCols();++j) {
188  mvec_[j]->axpy(alpha*B(i,j),*A.getVector(i));
189  }
190  }
191  }
192 
193  // Scale the MultiVector by a single scalar alpha
194  // \f$\text{this}\leftarrow\alpha\text{this}\f$
195  void scale(const Real alpha) {
196  for(int i=0;i<numVectors_;++i) {
197  mvec_[i]->scale(alpha);
198  }
199  }
200 
201  // Scale each vector in the MultiVector by a different alpha
202  // \f$\text{this}[i]\leftarrow\alpha[i]\text{this}[i]\f$
203  void scale(const std::vector<Real> &alpha) {
204 
205  TEUCHOS_TEST_FOR_EXCEPTION( static_cast<int>(alpha.size()) != numVectors_,
206  std::invalid_argument,
207  "Error: alpha must have the same length as the number of vectors.");
208 
209  for(int i=0;i<numVectors_;++i) {
210  mvec_[i]->scale(alpha[i]);
211  }
212  }
213 
214  // Set the MultiVector equal to another MultiVector
215  void set(const MV &A) {
216 
217 // TEUCHOS_TEST_FOR_EXCEPTION( this->dimensionMismatch(A),
218 // std::invalid_argument,
219 // "Error: MultiVectors must have the same dimensions.");
220 
221  for(int i=0;i<numVectors_;++i) {
222  mvec_[i]->set(*(A.getVector(i)));
223  }
224  }
225 
226 
227  // Set some of the vectors in this MultiVector equal to corresponding
228  // vectors in another MultiVector
229  void set(const MV &A, const std::vector<int> &index) {
230 
231 // TEUCHOS_TEST_FOR_EXCEPTION( this->dimensionMismatch(A),
232 // std::invalid_argument,
233 // "Error: MultiVectors must have the same dimensions.");
234 
235  int n = index.size();
236 
237  for(int i=0;i<n;++i) {
238  int k = index[i];
239  if(k<numVectors_ && i<A.getNumberOfVectors()) {
240  mvec_[k]->set(*A.getVector(i));
241  }
242 
243  }
244  }
245 
246  // Compute \f$\alpha A^\top \text{this}\f$
247  void innerProducts(const Real alpha,
248  const MV &A,
249  Teuchos::SerialDenseMatrix<int,Real> &B) const {
250 
251 // TEUCHOS_TEST_FOR_EXCEPTION( this->dimensionMismatch(A),
252 // std::invalid_argument,
253 // "Error: MultiVectors must have the same dimensions.");
254 
255  for(int i=0;i<A.getNumberOfVectors();++i) {
256  for(int j=0;j<numVectors_;++j) {
257  B(i,j) = alpha*mvec_[j]->dot(*A.getVector(i));
258  }
259  }
260  }
261 
262  // Compute dot products of pairs of vectors
263  void dots(const MV &A,
264  std::vector<Real> &b) const {
265 
266  TEUCHOS_TEST_FOR_EXCEPTION( this->dimensionMismatch(A),
267  std::invalid_argument,
268  "Error: MultiVectors must have the same dimensions.");
269 
270  for(int i=0;i<numVectors_;++i) {
271  b[i] = mvec_[i]->dot(*A.getVector(i));
272  }
273  }
274 
275  // Compute the norm of each vector in the MultiVector
276  void norms(std::vector<Real> &normvec) const {
277 
278  int min = numVectors_ < static_cast<int>(normvec.size()) ? numVectors_ : normvec.size();
279 
280  for(int i=0;i<min;++i) {
281  normvec[i] = mvec_[i]->norm();
282  }
283  }
284 
285  // Zero each of the vectors in the MultiVector
286  void zero() {
287  for(int i=0;i<numVectors_;++i) {
288  mvec_[i]->zero();
289  }
290  }
291 
292  // Return a pointer to the ith vector
293  PV getVector(int i) const {
294 
295  TEUCHOS_TEST_FOR_EXCEPTION( i>=numVectors_,
296  std::invalid_argument,
297  "Error: index out of bounds");
298 
299  return mvec_[i];
300  }
301 
302 };
303 }
304 
305 
306 #endif
void scale(const std::vector< Real > &alpha)
Scale each vector in the MultiVector by a different alpha .
const PMV shallowCopyConst(const std::vector< int > &index) const
Make a shallow copy of this MultiVector.
PMV shallowCopy(const std::vector< int > &index)
Make a shallow copy of this MultiVector.
void axpy(const Real alpha, const MV &x)
Perform the axpy operation columnwise on the MultiVector where is this MultiVector.
virtual ptrdiff_t getLength() const =0
Get the number of elements of a vector in the MultiVector.
void scale(const Real alpha)
Scale the MultiVector by a single scalar alpha .
PMV deepCopy() const
Make a deep copy of this MultiVector.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:74
ptrdiff_t getLength() const
Get the number of elements of a vector in the MultiVector.
void dots(const MV &A, std::vector< Real > &b) const
Compute dot products of pairs of vectors.
void innerProducts(const Real alpha, const MV &A, Teuchos::SerialDenseMatrix< int, Real > &B) const
Compute .
Teuchos::RCP< MV > PMV
virtual bool dimensionMismatch(const MV &A) const
void zero()
Zero each of the vectors in the MultiVector.
int getNumberOfVectors() const
Get the number of vectors in the MultiVector.
PMV deepCopy(const std::vector< int > &index) const
Make a deep copy of this MultiVector.
Default implementation of the ROL::MultiVector container class.
Teuchos::ArrayRCP< PV > APV
void norms(std::vector< Real > &normvec) const
Compute the norm of each vector in the MultiVector.
PMV clone(const int numvecs) const
Make a new MultiVector of specified "width".
Teuchos::RCP< V > PV
Teuchos::ArrayRCP< PV > APV
virtual PV getVector(int i) const =0
Return a pointer to the ith vector.
virtual int getNumberOfVectors() const =0
Get the number of vectors in the MultiVector.
Provides a container and operations on multiple ROL vectors for use with other Trilinos packages whic...
void gemm(const Real alpha, const MV &A, const Teuchos::SerialDenseMatrix< int, Real > &B, const Real beta)
Generic BLAS level 3 matrix multiplication
PMV clone() const
Make a new MultiVector of the same dimensions.
PV getVector(int i) const
Return a pointer to the ith vector.