PlayaAnasaziAdapter.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 //
00003  /* @HEADER@ */
00004 
00005 #ifndef ANASAZI_PLAYA_ADAPTER_HPP
00006 #define ANASAZI_PLAYA_ADAPTER_HPP
00007 
00008 #include "AnasaziMultiVecTraits.hpp"
00009 #include "AnasaziOperatorTraits.hpp"
00010 #include "AnasaziConfigDefs.hpp"
00011 
00012 
00013 #include "PlayaVectorImpl.hpp"
00014 #include "PlayaLinearOperatorImpl.hpp"
00015 #include "PlayaSimpleTransposedOpImpl.hpp"
00016 #include "PlayaLinearCombinationImpl.hpp"
00017 
00018 #include "Teuchos_Array.hpp"
00019 #include "Teuchos_RCP.hpp"
00020 
00021 #include "PlayaTabs.hpp"
00022 
00023 namespace Anasazi 
00024 {
00025 using Playa::Vector;
00026 using Teuchos::RCP;
00027 using Teuchos::Array;
00028 
00029 class SimpleMV
00030 {
00031 public:
00032   SimpleMV() : data_() {}
00033 
00034   SimpleMV(int n) : data_(rcp(new Array<Vector<double> >(n))) {}
00035 
00036   SimpleMV(const Array<Vector<double> >& data) 
00037     : data_(rcp(new Array<Vector<double> >(data.size())))
00038     {
00039       for (int i=0; i<data.size(); i++)
00040       {
00041         (*data_)[i] = data[i].copy();
00042       }
00043     }
00044 
00045   SimpleMV clone() const
00046     {
00047       return SimpleMV(*data_);
00048     }
00049 
00050   Vector<double>& operator[](int i) {return (*data_)[i];}
00051 
00052   const Vector<double>& operator[](int i) const {return (*data_)[i];}
00053 
00054   int size() const {return data_->size();}
00055 
00056   void resize(int n)
00057     {
00058       data_->resize(n);
00059     }
00060 
00061   void randomize() 
00062     {
00063       for (int i=0; i<size(); i++) (*data_)[i].randomize();
00064     }
00065   
00066 private:
00067   RCP<Array<Vector<double> > > data_;
00068 };
00069 
00070 
00071 
00072 inline std::ostream& operator<<(std::ostream& os, const SimpleMV& mv)
00073 {
00074   os << "MV (size=" << mv.size() << ")" << std::endl;
00075   for (int i=0; i<mv.size(); i++)
00076   {
00077     os << "ptr=" << mv[i].ptr().get() << std::endl;
00078     os << mv[i] << std::endl;
00079   }
00080 
00081   return os;
00082 }
00083 
00084 /** */
00085 template<>
00086 class MultiVecTraits<double, SimpleMV >
00087 {
00088 public:
00089   typedef SimpleMV _MV;
00090   typedef Teuchos::ScalarTraits<double> SCT;
00091 
00092   static double one() {static double rtn = SCT::one(); return rtn;}
00093   static double zero() {static double rtn = SCT::zero(); return rtn;}
00094 
00095   /** \name Creation methods */
00096   //@{
00097 
00098   /**
00099    */
00100   static RCP<_MV> Clone( const  _MV & mv, const int numvecs )
00101     { 
00102       //Out::os() << "Clone(nv == " << numvecs << ")" << endl;
00103       TEUCHOS_TEST_FOR_EXCEPT(mv.size() <= 0);
00104       TEUCHOS_TEST_FOR_EXCEPT(numvecs <= 0);
00105 
00106       RCP<_MV> rtn = rcp(new _MV(numvecs));
00107       for (int i=0; i<numvecs; i++)
00108       {
00109         (*rtn)[i] = mv[0].copy();
00110         (*rtn)[i].setToConstant(zero());
00111       }
00112       return rtn;
00113     }
00114 
00115   /**
00116    *
00117    */
00118   static RCP< _MV > CloneCopy( const  _MV & mv )
00119     { 
00120       //Out::os() << "CloneCopy()" << endl;
00121       int numvecs = mv.size();
00122       TEUCHOS_TEST_FOR_EXCEPT(numvecs <= 0);
00123 
00124       // create the new multivector
00125       RCP<_MV> rtn = rcp(new _MV(numvecs));
00126       for (int i=0; i<numvecs; i++)
00127       {
00128         (*rtn)[i] = mv[i].copy();
00129       }
00130       return rtn;
00131     }
00132 
00133   /** 
00134       
00135   */
00136   static RCP< _MV > CloneCopy( const  _MV & mv, const std::vector<int>& index )
00137     { 
00138       //Out::os() << "CloneCopy() indexed" << endl;
00139       int numvecs = index.size();
00140       TEUCHOS_TEST_FOR_EXCEPT(numvecs <= 0);
00141       TEUCHOS_TEST_FOR_EXCEPT((int) index.size() > mv.size());
00142 
00143 //      TEUCHOS_TEST_FOR_EXCEPT(detectRepeatedIndex(index));
00144 
00145       // create the new multivector
00146       RCP<  _MV  > rtn = rcp(new _MV(numvecs));
00147 
00148       for (int i=0; i<numvecs; i++)
00149       {
00150         (*rtn)[i] = mv[index[i]].copy();
00151       }
00152       return rtn;
00153     }
00154 
00155   /**
00156 
00157   */      
00158   static RCP< _MV > CloneViewNonConst(  _MV & mv, const std::vector<int>& index )
00159     {
00160       int numvecs = index.size();
00161       //Out::os() << "index.size() = " << numvecs << endl;
00162       //Out::os() << "input size = " << mv.size() << endl;
00163       TEUCHOS_TEST_FOR_EXCEPT(numvecs <= 0);
00164       TEUCHOS_TEST_FOR_EXCEPT((int) index.size() > mv.size());
00165 
00166 //      TEUCHOS_TEST_FOR_EXCEPT(detectRepeatedIndex(index));
00167 
00168       // create the new multivector
00169       RCP<  _MV  > rtn = rcp(new _MV(numvecs));
00170 
00171       for (int i=0; i<numvecs; i++)
00172       {
00173         (*rtn)[i] = mv[index[i]]; // shallow copy
00174       }
00175 
00176       return rtn;
00177     }
00178 
00179   static RCP<_MV> 
00180   CloneViewNonConst (_MV & mv, const Teuchos::Range1D& index) 
00181   {
00182     typedef std::vector<int>::size_type size_type;
00183     std::vector<int> ind (index.size ());
00184     for (size_type i = 0; i < static_cast<size_type> (index.size ()); ++i) {
00185       ind[i] = index.lbound () + i;
00186     }
00187     return CloneViewNonConst (mv, ind);
00188   }
00189 
00190   /**
00191    *
00192    */      
00193   static RCP<const _MV > CloneView( const _MV & mv, const std::vector<int>& index )
00194     {
00195       //Out::os() << "CloneView()" << endl;
00196       int numvecs = index.size();
00197       //Out::os() << "index size = " << numvecs << endl;
00198       //Out::os() << "input size = " << mv.size() << endl;
00199       TEUCHOS_TEST_FOR_EXCEPT(numvecs <= 0);
00200       TEUCHOS_TEST_FOR_EXCEPT((int) index.size() > mv.size());
00201 
00202 //      TEUCHOS_TEST_FOR_EXCEPT(detectRepeatedIndex(index));
00203 
00204       // create the new multivector
00205       RCP<  const _MV  > rtn = rcp(new _MV(numvecs));
00206 
00207       for (int i=0; i<numvecs; i++)
00208       {
00209         (*(rcp_const_cast<_MV>(rtn)))[i] = mv[index[i]]; // shallow copy
00210       }
00211       return rtn;
00212     }
00213 
00214   static RCP<const _MV> 
00215   CloneView (const _MV & mv, const Teuchos::Range1D& index) 
00216   {
00217     typedef std::vector<int>::size_type size_type;
00218     std::vector<int> ind (index.size ());
00219     for (size_type i = 0; i < static_cast<size_type> (index.size ()); ++i) {
00220       ind[i] = index.lbound () + i;
00221     }
00222     return CloneView (mv, ind);
00223   }
00224 
00225   //@}
00226 
00227   /** \name Attribute methods */
00228   //@{
00229 
00230   /** Obtain the vector length of \c mv. */
00231   static int GetVecLength( const  _MV & mv )
00232     {
00233       TEUCHOS_TEST_FOR_EXCEPT(mv.size() <= 0);
00234       return mv[0].space().dim(); 
00235     }
00236 
00237   /** Obtain the number of vectors in \c mv */
00238   static int GetNumberVecs( const  _MV & mv )
00239     {
00240       //Out::os() << "GetNumVec(" << mv.size() << ")" << endl;
00241       return mv.size(); 
00242     }
00243 
00244   //@}
00245 
00246   /** \name Update methods */
00247   //@{
00248 
00249   /*! \brief Update \c mv with \f$ \alpha A B + \beta mv \f$.
00250    */
00251   static void MvTimesMatAddMv( const double alpha, const  _MV & A, 
00252     const Teuchos::SerialDenseMatrix<int,double>& B, 
00253     const double beta,  _MV & mv )
00254     {
00255 //      Out::os() << "MvTimesMatAddMv()" << endl;
00256       int n = B.numCols();
00257 //      Out::os() << "B.numCols()=" << n << endl;
00258 
00259       TEUCHOS_TEST_FOR_EXCEPT(mv.size() != n);
00260 
00261       for (int j=0; j<mv.size(); j++)
00262       {
00263         Vector<double> tmp;
00264         if (beta==one())
00265         {
00266           tmp = mv[j].copy();
00267         }
00268         else if (beta==zero())
00269         {
00270           tmp = mv[j].copy();
00271           tmp.setToConstant(zero());
00272         }
00273         else
00274         {
00275           tmp = beta * mv[j];
00276         }
00277         if (alpha != zero())
00278         {
00279           for (int i=0; i<A.size(); i++)
00280           {
00281             tmp = tmp + alpha*B(i,j)*A[i];
00282           }
00283         }
00284         mv[j].acceptCopyOf(tmp);
00285       }
00286     }
00287 
00288   /*! \brief Replace \c mv with \f$\alpha A + \beta B\f$.
00289    */
00290   static void MvAddMv( const double alpha, const  _MV & A, 
00291     const double beta,  const  _MV & B,  _MV & mv )
00292     { 
00293       TEUCHOS_TEST_FOR_EXCEPT(A.size() != B.size());
00294       mv.resize(A.size());
00295       for (int i=0; i<A.size(); i++)
00296       {
00297         if (alpha==zero() && beta != zero()) mv[i]=beta*B[i];
00298         else if (beta==zero() && alpha != zero()) mv[i]=alpha*A[i];
00299         else if (alpha!=zero() && beta!=zero())
00300           mv[i]= alpha*A[i] + beta*B[i] ;
00301         else
00302         {
00303           mv[i].acceptCopyOf(A[i]);
00304           mv[i].setToConstant(zero());
00305         }
00306       }
00307     }
00308 
00309   /*! \brief Compute a dense matrix \c B through the matrix-matrix multiply \f$ \alpha A^Tmv \f$.
00310    */
00311   static void MvTransMv( const double alpha, const  _MV & A, const  _MV & mv, 
00312     Teuchos::SerialDenseMatrix<int,double>& B )
00313     { 
00314       // Create a multivector to hold the result (m by n)
00315       int m = A.size();
00316       int n = mv.size();
00317 //      B.shape(m, n);
00318       //Out::os() << "m=" << m << ", n=" << n << endl;
00319       for (int i=0; i<m; i++)
00320       {
00321         for (int j=0; j<n; j++)
00322         {
00323           B(i,j) = alpha * (A[i] * mv[j]);
00324         }
00325       }
00326     
00327     }
00328 
00329   /**
00330    * Dot product
00331   */
00332   static void MvDot( const  _MV & mv, const  _MV & A, std::vector<double> &b )
00333     {
00334       //Out::os() << "MvDot()" << endl;
00335       TEUCHOS_TEST_FOR_EXCEPT(mv.size() != A.size());
00336       b.resize(A.size());
00337       for (int i=0; i<mv.size(); i++) 
00338         b[i] = mv[i] * A[i];
00339     }
00340 
00341   /** Scale each element of the vectors in \c *this with \c alpha.
00342    */
00343   static void MvScale (  _MV & mv, const double alpha )
00344     { 
00345       //Out::os() << "MvScale()" << endl;
00346       for (int i=0; i<mv.size(); i++) mv[i].scale(alpha);
00347     }
00348     
00349   /** Scale each element of the \c i-th vector in \c *this with \c alpha[i].
00350    */
00351   static void MvScale (  _MV & mv, const std::vector<double>& alpha ) 
00352     { 
00353       //Out::os() << "MvScale() vector" << endl;
00354       for (int i=0; i<mv.size(); i++) mv[i].scale(alpha[i]);
00355     }
00356     
00357   //@}
00358 
00359   /** \name Norm method */
00360   //@{
00361 
00362   /** Compute the 2-norm of each individual vector of \c mv. */
00363   static void MvNorm( const  _MV & mv, 
00364     std::vector<Teuchos::ScalarTraits<double>::magnitudeType> &normvec )
00365     { 
00366 //      Out::os() << "MvNorm()" << endl;
00367       normvec.resize(mv.size());
00368       for (int i=0; i<mv.size(); i++) 
00369       {
00370         normvec[i] = mv[i].norm2();
00371         //      Out::os() << "i=" << i << " |v|=" << normvec[i] << endl;
00372       }
00373       
00374     }
00375 
00376   //@}
00377 
00378   /** \name Initialization methods */
00379   //@{
00380 
00381   /*! \brief Copy the vectors in \c A to a set of vectors in \c mv indicated by the indices given in \c index.
00382    */
00383   static void SetBlock( const  _MV & A, const std::vector<int>& index,  _MV & mv )
00384     { 
00385       //Out::os() << "SetBlock()" << endl;
00386       TEUCHOS_TEST_FOR_EXCEPT(A.size() < (int) index.size());
00387 //      mv.resize(index.size());
00388 //      TEUCHOS_TEST_FOR_EXCEPT(detectRepeatedIndex(index));
00389       for (unsigned int i=0; i<index.size(); i++)
00390       {
00391         mv[index[i]].acceptCopyOf(A[i]);
00392       }
00393     }
00394 
00395   //! Replace the vectors in \c mv with random vectors.
00396   static void MvRandom(  _MV & mv )
00397     { 
00398       for (int i=0; i<mv.size(); i++) mv[i].randomize(); 
00399     }
00400 
00401   //! Assign (deep copy) A into mv.
00402   static void Assign( const _MV& A, _MV& mv ) {
00403     for (unsigned int i = 0; i < mv.size(); ++i) {
00404       mv[i].acceptCopyOf (A[i]);
00405     }
00406   }
00407 
00408   //! Replace each element of the vectors in \c mv with \c alpha.
00409   static void MvInit(  _MV & mv, double alpha = Teuchos::ScalarTraits<double>::zero() )
00410     { 
00411       //Out::os() << "MvInit()" << endl;
00412       for (int i=0; i<mv.size(); i++) mv[i].setToConstant(alpha); 
00413     }
00414 
00415   //@}
00416 
00417   /** \name Print method */
00418   //@{
00419 
00420   /** Print the \c mv multi-vector to the \c os output stream. */
00421   static void MvPrint( const  _MV & mv, std::ostream& os )
00422     { 
00423       os << mv << std::endl;
00424     }
00425 
00426   //@}
00427 
00428 #ifdef HAVE_ANASAZI_TSQR
00429   /// \typedef tsqr_adaptor_type
00430   /// \brief TSQR adapter for the multivector type SimpleMV.
00431   ///
00432   /// For now, we provide a "stub" implementation.  It has the right
00433   /// methods and typedefs, but its constructors and methods all throw
00434   /// std::logic_error.  If you plan to use TSQR in Anasazi (e.g.,
00435   /// through TsqrOrthoManager) with SimpleMV, you must implement a
00436   /// functional TSQR adapter for SimpleMV.  Please refer to
00437   /// Epetra::TsqrAdapter (for Epetra_MultiVector) or
00438   /// Tpetra::TsqrAdaptor (for Tpetra::MultiVector) for examples of
00439   /// how to implement a TSQR adapter.
00440   typedef Anasazi::details::StubTsqrAdapter<SimpleMV> tsqr_adaptor_type;
00441 #endif // HAVE_ANASAZI_TSQR
00442 
00443   /** */
00444   static bool detectRepeatedIndex(const std::vector<int>& index)
00445     {
00446       std::set<int> s;
00447       bool rtn = false;
00448 
00449       for (unsigned int i=0; i<index.size(); i++)
00450       {
00451         if (s.find(index[i]) != s.end())
00452         {
00453           //Out::os() << "detected repeated index " << index[i] << endl;
00454           rtn = true;
00455         }
00456         s.insert(index[i]);
00457       }
00458       
00459       return rtn;
00460     }
00461 
00462 };        
00463 
00464 
00465 /**
00466 
00467 */
00468 template <>  
00469 class OperatorTraits < double, SimpleMV, LinearOperator<double> >
00470 {
00471 public:
00472   typedef SimpleMV _MV;  
00473   /**
00474   */    
00475   static void Apply ( 
00476     const LinearOperator< double >& Op, 
00477     const  _MV & x,  
00478     _MV & y )
00479     {
00480       //Out::os() << "Apply()" << endl;
00481       y.resize(x.size());
00482       for (int i=0; i<x.size(); i++) 
00483       {
00484 //        y[i] = Op * x[i];
00485         y[i].acceptCopyOf(Op * x[i]);
00486 //        Out::os() << "i=" << i << " x=" << endl;
00487 //        Out::os() << x[i] << endl;
00488 //        Out::os() << "i=" << i << " y=" << endl;
00489 //        Out::os() << y[i] << endl;
00490 //        TEUCHOS_TEST_FOR_EXCEPT(x[i].norm2() < 1.0e-12);
00491       }
00492     }
00493     
00494 };
00495 
00496 
00497 
00498 } // end of Anasazi namespace 
00499 
00500 #endif 

Site Contact