Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
AnasaziSaddleContainer.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends