PlayaVectorDecl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 //   
00003  /* @HEADER@ */
00004 
00005 #ifndef PLAYA_VECTORDECL_HPP
00006 #define PLAYA_VECTORDECL_HPP
00007 
00008 #include "PlayaDefs.hpp"
00009 #include "PlayaHandle.hpp"
00010 #include "PlayaVectorBaseDecl.hpp"
00011 #include "PlayaVectorSpaceDecl.hpp"
00012 #include "PlayaVectorFunctorsDecl.hpp"
00013 #include "Teuchos_TimeMonitor.hpp"
00014 
00015 namespace Playa
00016 {
00017 
00018 template <class Scalar, int> class LCN;
00019   
00020 /** 
00021  * User-level vector class. 
00022  *
00023  * <h2> Vector creation </h2>
00024  *
00025  * Ordinarily, you will never construct a Vector directly
00026  * from a derived type.  Rather, the createMember() method of
00027  * VectorSpace is used to build a vector of the appropriate
00028  * type, for example,
00029  * \code
00030  * VectorType<double> vecType = new EpetraVectorType();
00031  * int dimension = 100;
00032  * VectorSpace<double> space = vecType.createSpace(dimension);
00033  * Vector<double> x = space.createMember();
00034  * Vector<double> y = space.createMember();
00035  * \endcode
00036  * This hides from you all the ugly
00037  * details of creating a particular concrete type.
00038  *
00039  * You will frequently create an empty vector to be filled in later,
00040  * for example,
00041  * \code
00042  * Vector<double> y;
00043  * \endcode
00044  * Note that this vector isn't just empty, it's null. Not only does
00045  * it have no values assigned, it does not have a concrete type. An
00046  * call a method on a null vector will result in an error. What you
00047  * <it>can</it> do with a null vector is
00048  * <ul>
00049  * <li> assign another vector to it
00050  * \code
00051  * Vector<double> x = space.createVector();
00052  * Vector<Scalar> y;
00053  * y = x.copy();
00054  * \endcode
00055  * <li> assign the result of a vector operation to it
00056  * \code
00057  * Vector<Scalar> z = a*x + b*y;
00058  * \endcode
00059  *
00060  * <h2> Vector creation </h2>
00061  */
00062 template <class Scalar>
00063 class Vector : public Playa::Handle<VectorBase<Scalar> >
00064 {
00065 public:
00066   /** \name Constructors, Destructors, and Assignment Operators */
00067   //@{
00068   HANDLE_CTORS(Vector<Scalar>, VectorBase<Scalar>);
00069 
00070   /** \brief Construct a vector from an N-term LC */
00071   template <int N>
00072   Vector<Scalar>(const LCN<Scalar, N>& x);
00073 
00074 
00075   /**  \brief Assign a one-term LC to this vector */
00076   Vector<Scalar>& operator=(const LCN<Scalar, 1>& x);
00077 
00078   /**  \brief Assign a two-term LC to this vector */
00079   Vector<Scalar>& operator=(const LCN<Scalar, 2>& x);
00080 
00081   /**  \brief Assign a three-term LC to this vector */
00082   Vector<Scalar>& operator=(const LCN<Scalar, 3>& x);
00083 
00084   /**  \brief Assign an N-term LC to this vector */
00085   template <int N>
00086   Vector<Scalar>& operator=(const LCN<Scalar, N>& x);
00087 
00088   //@}
00089 
00090   /** \name Operators with assignment */
00091   //@{
00092   /** Add a vector into this vector */
00093   Vector<Scalar>& operator+=(const Vector<Scalar>& other);
00094 
00095   /** Add a one-term LC into this vector */
00096   Vector<Scalar>& operator+=(const LCN<Scalar, 1>& x);
00097 
00098   /** Add a two-term LC into this vector */
00099   Vector<Scalar>& operator+=(const LCN<Scalar, 2>& x);
00100 
00101   /** Add an N-term LC into this vector */
00102   template <int N>
00103   Vector<Scalar>& operator+=(const LCN<Scalar, N>& x);
00104 
00105   /** Subtract a vector from this vector */
00106   Vector<Scalar>& operator-=(const Vector<Scalar>& other);
00107 
00108   /** Subtract a one-term LC from this vector */
00109   Vector<Scalar>& operator-=(const LCN<Scalar, 1>& x);
00110 
00111   /** Subtract a two-term LC from this vector */
00112   Vector<Scalar>& operator-=(const LCN<Scalar, 2>& x);
00113 
00114   /** Subtract an N-term LC from this vector */
00115   template <int N>
00116   Vector<Scalar>& operator-=(const LCN<Scalar, N>& x);
00117 
00118   /** Scale by a constant */
00119   Vector<Scalar>& operator*=(const Scalar& a);
00120 
00121   /** Divide by a constant */
00122   Vector<Scalar>& operator/=(const Scalar& a);
00123   //@}
00124 
00125   /** \name Structural information */
00126   //@{
00127   /**  \brief My space */
00128   VectorSpace<Scalar> space() const 
00129     {return this->ptr()->space();}
00130 
00131   /**  \brief My communicator */
00132   const MPIComm& comm() const 
00133     {return this->space().comm();}
00134 
00135   /**  \brief My dimension  */
00136   int dim() const
00137     {
00138       return this->ptr()->space()->dim();
00139     }
00140   //@}
00141       
00142 
00143   /** \name Block operations */
00144   //@{
00145   /**  \brief get number of blocks */
00146   int numBlocks() const ;
00147 
00148   /**  \brief set the i-th block  */
00149   void setBlock(int i, const Vector<Scalar>& v);
00150       
00151   /**  \brief get the i-th block */
00152   const Vector<Scalar>& getBlock(int i) const;
00153       
00154   /**  \brief get the i-th block */
00155   Vector<Scalar> getNonConstBlock(int i) ;
00156       
00157   /**  \brief get the i-th block */
00158   const Vector<Scalar>& getBlock(const BlockIterator<Scalar>& b) const;
00159       
00160   /**  \brief get the i-th block */
00161   Vector<Scalar> getNonConstBlock(const BlockIterator<Scalar>& b);
00162   //@}
00163 
00164 
00165 
00166   /** \name Sequential data accessors */
00167   //@{
00168   /**  \brief Get the next chunk of values for read-only access */
00169   ConstDataChunk<Scalar> nextConstChunk() const ;
00170     
00171   /**  \brief Get the next chunk of values for read-write access */
00172   NonConstDataChunk<Scalar> nextChunk() ;
00173 
00174   /**  \brief Tell whether there are more chunks remaining to be accessed */
00175   bool hasMoreChunks() const ;
00176 
00177   /**  \brief Reset the data stream back to a state where all chunks are
00178    * considered unread. */
00179   void rewind() const ;
00180   //@}
00181 
00182   /** \name Random access to local elements */
00183   //@{
00184   /**  \brief const bracket operator for read-only random access to
00185    * local elements as specified by
00186    * a flat index that runs from 0 to space().numLocalElements(). 
00187    * If the vector does not consist of a single contiguous data chunk,
00188    * this might be slow (worst case would be O(N), if every element
00189    * is stored in its own chunk of length 1). 
00190    */
00191   const Scalar& operator[](int localIndex) const ;
00192     
00193   /**  \brief non-const bracket operator for read-write random access to
00194    * local elements as specified by
00195    * a flat index that runs from 0 to space().numLocalElements(). 
00196    * If the vector does not consist of a single contiguous data chunk,
00197    * this might be slow (worst case would be O(N), if every element
00198    * is stored in its own chunk of length 1). 
00199    */
00200   Scalar& operator[](int localIndex);
00201 
00202   /** \brief  parentheses operator for read-only random access to
00203    * local elements as specified by 
00204    * a block iterator and a flat index indicating the
00205    * element's location within that block. 
00206    */
00207   const Scalar& operator()(const BlockIterator<Scalar>& b,
00208     int localIndexWithinBlock) const ;
00209     
00210 /** \brief  parentheses operator for read-write random access to
00211    * local elements as specified by 
00212    * a block iterator and a flat index indicating the
00213    * element's location within that block. 
00214    */
00215   Scalar& operator()(const BlockIterator<Scalar>& b,
00216     int localIndexWithinBlock) ;
00217   //@}
00218 
00219   /** \name Diagnostic output */
00220   //@{
00221   /**  \brief Return a short string description of the vector */
00222   std::string description() const ;
00223 
00224   /** \brief  Print the vector in some detail */
00225   void print(std::ostream& os) const ;    
00226   //@}
00227 
00228 
00229   /** \name Math operations */
00230   //@{
00231   /** \brief  Multiply this vector by a constant scalar factor 
00232    * \code
00233    * this = alpha * this;
00234    * \endcode
00235    */
00236   Vector<Scalar>& scale(const Scalar& alpha);
00237 
00238   /** 
00239    *  \brief Add a scaled vector to this vector times a constant:
00240    * \f$ this=\alpha x + \gamma \,this. \f$
00241    */
00242   Vector<Scalar>& update(const Scalar& alpha, const Vector<Scalar>& x, 
00243     const Scalar& gamma=1.0);
00244   /** 
00245    * \brief  Add two scaled vectors to this vector times a constant:
00246    * \f$ this=\alpha x + \beta y + \gamma \, this. \f$
00247    */
00248   Vector<Scalar>& update(const Scalar& alpha, const Vector<Scalar>& x, 
00249     const Scalar& beta, const Vector<Scalar>& y, 
00250     const Scalar& gamma);
00251   /** 
00252    * \brief  Add three scaled vectors to this vector times a constant:
00253    * \f$ this=\alpha x + \beta y + \gamma x + \delta \, this. \f$
00254    */
00255   Vector<Scalar>& update(const Scalar& alpha, const Vector<Scalar>& x, 
00256     const Scalar& beta, const Vector<Scalar>& y, 
00257     const Scalar& gamma, const Vector<Scalar>& z, 
00258     const Scalar& delta);
00259 
00260   /** 
00261    *  \brief Copy the values of another vector into this vector
00262    * \code
00263    * this = x
00264    * \endcode
00265    */
00266   Vector<Scalar>& acceptCopyOf(const Vector<Scalar>& x);
00267 
00268   /** 
00269    * \brief  Create a new vector that is a copy of this vector 
00270    */
00271   Vector<Scalar> copy() const ;
00272 
00273   /** 
00274    * \brief  In-place element-by-element product (Matlab dot-star operator)
00275    */
00276   Vector<Scalar>& selfDotStar(const Vector<Scalar>& other) ;
00277 
00278   /** 
00279    * \brief  In-place element-by-element division (Matlab dot-slash operator)
00280    */
00281   Vector<Scalar>& selfDotSlash(const Vector<Scalar>& other) ;
00282 
00283   /** 
00284    * \brief  Element-by-element product (Matlab dot-star operator)
00285    */
00286   Vector<Scalar> dotStar(const Vector<Scalar>& other) const ;
00287 
00288   /** 
00289    *  \brief Element-by-element division (Matlab dot-slash operator)
00290    */
00291   Vector<Scalar> dotSlash(const Vector<Scalar>& other) const ;
00292 
00293   /** 
00294    * \brief  Return element-by-element reciprocal as a new vector
00295    */
00296   Vector<Scalar> reciprocal() const ;
00297 
00298 
00299   /** 
00300    * \brief  Return element-by-element absolute value as a new vector
00301    */
00302   Vector<Scalar> abs() const ;
00303 
00304   /** 
00305    * \brief  Overwrite self with element-by-element reciprocal
00306    */
00307   Vector<Scalar>& selfReciprocal() ;
00308 
00309   /** 
00310    *  \brief Overwrite self with element-by-element absolute value 
00311    */
00312   Vector<Scalar>& selfAbs() ;
00313 
00314   /** 
00315    *  \brief Overwrite self with random values
00316    */
00317   Vector<Scalar>& randomize() ;
00318 
00319   /** 
00320    *  \brief Set all elements to a constant value
00321    */
00322   void setToConstant(const Scalar& alpha) ;
00323 
00324       
00325   /** 
00326    *  \brief Take dot product with another vector
00327    */
00328   Scalar dot(const Vector<Scalar>& other) const ;
00329 
00330   /** 
00331    * \brief  Overloaded operator for dot product 
00332    */
00333   Scalar operator*(const Vector<Scalar>& other) const ;
00334 
00335   /**
00336    *  \brief Compute the 1-norm of this vector
00337    */
00338   Scalar norm1() const ;
00339 
00340   /**
00341    *  \brief Compute the 2-norm of this vector
00342    */
00343   Scalar norm2() const ;
00344 
00345   /**
00346    *  \brief Compute the weighted 2-norm of this vector
00347    */
00348   Scalar norm2(const Vector<Scalar>& weights) const ;    
00349 
00350 
00351   /**
00352    *  \brief Compute the infinity-norm of this vector
00353    */
00354   Scalar normInf() const ;
00355 
00356   /**
00357    *  \brief Set all elements to zero 
00358    */
00359   void zero();
00360 
00361 
00362   /**  \brief Return the max element */
00363   Scalar max() const;
00364 
00365   /**  \brief Return the min element */
00366   Scalar min()const;
00367 
00368 
00369   //@}
00370 
00371 
00372 
00373 
00374   /**  \brief Get a stopwtach for timing vector operations */
00375   static RCP<Time>& opTimer()
00376     {
00377       static RCP<Time> rtn 
00378         = TimeMonitor::getNewTimer("Low-level vector operations");
00379       return rtn;
00380     }
00381 
00382   /** \name Functor application */
00383   //@{
00384 
00385   /**  \brief Apply a unary functor, overwriting this vector with the results */
00386   template <class UF> 
00387   Vector<Scalar>& applyUnaryFunctor(const UF& functor);
00388 
00389   /**  \brief Apply a unary functor to another vector, writing the results
00390       into this vector. The other vector is unchanged. */
00391   template <class UF> 
00392   Vector<Scalar>& acceptUnaryFunctor(const UF& functor,
00393     const Vector<Scalar>& other);
00394 
00395   /**  \brief Apply a binary functor to this vector and another vector, 
00396       writing the results
00397       into this vector. The other vector is unchanged. */
00398   template <class VF> 
00399   Vector<Scalar>& applyBinaryFunctor(const VF& functor,
00400     const Vector<Scalar>& other);
00401 
00402   /** \brief Apply a ternary functor to this vector and two other vectors, 
00403       writing the results
00404       into this vector. The other vectors are unchanged. */
00405   template <class VF> 
00406   Vector<Scalar>& applyTernaryFunctor(const VF& functor,
00407     const Vector<Scalar>& x, const Vector<Scalar>& y);
00408 
00409   /** \brief Apply a unary reduction functor */
00410   template <class RF> 
00411   typename PlayaFunctors::VectorFunctorTraits<Scalar, RF>::ReturnType 
00412   applyUnaryReductionFunctor(
00413     const RF& functor)
00414     const ;
00415 
00416   /** \brief Apply a binary reduction functor */
00417   template <class RF> 
00418   typename PlayaFunctors::VectorFunctorTraits<Scalar, RF>::ReturnType 
00419   applyBinaryReductionFunctor(const RF& functor, const Vector<Scalar>& other)
00420     const ;
00421     
00422 
00423     
00424   //@}
00425     
00426 protected:
00427 
00428   /** get a subblock as specified by a deque of indices */
00429   const Vector<Scalar>& getBlock(const std::deque<int>& iter) const ;
00430 
00431   /** get a non-const subblock as specified by a deque of indices */
00432   Vector<Scalar> getNonConstBlock(const std::deque<int>& iter) ;
00433   
00434 
00435 private:
00436 
00437 };
00438 
00439 
00440 template <class Scalar> class LoadableVector;
00441 /** \relates Vector \brief Dynamic cast a Vector's underlying pointer to 
00442 a LoadableVector. */
00443 template <class Scalar>
00444 LoadableVector<Scalar>* loadable(Vector<Scalar> vec) ;
00445 
00446 
00447 /** \relates Vector \brief Return a pointer to the beginning of the vector's
00448 single data chunk. If the underlying VectorBase is not a SingleChunkVector
00449 an exception will be thrown. */
00450 template <class Scalar>
00451 Scalar* dataPtr(Vector<Scalar> vec) ;
00452 
00453 /** \relates Vector \brief Return a pointer to the beginning of the vector's
00454 single data chunk. If the underlying VectorBase is not a SingleChunkVector
00455 an exception will be thrown. */
00456 template <class Scalar>
00457 const Scalar* dataPtr(const Vector<Scalar>& vec) ;
00458 
00459 
00460 }
00461 
00462 template <class Scalar> inline
00463 std::ostream& operator<<(std::ostream& os, const Playa::Vector<Scalar>& x) 
00464 {
00465   x.print(os);
00466   return os;
00467 }
00468 
00469 
00470 
00471 
00472 #endif

Site Contact