|
Anasazi
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Anasazi: Block Eigensolvers Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00036 #ifndef ANASAZI_SADDLE_CONTAINER_HPP 00037 #define ANASAZI_SADDLE_CONTAINER_HPP 00038 00039 #include "AnasaziConfigDefs.hpp" 00040 #include "Teuchos_VerboseObject.hpp" 00041 00042 using Teuchos::RCP; 00043 using Teuchos::rcp; 00044 00045 namespace Anasazi { 00046 namespace Experimental { 00047 00048 template <class ScalarType, class MV> 00049 class SaddleContainer //: public Anasazi::SaddleContainer<ScalarType, MV> 00050 { 00051 template <class Scalar_, class MV_, class OP_> friend class SaddleOperator; 00052 00053 private: 00054 typedef Anasazi::MultiVecTraits<ScalarType,MV> MVT; 00055 typedef Teuchos::SerialDenseMatrix<int,ScalarType> SerialDenseMatrix; 00056 const ScalarType ONE; 00057 RCP<MV> X_; 00058 RCP<SerialDenseMatrix> Y_; 00059 00060 public: 00061 // Constructors 00062 SaddleContainer( ) : ONE(Teuchos::ScalarTraits<ScalarType>::one()) { }; 00063 SaddleContainer( const RCP<MV> X, bool eye=false ); 00064 00065 // Things that are necessary for compilation 00066 // Returns a clone of the current vector 00067 SaddleContainer<ScalarType, MV> * Clone(const int nvecs) const; 00068 // Returns a duplicate of the current vector 00069 SaddleContainer<ScalarType, MV> * CloneCopy() const; 00070 // Returns a duplicate of the specified vectors 00071 SaddleContainer<ScalarType, MV> * CloneCopy(const std::vector< int > &index) const; 00072 int GetVecLength() const; 00073 int GetNumberVecs() const { return MVT::GetNumberVecs(*X_); }; 00074 // Update *this with alpha * A * B + beta * (*this) 00075 void MvTimesMatAddMv(ScalarType alpha, const SaddleContainer<ScalarType,MV> &A, 00076 const Teuchos::SerialDenseMatrix<int, ScalarType> &B, 00077 ScalarType beta); 00078 // Replace *this with alpha * A + beta * B 00079 void MvAddMv(ScalarType alpha, const SaddleContainer<ScalarType,MV>& A, 00080 ScalarType beta, const SaddleContainer<ScalarType,MV>& B); 00081 // Scale the vectors by alpha 00082 void MvScale( ScalarType alpha ); 00083 // Scale the i-th vector by alpha[i] 00084 void MvScale( const std::vector<ScalarType>& alpha ); 00085 // Compute a dense matrix B through the matrix-matrix multiply alpha * A^H * (*this) 00086 void MvTransMv (ScalarType alpha, const SaddleContainer<ScalarType, MV>& A, 00087 Teuchos::SerialDenseMatrix< int, ScalarType >& B) const; 00088 // 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. 00089 void MvDot (const SaddleContainer<ScalarType, MV>& A, std::vector<ScalarType> &b) const; 00090 // Compute the 2-norm of each individual vector 00091 void MvNorm ( std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &normvec) const; 00092 // Copy the vectors in A to a set of vectors in *this. The numvecs vectors in 00093 // A are copied to a subset of vectors in *this indicated by the indices given 00094 // in index. 00095 void SetBlock (const SaddleContainer<ScalarType, MV>& A, const std::vector<int> &index); 00096 // Deep copy. 00097 void Assign (const SaddleContainer<ScalarType, MV>&A); 00098 // Fill the vectors in *this with random numbers. 00099 void MvRandom (); 00100 // Replace each element of the vectors in *this with alpha. 00101 void MvInit (ScalarType alpha); 00102 // Prints the multivector to an output stream 00103 void MvPrint (std::ostream &os) const; 00104 }; 00105 00106 00107 00108 // Constructor 00109 template <class ScalarType, class MV> 00110 SaddleContainer<ScalarType, MV>::SaddleContainer( const RCP<MV> X, bool eye ) 00111 : ONE(Teuchos::ScalarTraits<ScalarType>::one()) 00112 { 00113 int nvecs = MVT::GetNumberVecs(*X); 00114 00115 if(eye) 00116 { 00117 // Initialize X_ as all 0s 00118 X_ = MVT::Clone(*X, nvecs); 00119 MVT::MvInit(*X_); 00120 00121 // Initialize Y to be I 00122 Y_ = rcp(new SerialDenseMatrix(nvecs,nvecs)); 00123 for(int i=0; i < nvecs; i++) 00124 (*Y_)(i,i) = ONE; 00125 } 00126 else 00127 { 00128 // Point X_ to X 00129 X_ = X; 00130 00131 // Initialize Y to be 0 00132 Y_ = rcp(new SerialDenseMatrix(nvecs,nvecs)); 00133 } 00134 } 00135 00136 00137 00138 // Returns a clone of the current vector 00139 template <class ScalarType, class MV> 00140 SaddleContainer<ScalarType, MV> * SaddleContainer<ScalarType, MV>::Clone(const int nvecs) const 00141 { 00142 SaddleContainer<ScalarType, MV> * newSC = new SaddleContainer<ScalarType, MV>(); 00143 00144 newSC->X_ = MVT::Clone(*X_,nvecs); 00145 newSC->Y_ = rcp(new SerialDenseMatrix(Y_->numRows(),Y_->numCols())); 00146 00147 return newSC; 00148 } 00149 00150 00151 00152 // Returns a duplicate of the current vector 00153 template <class ScalarType, class MV> 00154 SaddleContainer<ScalarType, MV> * SaddleContainer<ScalarType, MV>::CloneCopy() const 00155 { 00156 SaddleContainer<ScalarType, MV> * newSC = new SaddleContainer<ScalarType, MV>(); 00157 00158 newSC->X_ = MVT::CloneCopy(*X_); 00159 newSC->Y_ = rcp(new SerialDenseMatrix(*Y_)); 00160 00161 return newSC; 00162 } 00163 00164 00165 00166 // Returns a duplicate of the specified vectors 00167 template <class ScalarType, class MV> 00168 SaddleContainer<ScalarType, MV> * SaddleContainer<ScalarType, MV>::CloneCopy(const std::vector< int > &index) const 00169 { 00170 SaddleContainer<ScalarType, MV> * newSC = new SaddleContainer<ScalarType, MV>(); 00171 00172 newSC->X_ = MVT::CloneCopy(*X_,index); 00173 00174 int ncols = index.size(); 00175 int nrows = Y_->numRows(); 00176 newSC->Y_ = rcp(new SerialDenseMatrix(nrows,ncols)); 00177 for(int c=0; c < ncols; c++) 00178 { 00179 for(int r=0; r < nrows; r++) 00180 (*newSC->Y_)(r,c) = (*Y_)(r,index[c]); 00181 } 00182 00183 return newSC; 00184 } 00185 00186 00187 00188 // Replace *this with alpha * A + beta * B 00189 template <class ScalarType, class MV> 00190 void SaddleContainer<ScalarType, MV>::MvAddMv(ScalarType alpha, const SaddleContainer<ScalarType,MV>& A, 00191 ScalarType beta, const SaddleContainer<ScalarType,MV>& B) 00192 { 00193 MVT::MvAddMv(alpha, *(A.X_), beta, *(B.X_), *X_); 00194 00195 int ncolsA = A.Y_->numCols(); 00196 int ncolsThis = Y_->numCols(); 00197 int nrows = Y_->numRows(); 00198 00199 // check whether space needs to be reallocated 00200 if(ncolsA != ncolsThis) 00201 Y_->shapeUninitialized(nrows,ncolsA); 00202 00203 // Y = alpha A 00204 Y_->assign(*A.Y_); 00205 if(alpha != ONE) 00206 Y_->scale(alpha); 00207 // Y += beta B 00208 if(beta == ONE) 00209 *Y_ += *B.Y_; 00210 else if(beta == -ONE) 00211 *Y_ -= *B.Y_; 00212 else 00213 { 00214 SerialDenseMatrix scaledB(*B.Y_); 00215 scaledB.scale(beta); 00216 *Y_ += *B.Y_; 00217 } 00218 } 00219 00220 00221 00222 // Scale the vectors by alpha 00223 template <class ScalarType, class MV> 00224 void SaddleContainer<ScalarType, MV>::MvScale( ScalarType alpha ) 00225 { 00226 MVT::MvScale(*X_, alpha); 00227 Y_->scale(alpha); 00228 } 00229 00230 00231 00232 // Scale the i-th vector by alpha[i] 00233 template <class ScalarType, class MV> 00234 void SaddleContainer<ScalarType, MV>::MvScale( const std::vector<ScalarType>& alpha ) 00235 { 00236 MVT::MvScale(*X_, alpha); 00237 00238 int nrows = Y_->numRows(); 00239 int ncols = Y_->numCols(); 00240 00241 for(int c=0; c<ncols; c++) 00242 { 00243 for(int r=0; r<nrows; r++) 00244 (*Y_)(r,c) *= alpha[c]; 00245 } 00246 } 00247 00248 00249 00250 // 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. 00251 template <class ScalarType, class MV> 00252 void SaddleContainer<ScalarType, MV>::MvDot (const SaddleContainer<ScalarType, MV>& A, std::vector<ScalarType> &b) const 00253 { 00254 MVT::MvDot(*X_, *(A.X_), b); 00255 00256 int nrows = Y_->numRows(); 00257 int ncols = Y_->numCols(); 00258 00259 for(int c=0; c < ncols; c++) 00260 { 00261 for(int r=0; r < nrows; r++) 00262 { 00263 b[c] += ((*A.Y_)(r,c) * (*Y_)(r,c)); 00264 } 00265 } 00266 } 00267 00268 00269 00270 // Copy the vectors in A to a set of vectors in *this. The numvecs vectors in 00271 // A are copied to a subset of vectors in *this indicated by the indices given 00272 // in index. 00273 template <class ScalarType, class MV> 00274 void SaddleContainer<ScalarType, MV>::SetBlock (const SaddleContainer<ScalarType, MV>& A, const std::vector<int> &index) 00275 { 00276 MVT::SetBlock(*(A.X_), index, *X_); 00277 00278 int nrows = Y_->numRows(); 00279 00280 int nvecs = index.size(); 00281 for(int c=0; c<nvecs; c++) 00282 { 00283 for(int r=0; r<nrows; r++) 00284 (*Y_)(r,index[c]) = (*A.Y_)(r,c); 00285 } 00286 } 00287 00288 00289 00290 // Deep copy. 00291 template <class ScalarType, class MV> 00292 void SaddleContainer<ScalarType, MV>::Assign (const SaddleContainer<ScalarType, MV>&A) 00293 { 00294 MVT::Assign(*(A.X_),*(X_)); 00295 00296 *Y_ = *A.Y_; // This is a well-defined operator for SerialDenseMatrix 00297 } 00298 00299 00300 00301 // Replace each element of the vectors in *this with alpha. 00302 template <class ScalarType, class MV> 00303 void SaddleContainer<ScalarType, MV>::MvInit (ScalarType alpha) 00304 { 00305 MVT::MvInit(*X_,alpha); 00306 Y_->putScalar(alpha); 00307 } 00308 00309 00310 00311 // Prints the multivector to an output stream 00312 template <class ScalarType, class MV> 00313 void SaddleContainer<ScalarType, MV>::MvPrint (std::ostream &os) const 00314 { 00315 int nrows = Y_->numRows(); 00316 int ncols = Y_->numCols(); 00317 00318 os << "Object SaddleContainer" << std::endl; 00319 os << "X\n"; 00320 // X_->describe(*(Teuchos::VerboseObjectBase::getDefaultOStream()),Teuchos::VERB_EXTREME); 00321 // os << "X\n" << *X_ << std::endl; 00322 00323 os << "Y\n"; 00324 for(int r=0; r<nrows; r++) 00325 { 00326 for(int c=0; c<ncols; c++) 00327 os << "Y[" << r << "][" << c << "]=" << (*Y_)[c][r] << std::endl; 00328 } 00329 } 00330 00331 } // End namespace Experimental 00332 00333 template<class ScalarType, class MV > 00334 class MultiVecTraits<ScalarType,Experimental::SaddleContainer<ScalarType, MV> > 00335 { 00336 public: 00337 static RCP<Experimental::SaddleContainer<ScalarType, MV> > Clone( const Experimental::SaddleContainer<ScalarType, MV>& mv, const int numvecs ) 00338 { return rcp( const_cast<Experimental::SaddleContainer<ScalarType, MV>&>(mv).Clone(numvecs) ); } 00339 00340 static RCP<Experimental::SaddleContainer<ScalarType, MV> > CloneCopy( const Experimental::SaddleContainer<ScalarType, MV>& mv ) 00341 { return rcp( const_cast<Experimental::SaddleContainer<ScalarType, MV>&>(mv).CloneCopy() ); } 00342 00343 static RCP<Experimental::SaddleContainer<ScalarType, MV> > CloneCopy( const Experimental::SaddleContainer<ScalarType, MV>& mv, const std::vector<int>& index ) 00344 { return rcp( const_cast<Experimental::SaddleContainer<ScalarType, MV>&>(mv).CloneCopy(index) ); } 00345 00346 static int GetVecLength( const Experimental::SaddleContainer<ScalarType, MV>& mv ) 00347 { return mv.GetVecLength(); } 00348 00349 static int GetNumberVecs( const Experimental::SaddleContainer<ScalarType, MV>& mv ) 00350 { return mv.GetNumberVecs(); } 00351 00352 static void MvTimesMatAddMv( ScalarType alpha, const Experimental::SaddleContainer<ScalarType, MV>& A, 00353 const Teuchos::SerialDenseMatrix<int,ScalarType>& B, 00354 ScalarType beta, Experimental::SaddleContainer<ScalarType, MV>& mv ) 00355 { mv.MvTimesMatAddMv(alpha, A, B, beta); } 00356 00357 static void MvAddMv( ScalarType alpha, const Experimental::SaddleContainer<ScalarType, MV>& A, ScalarType beta, const Experimental::SaddleContainer<ScalarType, MV>& B, Experimental::SaddleContainer<ScalarType, MV>& mv ) 00358 { mv.MvAddMv(alpha, A, beta, B); } 00359 00360 static void MvTransMv( ScalarType alpha, const Experimental::SaddleContainer<ScalarType, MV>& A, const Experimental::SaddleContainer<ScalarType, MV>& mv, Teuchos::SerialDenseMatrix<int,ScalarType>& B) 00361 { mv.MvTransMv(alpha, A, B); } 00362 00363 static void MvDot( const Experimental::SaddleContainer<ScalarType, MV>& mv, const Experimental::SaddleContainer<ScalarType, MV>& A, std::vector<ScalarType> & b) 00364 { mv.MvDot( A, b); } 00365 00366 static void MvScale ( Experimental::SaddleContainer<ScalarType, MV>& mv, ScalarType alpha ) 00367 { mv.MvScale( alpha ); } 00368 00369 static void MvScale ( Experimental::SaddleContainer<ScalarType, MV>& mv, const std::vector<ScalarType>& alpha ) 00370 { mv.MvScale( alpha ); } 00371 00372 static void MvNorm( const Experimental::SaddleContainer<ScalarType, MV>& mv, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> & normvec) 00373 { mv.MvNorm(normvec); } 00374 00375 static void SetBlock( const Experimental::SaddleContainer<ScalarType, MV>& A, const std::vector<int>& index, Experimental::SaddleContainer<ScalarType, MV>& mv ) 00376 { mv.SetBlock(A, index); } 00377 00378 static void Assign( const Experimental::SaddleContainer<ScalarType, MV>& A, Experimental::SaddleContainer<ScalarType, MV>& mv ) 00379 { mv.Assign(A); } 00380 00381 static void MvRandom( Experimental::SaddleContainer<ScalarType, MV>& mv ) 00382 { mv.MvRandom(); } 00383 00384 static void MvInit( Experimental::SaddleContainer<ScalarType, MV>& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero() ) 00385 { mv.MvInit(alpha); } 00386 00387 static void MvPrint( const Experimental::SaddleContainer<ScalarType, MV>& mv, std::ostream& os ) 00388 { mv.MvPrint(os); } 00389 }; 00390 00391 } // end namespace Anasazi 00392 00393 #endif
1.7.6.1