MyMultiVec.cpp
1 #ifndef SELDON_FILE_MY_MULTIVEC_CPP
2 #define SELDON_FILE_MY_MULTIVEC_CPP
3 
4 namespace Anasazi
5 {
6 
7  template<class ScalarType>
8  inline int MyMultiVec<ScalarType>::GetVecLength () const
9  {
10  return(Length_);
11  }
12 
13 
14  template<class ScalarType>
15  inline int MyMultiVec<ScalarType>::GetNumberVecs () const
16  {
17  return(NumberVecs_);
18  }
19 
20  template<class ScalarType>
21  inline ptrdiff_t MyMultiVec<ScalarType>::GetGlobalLength () const
22  {
23  return(Length_);
24  }
25 
26  template<class ScalarType>
27  inline ScalarType& MyMultiVec<ScalarType>
28  ::operator()(const int i, const int j)
29  {
30  if (j < 0 || j >= NumberVecs_) throw(-1);
31  if (i < 0 || i >= Length_) throw(-2);
32  //
33  return(data_[j][i]);
34  }
35 
36 
37  template<class ScalarType>
38  inline const ScalarType& MyMultiVec<ScalarType>
39  ::operator()(const int i, const int j) const
40  {
41  if (j < 0 || j >= NumberVecs_) throw(-1);
42  if (i < 0 || i >= Length_) throw(-2);
43  //
44  return(data_[j][i]);
45  }
46 
47 
48  template<class ScalarType>
49  inline ScalarType* MyMultiVec<ScalarType>::operator[](int v)
50  {
51  if (v < 0 || v >= NumberVecs_) throw(-1);
52  return(data_[v]);
53  }
54 
55 
56  template<class ScalarType>
57  inline ScalarType* MyMultiVec<ScalarType>::operator[](int v) const
58  {
59  return(data_[v]);
60  }
61 
62 
64  template<class ScalarType>
65  MyMultiVec<ScalarType>::MyMultiVec(const int Length, const int NumberVecs)
66  : Length_(Length),
67  NumberVecs_(NumberVecs)
68  {
69  Check();
70 
71  data_.resize(NumberVecs);
72  ownership_.resize(NumberVecs);
73 
74  // Allocates memory to store the vectors.
75  for (int v = 0 ; v < NumberVecs_ ; ++v)
76  {
77  data_[v] = new ScalarType[Length];
78  ownership_[v] = true;
79  }
80 
81  // Initializes all elements to zero.
82  MvInit(0.0);
83  }
84 
85 
87  template<class ScalarType>
89  ::MyMultiVec(const int Length, const std::vector<ScalarType*>& rhs) :
90  Length_(Length),
91  NumberVecs_(rhs.size())
92  {
93  Check();
94 
95  data_.resize(NumberVecs_);
96  ownership_.resize(NumberVecs_);
97 
98  // Copies pointers from input array, set ownership so that
99  // this memory is not free'd in the destructor
100  for (int v = 0 ; v < NumberVecs_ ; ++v)
101  {
102  data_[v] = rhs[v];
103  ownership_[v] = false;
104  }
105  }
106 
107 
109  template<class ScalarType>
111  Length_(rhs.GetVecLength()),
112  NumberVecs_(rhs.NumberVecs_)
113  {
114  Check();
115 
116  data_.resize(NumberVecs_);
117  ownership_.resize(NumberVecs_);
118 
119  for (int v = 0 ; v < NumberVecs_ ; ++v)
120  {
121  data_[v] = new ScalarType[Length_];
122  ownership_[v] = true;
123  }
124 
125  for (int v = 0 ; v < NumberVecs_ ; ++v)
126  {
127  for (int i = 0 ; i < Length_ ; ++i)
128  (*this)(i, v) = rhs(i, v);
129  }
130  }
131 
132 
134  template<class ScalarType>
136  {
137  for (int v = 0 ; v < NumberVecs_ ; ++v)
138  if (ownership_[v])
139  delete[] data_[v];
140  }
141 
142 
144  template<class ScalarType>
146  {
147  // FIXME
148  MyMultiVec<ScalarType>* tmp = new MyMultiVec<ScalarType>(Length_, NumberVecs);
149 
150  // for (int v = 0 ; v < NumberVecs ; ++v)
151  // for (int i = 0 ; i < Length_ ; ++i)
152  // (*tmp)(i, v) = (*this)(i, v);
153 
154  return(tmp);
155  }
156 
157 
158  // Returns a clone of the corrent multi-vector.
159  template<class ScalarType>
161  {
162  return(new MyMultiVec<ScalarType>(*this));
163  }
164 
165 
167  template<class ScalarType>
168  MyMultiVec<ScalarType>* MyMultiVec<ScalarType>::CloneCopy(const std::vector< int > &index) const
169  {
170  int size = index.size();
171  MyMultiVec<ScalarType>* tmp = new MyMultiVec<ScalarType>(Length_, size);
172 
173  for (unsigned int v = 0 ; v < index.size() ; ++v)
174  for (int i = 0 ; i < Length_ ; ++i)
175  (*tmp)(i, v) = (*this)(i, index[v]);
176 
177  return(tmp);
178  }
179 
180 
182  template<class ScalarType>
184  ::CloneViewNonConst(const std::vector< int > &index)
185  {
186  int size = index.size();
187  std::vector<ScalarType*> values(size);
188 
189  for (unsigned int v = 0 ; v < index.size() ; ++v)
190  values[v] = data_[index[v]];
191 
192  return(new MyMultiVec<ScalarType>(Length_, values));
193  }
194 
195 
197  template<class ScalarType>
199  ::CloneView(const std::vector< int > &index) const
200  {
201  int size = index.size();
202  std::vector<ScalarType*> values(size);
203 
204  for (unsigned int v = 0 ; v < index.size() ; ++v)
205  values[v] = data_[index[v]];
206 
207  return(new MyMultiVec<ScalarType>(Length_, values));
208  }
209 
210 
211  // Update *this with alpha * A * B + beta * (*this).
212  template<class ScalarType>
214  ::MvTimesMatAddMv(ScalarType alpha, const Anasazi::MultiVec<ScalarType> &A,
215  const Teuchos::SerialDenseMatrix<int, ScalarType> &B,
216  ScalarType beta)
217  {
218 
219  assert (Length_ == A.GetVecLength());
220  assert (B.numRows() == A.GetNumberVecs());
221  assert (B.numCols() <= NumberVecs_);
222 
223  MyMultiVec* MyA;
224  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A));
225  assert(MyA!=NULL);
226 
227  if ((*this)[0] == (*MyA)[0]) {
228  // If this == A, then need additional storage ...
229  // This situation is a bit peculiar but it may be required by
230  // certain algorithms.
231 
232  std::vector<ScalarType> tmp(NumberVecs_);
233 
234  for (int i = 0 ; i < Length_ ; ++i) {
235  for (int v = 0; v < A.GetNumberVecs() ; ++v) {
236  tmp[v] = (*MyA)(i, v);
237  }
238 
239  for (int v = 0 ; v < B.numCols() ; ++v) {
240  (*this)(i, v) *= beta;
241  ScalarType res = Teuchos::ScalarTraits<ScalarType>::zero();
242 
243  for (int j = 0 ; j < A.GetNumberVecs() ; ++j) {
244  res += tmp[j] * B(j, v);
245  }
246 
247  (*this)(i, v) += alpha * res;
248  }
249  }
250  }
251  else {
252  for (int i = 0 ; i < Length_ ; ++i) {
253  for (int v = 0 ; v < B.numCols() ; ++v) {
254  (*this)(i, v) *= beta;
255  ScalarType res = 0.0;
256  for (int j = 0 ; j < A.GetNumberVecs() ; ++j) {
257  res += (*MyA)(i, j) * B(j, v);
258  }
259 
260  (*this)(i, v) += alpha * res;
261  }
262  }
263  }
264  }
265 
266 
267  // Replace *this with alpha * A + beta * B.
268  template<class ScalarType>
269  void MyMultiVec<ScalarType>
270  ::MvAddMv(ScalarType alpha, const Anasazi::MultiVec<ScalarType>& A,
271  ScalarType beta, const Anasazi::MultiVec<ScalarType>& B)
272  {
273  MyMultiVec* MyA;
274  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A));
275  assert (MyA != 0);
276 
277  MyMultiVec* MyB;
278  MyB = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(B));
279  assert (MyB != 0);
280 
281  assert (NumberVecs_ == A.GetNumberVecs());
282  assert (NumberVecs_ == B.GetNumberVecs());
283 
284  assert (Length_ == A.GetVecLength());
285  assert (Length_ == B.GetVecLength());
286 
287  for (int v = 0 ; v < NumberVecs_ ; ++v) {
288  for (int i = 0 ; i < Length_ ; ++i) {
289  (*this)(i, v) = alpha * (*MyA)(i, v) + beta * (*MyB)(i, v);
290  }
291  }
292  }
293 
294 
295  // Compute a dense matrix B through the matrix-matrix multiply alpha * A^H * (*this).
296  template<class ScalarType>
297  void MyMultiVec<ScalarType>
298  ::MvTransMv(ScalarType alpha, const Anasazi::MultiVec<ScalarType>& A,
299  Teuchos::SerialDenseMatrix< int, ScalarType >& B
300 #ifdef HAVE_ANASAZI_EXPERIMENTAL
301  , Anasazi::ConjType conj
302 #endif
303  ) const
304  {
305  MyMultiVec* MyA;
306  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A));
307  assert (MyA != 0);
308 
309  assert (A.GetVecLength() == Length_);
310  assert (NumberVecs_ <= B.numCols());
311  assert (A.GetNumberVecs() <= B.numRows());
312 
313 #ifdef HAVE_ANASAZI_EXPERIMENTAL
314  if (conj == Anasazi::CONJ) {
315 #endif
316  for (int v = 0 ; v < A.GetNumberVecs() ; ++v) {
317  for (int w = 0 ; w < NumberVecs_ ; ++w) {
318  ScalarType value = 0.0;
319  for (int i = 0 ; i < Length_ ; ++i) {
320  value += Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v)) * (*this)(i, w);
321  }
322  B(v, w) = alpha * value;
323  }
324  }
325 #ifdef HAVE_ANASAZI_EXPERIMENTAL
326  } else {
327  for (int v = 0 ; v < A.GetNumberVecs() ; ++v) {
328  for (int w = 0 ; w < NumberVecs_ ; ++w) {
329  ScalarType value = 0.0;
330  for (int i = 0 ; i < Length_ ; ++i) {
331  value += (*MyA)(i, v) * (*this)(i, w);
332  }
333  B(v, w) = alpha * value;
334  }
335  }
336  }
337 #endif
338  }
339 
340 
341  // Compute a 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.
342  template<class ScalarType>
343  void MyMultiVec<ScalarType>
344  ::MvDot(const Anasazi::MultiVec<ScalarType>& A, std::vector<ScalarType> &b
345 #ifdef HAVE_ANASAZI_EXPERIMENTAL
346  , Anasazi::ConjType conj
347 #endif
348  ) const
349  {
350  MyMultiVec* MyA;
351  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A));
352  assert (MyA != 0);
353 
354  assert (NumberVecs_ <= (int)b.size());
355  assert (NumberVecs_ == A.GetNumberVecs());
356  assert (Length_ == A.GetVecLength());
357 
358 #ifdef HAVE_ANASAZI_EXPERIMENTAL
359  if (conj == Anasazi::CONJ) {
360 #endif
361  for (int v = 0 ; v < NumberVecs_ ; ++v) {
362  ScalarType value = 0.0;
363  for (int i = 0 ; i < Length_ ; ++i) {
364  value += (*this)(i, v) * Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v));
365  }
366  b[v] = value;
367  }
368 #ifdef HAVE_ANASAZI_EXPERIMENTAL
369  } else {
370  for (int v = 0 ; v < NumberVecs_ ; ++v) {
371  ScalarType value = 0.0;
372  for (int i = 0 ; i < Length_ ; ++i) {
373  value += (*this)(i, v) * (*MyA)(i, v);
374  }
375  b[v] = value;
376  }
377  }
378 #endif
379  }
380 
381 
382  template<class ScalarType>
383  void MyMultiVec<ScalarType>
384  ::MvNorm( std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &normvec) const
385  {
386  assert (NumberVecs_ <= (int)normvec.size());
387 
388  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
389 
390  for (int v = 0 ; v < NumberVecs_ ; ++v) {
391  MagnitudeType value = Teuchos::ScalarTraits<MagnitudeType>::zero();
392  for (int i = 0 ; i < Length_ ; ++i) {
393  MagnitudeType val = Teuchos::ScalarTraits<ScalarType>::magnitude((*this)(i, v));
394  value += val * val;
395  }
396  normvec[v] = Teuchos::ScalarTraits<MagnitudeType>::squareroot(value);
397  }
398  }
399 
400 
401  // Copy the vectors in A to a set of vectors in *this. The numvecs vectors in
402  // A are copied to a subset of vectors in *this indicated by the indices given
403  // in index.
404  // FIXME: not so clear what the size of A and index.size() are...
405  template<class ScalarType>
406  void MyMultiVec<ScalarType>::SetBlock(const Anasazi::MultiVec<ScalarType>& A,
407  const std::vector<int> &index)
408  {
409  MyMultiVec* MyA;
410  MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A));
411  assert (MyA != 0);
412 
413  assert (A.GetNumberVecs() >= (int)index.size());
414  assert (A.GetVecLength() == Length_);
415 
416  for (unsigned int v = 0 ; v < index.size() ; ++v) {
417  for (int i = 0 ; i < Length_ ; ++i) {
418  (*this)(i, index[v]) = (*MyA)(i, v);
419  }
420  }
421  }
422 
423 
424  // Scale the vectors by alpha
425  template<class ScalarType>
426  void MyMultiVec<ScalarType>::MvScale( ScalarType alpha )
427  {
428  for (int v = 0 ; v < NumberVecs_ ; ++v) {
429  for (int i = 0 ; i < Length_ ; ++i) {
430  (*this)(i, v) *= alpha;
431  }
432  }
433  }
434 
435 
436  // Scale the i-th vector by alpha[i]
437  template<class ScalarType>
438  void MyMultiVec<ScalarType>::MvScale( const std::vector<ScalarType>& alpha )
439  {
440  for (int v = 0 ; v < NumberVecs_ ; ++v) {
441  for (int i = 0 ; i < Length_ ; ++i) {
442  (*this)(i, v) *= alpha[v];
443  }
444  }
445  }
446 
447 
448  // Fill the vectors in *this with random numbers.
449  template<class ScalarType>
450  void MyMultiVec<ScalarType>::MvRandom ()
451  {
452  for (int v = 0 ; v < NumberVecs_ ; ++v) {
453  for (int i = 0 ; i < Length_ ; ++i) {
454  (*this)(i, v) = Teuchos::ScalarTraits<ScalarType>::random();
455  }
456  }
457  }
458 
459 
460  // Replace each element of the vectors in *this with alpha.
461  template<class ScalarType>
462  void MyMultiVec<ScalarType>::MvInit(ScalarType alpha)
463  {
464  for (int v = 0 ; v < NumberVecs_ ; ++v) {
465  for (int i = 0 ; i < Length_ ; ++i) {
466  (*this)(i, v) = alpha;
467  }
468  }
469  }
470 
471 
472  template<class ScalarType>
473  void MyMultiVec<ScalarType>::MvPrint(std::ostream &os) const
474  {
475  os << "Object MyMultiVec" << std::endl;
476  os << "Number of rows = " << Length_ << std::endl;
477  os << "Number of vecs = " << NumberVecs_ << std::endl;
478 
479  for (int i = 0 ; i < Length_ ; ++i)
480  {
481  for (int v = 0 ; v < NumberVecs_ ; ++v)
482  os << (*this)(i, v) << " ";
483  os << std::endl;
484  }
485  }
486 
487 
488  template<class ScalarType>
489  void MyMultiVec<ScalarType>::Check()
490  {
491  if (Length_ <= 0)
492  throw("Length must be positive");
493 
494  if (NumberVecs_ <= 0)
495  throw("Number of vectors must be positive");
496  }
497 
498 
499  template <typename ScalarType>
500  std::ostream& operator<<(std::ostream& os, const MyMultiVec<ScalarType>& Obj)
501  {
502  Obj.MvPrint(os);
503  return os;
504  }
505 
506 }
507 
508 #endif // MY_MULTIVECTOR_CPP
Anasazi::MyMultiVec::CloneViewNonConst
MyMultiVec< ScalarType > * CloneViewNonConst(const std::vector< int > &index)
Returns a view of current vector (shallow copy)
Definition: MyMultiVec.cpp:184
Anasazi::MyMultiVec
Simple example of a user's defined Anasazi::MultiVec class.
Definition: MyMultiVec.hpp:19
Anasazi::MyMultiVec::CloneView
const MyMultiVec< ScalarType > * CloneView(const std::vector< int > &index) const
Returns a view of current vector (shallow copy), const version.
Definition: MyMultiVec.cpp:199
Seldon::operator<<
ostream & operator<<(ostream &out, const Array< T, N, Allocator > &A)
operator<< overloaded for a 3D array.
Definition: Array.cxx:1617
Anasazi::MyMultiVec::~MyMultiVec
~MyMultiVec()
Destructor.
Definition: MyMultiVec.cpp:135
Anasazi::MyMultiVec::MyMultiVec
MyMultiVec(const int Length, const int NumberVecs)
Constructor for a NumberVecs vectors of length Length.
Definition: MyMultiVec.cpp:65
Anasazi::MyMultiVec::Clone
MyMultiVec< ScalarType > * Clone(const int NumberVecs) const
Returns a clone of the current vector.
Definition: MyMultiVec.cpp:145