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

Site Contact