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

Site Contact