00001 #ifndef MY_MULTIVECTOR_HPP
00002 #define MY_MULTIVECTOR_HPP
00003
00004 #include "BelosConfigDefs.hpp"
00005 #include "BelosMultiVec.hpp"
00006
00008
00018 template <class ScalarType>
00019 class MyMultiVec : public Belos::MultiVec<ScalarType>
00020 {
00021 public:
00022
00024 MyMultiVec(const int Length, const int NumberVecs) :
00025 Length_(Length),
00026 NumberVecs_(NumberVecs)
00027 {
00028 Check();
00029
00030 data_.resize(NumberVecs);
00031 ownership_.resize(NumberVecs);
00032
00033
00034 for (int v = 0 ; v < NumberVecs_ ; ++v)
00035 {
00036 data_[v] = new ScalarType[Length];
00037 ownership_[v] = true;
00038 }
00039
00040
00041 MvInit(0.0);
00042 }
00043
00045 MyMultiVec(const int Length, const std::vector<ScalarType*>& rhs) :
00046 Length_(Length),
00047 NumberVecs_(rhs.size())
00048 {
00049 Check();
00050
00051 data_.resize(NumberVecs_);
00052 ownership_.resize(NumberVecs_);
00053
00054
00055
00056 for (int v = 0 ; v < NumberVecs_ ; ++v)
00057 {
00058 data_[v] = rhs[v];
00059 ownership_[v] = false;
00060 }
00061 }
00062
00064 MyMultiVec(const MyMultiVec& rhs) :
00065 Length_(rhs.GetVecLength()),
00066 NumberVecs_(rhs.NumberVecs_)
00067 {
00068 Check();
00069
00070 data_.resize(NumberVecs_);
00071 ownership_.resize(NumberVecs_);
00072
00073 for (int v = 0 ; v < NumberVecs_ ; ++v)
00074 {
00075 data_[v] = new ScalarType[Length_];
00076 ownership_[v] = true;
00077 }
00078
00079 for (int v = 0 ; v < NumberVecs_ ; ++v)
00080 {
00081 for (int i = 0 ; i < Length_ ; ++i)
00082 (*this)(i, v) = rhs(i, v);
00083 }
00084 }
00085
00087 ~MyMultiVec()
00088 {
00089 for (int v = 0 ; v < NumberVecs_ ; ++v)
00090 if (ownership_[v])
00091 delete[] data_[v];
00092 }
00093
00095 MyMultiVec* Clone(const int NumberVecs) const
00096 {
00097
00098 MyMultiVec* tmp = new MyMultiVec(Length_, NumberVecs);
00099
00100
00101
00102
00103
00104 return(tmp);
00105 }
00106
00107
00108 MyMultiVec* CloneCopy() const
00109 {
00110 return(new MyMultiVec(*this));
00111 }
00112
00114 MyMultiVec* CloneCopy(const std::vector< int > &index) const
00115 {
00116 int size = index.size();
00117 MyMultiVec* tmp = new MyMultiVec(Length_, size);
00118
00119 for (unsigned int v = 0 ; v < index.size() ; ++v) {
00120 for (int i = 0 ; i < Length_ ; ++i) {
00121 (*tmp)(i, v) = (*this)(i, index[v]);
00122 }
00123 }
00124
00125 return(tmp);
00126 }
00127
00129 MyMultiVec* CloneView(const std::vector< int > &index)
00130 {
00131 int size = index.size();
00132 std::vector<ScalarType*> values(size);
00133
00134 for (unsigned int v = 0 ; v < index.size() ; ++v)
00135 values[v] = data_[index[v]];
00136
00137 return(new MyMultiVec(Length_, values));
00138 }
00139
00141 const MyMultiVec* CloneView(const std::vector< int > &index) const
00142 {
00143 int size = index.size();
00144 std::vector<ScalarType*> values(size);
00145
00146 for (unsigned int v = 0 ; v < index.size() ; ++v)
00147 values[v] = data_[index[v]];
00148
00149 return(new MyMultiVec(Length_, values));
00150 }
00151
00152 int GetVecLength () const
00153 {
00154 return(Length_);
00155 }
00156
00157 int GetNumberVecs () const
00158 {
00159 return(NumberVecs_);
00160 }
00161
00162
00163 void MvTimesMatAddMv (const ScalarType alpha, const Belos::MultiVec<ScalarType> &A,
00164 const Teuchos::SerialDenseMatrix<int, ScalarType> &B,
00165 const ScalarType beta)
00166 {
00167
00168 assert (Length_ == A.GetVecLength());
00169 assert (B.numRows() == A.GetNumberVecs());
00170 assert (B.numCols() <= NumberVecs_);
00171
00172 MyMultiVec* MyA;
00173 MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
00174 assert(MyA!=NULL);
00175
00176 if ((*this)[0] == (*MyA)[0]) {
00177
00178
00179
00180
00181 std::vector<ScalarType> tmp(NumberVecs_);
00182
00183 for (int i = 0 ; i < Length_ ; ++i) {
00184 for (int v = 0; v < A.GetNumberVecs() ; ++v) {
00185 tmp[v] = (*MyA)(i, v);
00186 }
00187
00188 for (int v = 0 ; v < B.numCols() ; ++v) {
00189 (*this)(i, v) *= beta;
00190 ScalarType res = Teuchos::ScalarTraits<ScalarType>::zero();
00191
00192 for (int j = 0 ; j < A.GetNumberVecs() ; ++j) {
00193 res += tmp[j] * B(j, v);
00194 }
00195
00196 (*this)(i, v) += alpha * res;
00197 }
00198 }
00199 }
00200 else {
00201 for (int i = 0 ; i < Length_ ; ++i) {
00202 for (int v = 0 ; v < B.numCols() ; ++v) {
00203 (*this)(i, v) *= beta;
00204 ScalarType res = 0.0;
00205 for (int j = 0 ; j < A.GetNumberVecs() ; ++j) {
00206 res += (*MyA)(i, j) * B(j, v);
00207 }
00208
00209 (*this)(i, v) += alpha * res;
00210 }
00211 }
00212 }
00213 }
00214
00215
00216 void MvAddMv (const ScalarType alpha, const Belos::MultiVec<ScalarType>& A,
00217 const ScalarType beta, const Belos::MultiVec<ScalarType>& B)
00218 {
00219 MyMultiVec* MyA;
00220 MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
00221 assert (MyA != 0);
00222
00223 MyMultiVec* MyB;
00224 MyB = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(B));
00225 assert (MyB != 0);
00226
00227 assert (NumberVecs_ == A.GetNumberVecs());
00228 assert (NumberVecs_ == B.GetNumberVecs());
00229
00230 assert (Length_ == A.GetVecLength());
00231 assert (Length_ == B.GetVecLength());
00232
00233 for (int v = 0 ; v < NumberVecs_ ; ++v) {
00234 for (int i = 0 ; i < Length_ ; ++i) {
00235 (*this)(i, v) = alpha * (*MyA)(i, v) + beta * (*MyB)(i, v);
00236 }
00237 }
00238 }
00239
00240
00241 void MvTransMv (ScalarType alpha, const Belos::MultiVec<ScalarType>& A,
00242 Teuchos::SerialDenseMatrix< int, ScalarType >& B
00243 #ifdef HAVE_BELOS_EXPERIMENTAL
00244 , Belos::ConjType conj
00245 #endif
00246 ) const
00247 {
00248 MyMultiVec* MyA;
00249 MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
00250 assert (MyA != 0);
00251
00252 assert (A.GetVecLength() == Length_);
00253 assert (NumberVecs_ <= B.numCols());
00254 assert (A.GetNumberVecs() <= B.numRows());
00255
00256 #ifdef HAVE_BELOS_EXPERIMENTAL
00257 if (conj == Belos::CONJ) {
00258 #endif
00259 for (int v = 0 ; v < A.GetNumberVecs() ; ++v) {
00260 for (int w = 0 ; w < NumberVecs_ ; ++w) {
00261 ScalarType value = 0.0;
00262 for (int i = 0 ; i < Length_ ; ++i) {
00263 value += Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v)) * (*this)(i, w);
00264 }
00265 B(v, w) = alpha * value;
00266 }
00267 }
00268 #ifdef HAVE_BELOS_EXPERIMENTAL
00269 } else {
00270 for (int v = 0 ; v < A.GetNumberVecs() ; ++v) {
00271 for (int w = 0 ; w < NumberVecs_ ; ++w) {
00272 ScalarType value = 0.0;
00273 for (int i = 0 ; i < Length_ ; ++i) {
00274 value += (*MyA)(i, v) * (*this)(i, w);
00275 }
00276 B(v, w) = alpha * value;
00277 }
00278 }
00279 }
00280 #endif
00281 }
00282
00283
00284
00285 void MvDot (const Belos::MultiVec<ScalarType>& A, std::vector<ScalarType>* b
00286 #ifdef HAVE_BELOS_EXPERIMENTAL
00287 , Belos::ConjType conj
00288 #endif
00289 ) const
00290 {
00291 MyMultiVec* MyA;
00292 MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
00293 assert (MyA != 0);
00294
00295 assert (NumberVecs_ <= (int)b->size());
00296 assert (NumberVecs_ == A.GetNumberVecs());
00297 assert (Length_ == A.GetVecLength());
00298
00299 #ifdef HAVE_BELOS_EXPERIMENTAL
00300 if (conj == Belos::CONJ) {
00301 #endif
00302 for (int v = 0 ; v < NumberVecs_ ; ++v) {
00303 ScalarType value = 0.0;
00304 for (int i = 0 ; i < Length_ ; ++i) {
00305 value += (*this)(i, v) * Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v));
00306 }
00307 (*b)[v] = value;
00308 }
00309 #ifdef HAVE_BELOS_EXPERIMENTAL
00310 } else {
00311 for (int v = 0 ; v < NumberVecs_ ; ++v) {
00312 ScalarType value = 0.0;
00313 for (int i = 0 ; i < Length_ ; ++i) {
00314 value += (*this)(i, v) * (*MyA)(i, v);
00315 }
00316 (*b)[v] = value;
00317 }
00318 }
00319 #endif
00320 }
00321
00322
00323 void MvNorm ( std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>* normvec,
00324 Belos::NormType type = Belos::TwoNorm ) const
00325 {
00326 assert (normvec != 0);
00327 assert (NumberVecs_ <= (int)normvec->size());
00328
00329 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00330
00331 for (int v = 0 ; v < NumberVecs_ ; ++v) {
00332 MagnitudeType value = Teuchos::ScalarTraits<MagnitudeType>::zero();
00333 for (int i = 0 ; i < Length_ ; ++i) {
00334 MagnitudeType val = Teuchos::ScalarTraits<ScalarType>::magnitude((*this)(i, v));
00335 value += val * val;
00336 }
00337 (*normvec)[v] = Teuchos::ScalarTraits<MagnitudeType>::squareroot(value);
00338 }
00339 }
00340
00341
00342
00343
00344
00345 void SetBlock (const Belos::MultiVec<ScalarType>& A,
00346 const std::vector<int> &index)
00347 {
00348 MyMultiVec* MyA;
00349 MyA = dynamic_cast<MyMultiVec*>(&const_cast<Belos::MultiVec<ScalarType> &>(A));
00350 assert (MyA != 0);
00351
00352 assert (A.GetNumberVecs() >= (int)index.size());
00353 assert (A.GetVecLength() == Length_);
00354
00355 for (unsigned int v = 0 ; v < index.size() ; ++v) {
00356 for (int i = 0 ; i < Length_ ; ++i) {
00357 (*this)(i, index[v]) = (*MyA)(i, v);
00358 }
00359 }
00360 }
00361
00362
00363 void MvRandom ()
00364 {
00365 for (int v = 0 ; v < NumberVecs_ ; ++v) {
00366 for (int i = 0 ; i < Length_ ; ++i) {
00367 (*this)(i, v) = Teuchos::ScalarTraits<ScalarType>::random();
00368 }
00369 }
00370 }
00371
00372
00373 void MvInit (const ScalarType alpha)
00374 {
00375 for (int v = 0 ; v < NumberVecs_ ; ++v) {
00376 for (int i = 0 ; i < Length_ ; ++i) {
00377 (*this)(i, v) = alpha;
00378 }
00379 }
00380 }
00381
00382 void MvPrint (ostream &os) const
00383 {
00384 os << "Object MyMultiVec" << endl;
00385 os << "Number of rows = " << Length_ << endl;
00386 os << "Number of vecs = " << NumberVecs_ << endl;
00387
00388 for (int i = 0 ; i < Length_ ; ++i)
00389 {
00390 for (int v = 0 ; v < NumberVecs_ ; ++v)
00391 os << (*this)(i, v) << " ";
00392 os << endl;
00393 }
00394 }
00395
00396 inline ScalarType& operator()(const int i, const int j)
00397 {
00398 if (j < 0 || j >= NumberVecs_) throw(-1);
00399 if (i < 0 || i >= Length_) throw(-2);
00400
00401 return(data_[j][i]);
00402 }
00403
00404 inline const ScalarType& operator()(const int i, const int j) const
00405 {
00406 if (j < 0 || j >= NumberVecs_) throw(-1);
00407 if (i < 0 || i >= Length_) throw(-2);
00408
00409 return(data_[j][i]);
00410 }
00411
00412 ScalarType* operator[](int v)
00413 {
00414 if (v < 0 || v >= NumberVecs_) throw(-1);
00415 return(data_[v]);
00416 }
00417
00418 ScalarType* operator[](int v) const
00419 {
00420 return(data_[v]);
00421 }
00422
00423 private:
00424 void Check()
00425 {
00426 if (Length_ <= 0)
00427 throw("Length must be positive");
00428
00429 if (NumberVecs_ <= 0)
00430 throw("Number of vectors must be positive");
00431 }
00432
00434 const int Length_;
00436 const int NumberVecs_;
00438 std::vector<ScalarType*> data_;
00440 std::vector<bool> ownership_;
00441
00442 };
00443
00444
00445 #endif // MY_MULTIVECTOR_HPP