Belos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MyMultiVec.hpp
Go to the documentation of this file.
1 /*
2 // @HEADER
3 // *****************************************************************************
4 // Belos: Block Linear Solvers Package
5 //
6 // Copyright 2004-2016 NTESS and the Belos contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 */
11 
12 #ifndef MY_MULTIVECTOR_HPP
13 #define MY_MULTIVECTOR_HPP
14 
15 #include "BelosConfigDefs.hpp"
16 #include "BelosMultiVec.hpp"
17 
20 
22 
32 template <class ScalarType>
33 class MyMultiVec : public Belos::MultiVec<ScalarType>
34 {
35 public:
36 
38  MyMultiVec (const ptrdiff_t Length, const int NumberVecs) :
39  Length_ (Length),
40  NumberVecs_ (NumberVecs)
41  {
42  Check();
43 
44  data_.resize(NumberVecs);
45  ownership_.resize(NumberVecs);
46 
47  // Allocates memory to store the vectors.
48  for (int v = 0; v < NumberVecs_; ++v) {
49  data_[v] = new ScalarType[Length];
50  ownership_[v] = true;
51  }
52 
53  // Initializes all elements to zero.
54  MvInit(0.0);
55  }
56 
58  MyMultiVec(const ptrdiff_t Length, const std::vector<ScalarType*>& rhs) :
59  Length_(Length),
60  NumberVecs_(rhs.size())
61  {
62  Check();
63 
64  data_.resize(NumberVecs_);
65  ownership_.resize(NumberVecs_);
66 
67  // Copies pointers from input array, set ownership so that
68  // this memory is not free'd in the destructor
69  for (int v = 0; v < NumberVecs_; ++v) {
70  data_[v] = rhs[v];
71  ownership_[v] = false;
72  }
73  }
74 
76  MyMultiVec(const MyMultiVec& rhs) :
77  Length_(rhs.GetGlobalLength()),
79  {
80  Check();
81 
82  data_.resize(NumberVecs_);
83  ownership_.resize(NumberVecs_);
84 
85  for (int v = 0 ; v < NumberVecs_ ; ++v)
86  {
87  data_[v] = new ScalarType[Length_];
88  ownership_[v] = true;
89  }
90 
91  for (int v = 0 ; v < NumberVecs_ ; ++v)
92  {
93  for (int i = 0 ; i < Length_ ; ++i)
94  (*this)(i, v) = rhs(i, v);
95  }
96  }
97 
100  {
101  for (int v = 0 ; v < NumberVecs_ ; ++v)
102  if (ownership_[v])
103  delete[] data_[v];
104  }
105 
107  MyMultiVec* Clone(const int NumberVecs) const
108  {
109  // FIXME
110  MyMultiVec* tmp = new MyMultiVec(Length_, NumberVecs);
111 
112  // for (int v = 0 ; v < NumberVecs ; ++v)
113  // for (int i = 0 ; i < Length_ ; ++i)
114  // (*tmp)(i, v) = (*this)(i, v);
115 
116  return(tmp);
117  }
118 
119  // Returns a clone of the corrent multi-std::vector.
121  {
122  return(new MyMultiVec(*this));
123  }
124 
126  MyMultiVec* CloneCopy(const std::vector< int > &index) const
127  {
128  int size = index.size();
129  MyMultiVec* tmp = new MyMultiVec(Length_, size);
130 
131  for (size_t v = 0 ; v < index.size() ; ++v) {
132  for (int i = 0 ; i < Length_ ; ++i) {
133  (*tmp)(i, v) = (*this)(i, index[v]);
134  }
135  }
136 
137  return(tmp);
138  }
139 
141  MyMultiVec* CloneViewNonConst(const std::vector< int > &index)
142  {
143  int size = index.size();
144  std::vector<ScalarType*> values(size);
145 
146  for (size_t v = 0 ; v < index.size() ; ++v)
147  values[v] = data_[index[v]];
148 
149  return(new MyMultiVec(Length_, values));
150  }
151 
153  const MyMultiVec* CloneView (const std::vector<int>& index) const
154  {
155  int size = index.size();
156  std::vector<ScalarType*> values (size);
157 
158  for (size_t v = 0; v < index.size (); ++v) {
159  values[v] = data_[index[v]];
160  }
161 
162  return(new MyMultiVec(Length_, values));
163  }
164 
165  ptrdiff_t GetGlobalLength () const
166  {
167  return Length_;
168  }
169 
170  int GetNumberVecs () const
171  {
172  return(NumberVecs_);
173  }
174 
175  // Update *this with alpha * A * B + beta * (*this).
176  void MvTimesMatAddMv (const ScalarType alpha, const Belos::MultiVec<ScalarType> &A,
178  const ScalarType beta)
179  {
180  assert (Length_ == A.GetGlobalLength());
181  assert (B.numRows() == A.GetNumberVecs());
182  assert (B.numCols() <= NumberVecs_);
183 
184  MyMultiVec* MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
185  TEUCHOS_ASSERT(MyA != NULL);
186 
187  if ((*this)[0] == (*MyA)[0]) {
188  // If this == A, then need additional storage ...
189  // This situation is a bit peculiar but it may be required by
190  // certain algorithms.
191 
192  std::vector<ScalarType> tmp(NumberVecs_);
193 
194  for (int i = 0 ; i < Length_ ; ++i) {
195  for (int v = 0; v < A.GetNumberVecs() ; ++v) {
196  tmp[v] = (*MyA)(i, v);
197  }
198 
199  for (int v = 0 ; v < B.numCols() ; ++v) {
200  (*this)(i, v) *= beta;
201  ScalarType res = Teuchos::ScalarTraits<ScalarType>::zero();
202 
203  for (int j = 0 ; j < A.GetNumberVecs() ; ++j) {
204  res += tmp[j] * B(j, v);
205  }
206 
207  (*this)(i, v) += alpha * res;
208  }
209  }
210  }
211  else {
212  for (int i = 0 ; i < Length_ ; ++i) {
213  for (int v = 0 ; v < B.numCols() ; ++v) {
214  (*this)(i, v) *= beta;
215  ScalarType res = 0.0;
216  for (int j = 0 ; j < A.GetNumberVecs() ; ++j) {
217  res += (*MyA)(i, j) * B(j, v);
218  }
219 
220  (*this)(i, v) += alpha * res;
221  }
222  }
223  }
224  }
225 
226  // Replace *this with alpha * A + beta * B.
227  void MvAddMv (const ScalarType alpha, const Belos::MultiVec<ScalarType>& A,
228  const ScalarType beta, const Belos::MultiVec<ScalarType>& B)
229  {
230  MyMultiVec* MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
231  TEUCHOS_ASSERT(MyA != NULL);
232 
233  MyMultiVec* MyB = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(B));
234  TEUCHOS_ASSERT(MyB != NULL);
235 
236  assert (NumberVecs_ == A.GetNumberVecs());
237  assert (NumberVecs_ == B.GetNumberVecs());
238 
239  assert (Length_ == A.GetGlobalLength());
240  assert (Length_ == B.GetGlobalLength());
241 
242  for (int v = 0 ; v < NumberVecs_ ; ++v) {
243  for (int i = 0 ; i < Length_ ; ++i) {
244  (*this)(i, v) = alpha * (*MyA)(i, v) + beta * (*MyB)(i, v);
245  }
246  }
247  }
248 
249  // Replace each element of the vectors in *this with (*this)*alpha.
250  void MvScale (const ScalarType alpha)
251  {
252  for (int v = 0 ; v < NumberVecs_ ; ++v) {
253  for (int i = 0 ; i < Length_ ; ++i) {
254  (*this)(i, v) *= alpha;
255  }
256  }
257  }
258 
259  // Replace each element of the vectors in *this with (*this)*alpha[i].
260  void MvScale (const std::vector<ScalarType>& alpha)
261  {
262  assert((int)alpha.size() >= NumberVecs_);
263  for (int v = 0 ; v < NumberVecs_ ; ++v) {
264  for (int i = 0 ; i < Length_ ; ++i) {
265  (*this)(i, v) *= alpha[v];
266  }
267  }
268  }
269 
270  // Compute a dense matrix B through the matrix-matrix multiply alpha * A^H * (*this).
271  void MvTransMv (const ScalarType alpha, const Belos::MultiVec<ScalarType>& A,
273  {
274  MyMultiVec* MyA;
275  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
276  TEUCHOS_ASSERT(MyA != NULL);
277 
278  assert (A.GetGlobalLength() == Length_);
279  assert (NumberVecs_ <= B.numCols());
280  assert (A.GetNumberVecs() <= B.numRows());
281 
282  for (int v = 0 ; v < A.GetNumberVecs() ; ++v) {
283  for (int w = 0 ; w < NumberVecs_ ; ++w) {
284  ScalarType value = 0.0;
285  for (int i = 0 ; i < Length_ ; ++i) {
286  value += Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v)) * (*this)(i, w);
287  }
288  B(v, w) = alpha * value;
289  }
290  }
291  }
292 
293 
294  // Compute a std::vector b where the components are the individual dot-products, i.e.b[i] = A[i]^H*this[i] where A[i] is the i-th column of A.
295  void MvDot (const Belos::MultiVec<ScalarType>& A, std::vector<ScalarType>& b) const
296  {
297  MyMultiVec* MyA;
298  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
299  TEUCHOS_ASSERT(MyA != NULL);
300 
301  assert (NumberVecs_ <= (int)b.size());
302  assert (NumberVecs_ == A.GetNumberVecs());
303  assert (Length_ == A.GetGlobalLength());
304 
305  for (int v = 0 ; v < NumberVecs_ ; ++v) {
306  ScalarType value = 0.0;
307  for (int i = 0 ; i < Length_ ; ++i) {
308  value += (*this)(i, v) * Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v));
309  }
310  b[v] = value;
311  }
312  }
313 
314 
315  void MvNorm ( std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& normvec,
316  Belos::NormType type = Belos::TwoNorm ) const
317  {
318  assert (NumberVecs_ <= (int)normvec.size());
319 
320  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
321 
322  for (int v = 0 ; v < NumberVecs_ ; ++v) {
323  MagnitudeType value = Teuchos::ScalarTraits<MagnitudeType>::zero();
324  for (int i = 0 ; i < Length_ ; ++i) {
325  MagnitudeType val = Teuchos::ScalarTraits<ScalarType>::magnitude((*this)(i, v));
326  value += val * val;
327  }
329  }
330  }
331 
332  // Copy the vectors in A to a set of vectors in *this. The numvecs vectors in
333  // A are copied to a subset of vectors in *this indicated by the indices given
334  // in index.
335  // FIXME: not so clear what the size of A and index.size() are...
337  const std::vector<int> &index)
338  {
339  MyMultiVec* MyA;
340  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
341  TEUCHOS_ASSERT(MyA != NULL);
342 
343  assert (A.GetNumberVecs() >= (int)index.size());
344  assert (A.GetGlobalLength() == Length_);
345 
346  for (unsigned int v = 0 ; v < index.size() ; ++v) {
347  for (int i = 0 ; i < Length_ ; ++i) {
348  (*this)(i, index[v]) = (*MyA)(i, v);
349  }
350  }
351  }
352 
353  // Fill the vectors in *this with random numbers.
354  void MvRandom ()
355  {
357  Teuchos::randomSyncedMatrix( R );
358  for (int v = 0 ; v < NumberVecs_ ; ++v) {
359  for (int i = 0 ; i < Length_ ; ++i) {
360  (*this)(i, v) = R(i, v);
361  }
362  }
363  }
364 
365  // Replace each element of the vectors in *this with alpha.
366  void MvInit (const ScalarType alpha)
367  {
368  for (int v = 0 ; v < NumberVecs_ ; ++v) {
369  for (int i = 0 ; i < Length_ ; ++i) {
370  (*this)(i, v) = alpha;
371  }
372  }
373  }
374 
375  void MvPrint (std::ostream &os) const
376  {
377  os << "Object MyMultiVec" << std::endl;
378  os << "Number of rows = " << Length_ << std::endl;
379  os << "Number of vecs = " << NumberVecs_ << std::endl;
380 
381  for (int i = 0 ; i < Length_ ; ++i)
382  {
383  for (int v = 0 ; v < NumberVecs_ ; ++v)
384  os << (*this)(i, v) << " ";
385  os << std::endl;
386  }
387  }
388 
389  inline ScalarType& operator()(const int i, const int j)
390  {
391  if (j < 0 || j >= NumberVecs_) throw(-1);
392  if (i < 0 || i >= Length_) throw(-2);
393  //
394  return(data_[j][i]);
395  }
396 
397  inline const ScalarType& operator()(const int i, const int j) const
398  {
399  if (j < 0 || j >= NumberVecs_) throw(-1);
400  if (i < 0 || i >= Length_) throw(-2);
401  //
402  return(data_[j][i]);
403  }
404 
405  ScalarType* operator[](int v)
406  {
407  if (v < 0 || v >= NumberVecs_) throw(-1);
408  return(data_[v]);
409  }
410 
411  ScalarType* operator[](int v) const
412  {
413  return(data_[v]);
414  }
415 
416 private:
417  void Check()
418  {
419  if (Length_ <= 0)
420  throw("Length must be positive");
421 
422  if (NumberVecs_ <= 0)
423  throw("Number of vectors must be positive");
424  }
425 
427  const ptrdiff_t Length_;
429  const int NumberVecs_;
431  std::vector<ScalarType*> data_;
433  std::vector<bool> ownership_;
434 
435 };
436 
437 
438 #endif // MY_MULTIVECTOR_HPP
void Check()
Definition: MyMultiVec.hpp:417
void MvTransMv(const ScalarType alpha, const Belos::MultiVec< ScalarType > &A, Teuchos::SerialDenseMatrix< int, ScalarType > &B) const
Compute a dense matrix B through the matrix-matrix multiply alpha * A^T * (*this).
Definition: MyMultiVec.hpp:271
MyMultiVec(const MyMultiVec &rhs)
Copy constructor, performs a deep copy.
Definition: MyMultiVec.hpp:76
std::vector< ScalarType * > data_
Pointers to the storage of the vectors.
Definition: MyMultiVec.hpp:431
virtual int GetNumberVecs() const =0
The number of vectors (i.e., columns) in the multivector.
ScalarType & operator()(const int i, const int j)
Definition: MyMultiVec.hpp:389
ScalarType * operator[](int v) const
Definition: MyMultiVec.hpp:411
static T squareroot(T x)
void MvPrint(std::ostream &os) const
Print *this multivector to the os output stream.
Definition: MyMultiVec.hpp:375
void MvScale(const ScalarType alpha)
Scale each element of the vectors in *this with alpha.
Definition: MyMultiVec.hpp:250
~MyMultiVec()
Destructor.
Definition: MyMultiVec.hpp:99
MyMultiVec * CloneViewNonConst(const std::vector< int > &index)
Returns a view of current std::vector (shallow copy)
Definition: MyMultiVec.hpp:141
MyMultiVec(const ptrdiff_t Length, const std::vector< ScalarType * > &rhs)
Constructor with already allocated memory.
Definition: MyMultiVec.hpp:58
virtual ptrdiff_t GetGlobalLength() const =0
The number of rows in the multivector.
void MvTimesMatAddMv(const ScalarType alpha, const Belos::MultiVec< ScalarType > &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta)
Update *this with alpha * A * B + beta * (*this).
Definition: MyMultiVec.hpp:176
MyMultiVec * Clone(const int NumberVecs) const
Returns a clone of the current std::vector.
Definition: MyMultiVec.hpp:107
MyMultiVec * CloneCopy() const
Create a new MultiVec and copy contents of *this into it (deep copy).
Definition: MyMultiVec.hpp:120
Simple example of a user&#39;s defined Belos::MultiVec class.
Definition: MyMultiVec.hpp:33
static T conjugate(T a)
const MyMultiVec * CloneView(const std::vector< int > &index) const
Returns a view of current std::vector (shallow copy), const version.
Definition: MyMultiVec.hpp:153
ScalarType * operator[](int v)
Definition: MyMultiVec.hpp:405
static magnitudeType magnitude(T a)
OrdinalType numCols() const
NormType
The type of vector norm to compute.
Definition: BelosTypes.hpp:65
void MvRandom()
Fill all the vectors in *this with random numbers.
Definition: MyMultiVec.hpp:354
const int NumberVecs_
Number of multi-vectors.
Definition: MyMultiVec.hpp:429
void MvDot(const Belos::MultiVec< ScalarType > &A, std::vector< ScalarType > &b) const
Compute the dot product of each column of *this with the corresponding column of A.
Definition: MyMultiVec.hpp:295
void MvNorm(std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &normvec, Belos::NormType type=Belos::TwoNorm) const
Compute the norm of each vector in *this.
Definition: MyMultiVec.hpp:315
Interface for multivectors used by Belos&#39; linear solvers.
int GetNumberVecs() const
The number of vectors (i.e., columns) in the multivector.
Definition: MyMultiVec.hpp:170
MyMultiVec * CloneCopy(const std::vector< int > &index) const
Returns a clone copy of specified vectors.
Definition: MyMultiVec.hpp:126
#define TEUCHOS_ASSERT(assertion_test)
void MvScale(const std::vector< ScalarType > &alpha)
Scale each element of the i-th vector in *this with alpha[i].
Definition: MyMultiVec.hpp:260
const ptrdiff_t Length_
Length of the vectors.
Definition: MyMultiVec.hpp:427
Belos header file which uses auto-configuration information to include necessary C++ headers...
const ScalarType & operator()(const int i, const int j) const
Definition: MyMultiVec.hpp:397
void SetBlock(const Belos::MultiVec< ScalarType > &A, const std::vector< int > &index)
Copy the vectors in A to a set of vectors in *this.
Definition: MyMultiVec.hpp:336
std::vector< bool > ownership_
If true, then this object owns the vectors and must free them in dtor.
Definition: MyMultiVec.hpp:433
MyMultiVec(const ptrdiff_t Length, const int NumberVecs)
Constructor for a NumberVecs vectors of length Length.
Definition: MyMultiVec.hpp:38
void MvAddMv(const ScalarType alpha, const Belos::MultiVec< ScalarType > &A, const ScalarType beta, const Belos::MultiVec< ScalarType > &B)
Replace *this with alpha * A + beta * B.
Definition: MyMultiVec.hpp:227
OrdinalType numRows() const
void MvInit(const ScalarType alpha)
Replace each element of the vectors in *this with alpha.
Definition: MyMultiVec.hpp:366
Interface for multivectors used by Belos&#39; linear solvers.
ptrdiff_t GetGlobalLength() const
The number of rows in the multivector.
Definition: MyMultiVec.hpp:165