//! Applies the matrix to a multivector. void Apply(const Anasazi::MultiVec<ScalarType>& X, Anasazi::MultiVec<ScalarType>& Y) const { const MyMultiVec<ScalarType>* MyX; MyX = dynamic_cast<const MyMultiVec<ScalarType>*>(&X); assert (MyX != 0); MyMultiVec<ScalarType>* MyY; MyY = dynamic_cast<MyMultiVec<ScalarType>*>(&Y); assert (MyY != 0); // Initialize output vector to zero. MyY->MvInit( Teuchos::ScalarTraits<ScalarType>::zero() ); assert (X.GetNumberVecs() == Y.GetNumberVecs()); assert (X.GetGlobalLength() == Y.GetGlobalLength()); int nv = X.GetNumberVecs(); // Apply operator int IA1, IA2, ri; ScalarType aval; int i,j,v; for (j=0; j<_nr; j++) { IA1 = _cptr[j]-1; IA2 = _cptr[j+1]-1; for (i=IA1; i<IA2; i++) { ri = _rind[i]-1; aval = _vals[i]; for (v=0; v<nv; v++) { (*MyY)[v][ri] += aval*(*MyX)[v][j]; } } } }
// Update *this with alpha * A * B + beta * (*this). void MvTimesMatAddMv (ScalarType alpha, const Anasazi::MultiVec<ScalarType> &A, const Teuchos::SerialDenseMatrix<int, ScalarType> &B, ScalarType beta) { assert (Length_ == A.GetVecLength()); assert (B.numRows() == A.GetNumberVecs()); assert (B.numCols() <= NumberVecs_); MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A)); assert(MyA!=NULL); if ((*this)[0] == (*MyA)[0]) { // If this == A, then need additional storage ... // This situation is a bit peculiar but it may be required by // certain algorithms. std::vector<ScalarType> tmp(NumberVecs_); for (int i = 0 ; i < Length_ ; ++i) { for (int v = 0; v < A.GetNumberVecs() ; ++v) { tmp[v] = (*MyA)(i, v); } for (int v = 0 ; v < B.numCols() ; ++v) { (*this)(i, v) *= beta; ScalarType res = Teuchos::ScalarTraits<ScalarType>::zero(); for (int j = 0 ; j < A.GetNumberVecs() ; ++j) { res += tmp[j] * B(j, v); } (*this)(i, v) += alpha * res; } } } else { for (int i = 0 ; i < Length_ ; ++i) { for (int v = 0 ; v < B.numCols() ; ++v) { (*this)(i, v) *= beta; ScalarType res = 0.0; for (int j = 0 ; j < A.GetNumberVecs() ; ++j) { res += (*MyA)(i, j) * B(j, v); } (*this)(i, v) += alpha * res; } } } }
// Copy the vectors in A to a set of vectors in *this. The numvecs vectors in // A are copied to a subset of vectors in *this indicated by the indices given // in index. // FIXME: not so clear what the size of A and index.size() are... void SetBlock (const Anasazi::MultiVec<ScalarType>& A, const std::vector<int> &index) { MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A)); assert (MyA != 0); assert (A.GetNumberVecs() >= (int)index.size()); assert (A.GetVecLength() == Length_); for (unsigned int v = 0 ; v < index.size() ; ++v) { for (int i = 0 ; i < Length_ ; ++i) { (*this)(i, index[v]) = (*MyA)(i, v); } } }
// Compute a dense matrix B through the matrix-matrix multiply alpha * A^H * (*this). void MvTransMv (ScalarType alpha, const Anasazi::MultiVec<ScalarType>& A, Teuchos::SerialDenseMatrix< int, ScalarType >& B #ifdef HAVE_ANASAZI_EXPERIMENTAL , Anasazi::ConjType conj #endif ) const { MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A)); assert (MyA != 0); assert (A.GetVecLength() == Length_); assert (NumberVecs_ <= B.numCols()); assert (A.GetNumberVecs() <= B.numRows()); #ifdef HAVE_ANASAZI_EXPERIMENTAL if (conj == Anasazi::CONJ) { #endif for (int v = 0 ; v < A.GetNumberVecs() ; ++v) { for (int w = 0 ; w < NumberVecs_ ; ++w) { ScalarType value = 0.0; for (int i = 0 ; i < Length_ ; ++i) { value += Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v)) * (*this)(i, w); } B(v, w) = alpha * value; } } #ifdef HAVE_ANASAZI_EXPERIMENTAL } else { for (int v = 0 ; v < A.GetNumberVecs() ; ++v) { for (int w = 0 ; w < NumberVecs_ ; ++w) { ScalarType value = 0.0; for (int i = 0 ; i < Length_ ; ++i) { value += (*MyA)(i, v) * (*this)(i, w); } B(v, w) = alpha * value; } } } #endif }
// Replace *this with alpha * A + beta * B. void MvAddMv (ScalarType alpha, const Anasazi::MultiVec<ScalarType>& A, ScalarType beta, const Anasazi::MultiVec<ScalarType>& B) { MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A)); assert (MyA != 0); MyMultiVec* MyB; MyB = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(B)); assert (MyB != 0); assert (NumberVecs_ == A.GetNumberVecs()); assert (NumberVecs_ == B.GetNumberVecs()); assert (Length_ == A.GetVecLength()); assert (Length_ == B.GetVecLength()); for (int v = 0 ; v < NumberVecs_ ; ++v) { for (int i = 0 ; i < Length_ ; ++i) { (*this)(i, v) = alpha * (*MyA)(i, v) + beta * (*MyB)(i, v); } } }
// 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. void MvDot (const Anasazi::MultiVec<ScalarType>& A, std::vector<ScalarType> &b #ifdef HAVE_ANASAZI_EXPERIMENTAL , Anasazi::ConjType conj #endif ) const { MyMultiVec* MyA; MyA = dynamic_cast<MyMultiVec*>(&const_cast<Anasazi::MultiVec<ScalarType> &>(A)); assert (MyA != 0); assert (NumberVecs_ <= (int)b.size()); assert (NumberVecs_ == A.GetNumberVecs()); assert (Length_ == A.GetVecLength()); #ifdef HAVE_ANASAZI_EXPERIMENTAL if (conj == Anasazi::CONJ) { #endif for (int v = 0 ; v < NumberVecs_ ; ++v) { ScalarType value = 0.0; for (int i = 0 ; i < Length_ ; ++i) { value += (*this)(i, v) * Teuchos::ScalarTraits<ScalarType>::conjugate((*MyA)(i, v)); } b[v] = value; } #ifdef HAVE_ANASAZI_EXPERIMENTAL } else { for (int v = 0 ; v < NumberVecs_ ; ++v) { ScalarType value = 0.0; for (int i = 0 ; i < Length_ ; ++i) { value += (*this)(i, v) * (*MyA)(i, v); } b[v] = value; } } #endif }