TSFVectorDecl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // **********************************************************************/
00027  /* @HEADER@ */
00028 
00029 #ifndef TSFVECTORDECL_HPP
00030 #define TSFVECTORDECL_HPP
00031 
00032 #include "SundanceDefs.hpp"
00033 #include "SundanceHandle.hpp"
00034 #include "Thyra_VectorBase.hpp"
00035 #include "Thyra_VectorSpaceBase.hpp"
00036 #include "TSFVectorSpaceDecl.hpp"
00037 #include "TSFLoadableVector.hpp"
00038 #include "TSFAccessibleVector.hpp"
00039 #include "TSFRawDataAccessibleVector.hpp"
00040 #include "Thyra_VectorStdOps.hpp"
00041 #include "Teuchos_TimeMonitor.hpp"
00042 
00043 #ifdef TRILINOS_6
00044 #include "Thyra_ProductVector.hpp"
00045 #else
00046 #include "Thyra_DefaultProductVector.hpp"
00047 #include "Thyra_VectorStdOps.hpp"
00048 #endif
00049 
00050 namespace TSFExtendedOps
00051 {
00052 template <class Scalar, class Node1, class Node2> class LC2;
00053 template <class Scalar, class Node> class OpTimesLC; 
00054 /** 
00055  * 
00056  */
00057 enum LCSign {LCAdd = 1, LCSubtract = -1};
00058 }
00059 
00060 namespace TSFExtended
00061 {
00062   
00063 
00064   /** 
00065    * User-level vector class. 
00066    *
00067    * <h2> Creating vectors </h2>
00068    *
00069    * Ordinarily, you will never construct a Vector directly
00070    * from a derived type.  Rather, the createMember() method of
00071    * VectorSpace is used to build a vector of the appropriate
00072    * type, for example,
00073    * \code 
00074    * VectorType<double> vecType = new EpetraVectorType();
00075    * int dimension = 100;
00076    * VectorSpace<double> space = vecType.createSpace(dimension);
00077    * Vector<double> x = space.createMember(); 
00078    * Vector<double> y = space.createMember(); 
00079    * \endcode 
00080    * This hides from you all the ugly
00081    * details of creating a particular concrete type.
00082    *
00083    * You will frequently create an empty vector to be filled in later, 
00084    * for example,
00085    * \code
00086    * Vector<double> y;
00087    * \endcode
00088    * Note that this vector isn't just empty, it's null. Not only does 
00089    * it have no values assigned, it does not have a concrete type. An 
00090    * call a method on a null vector will result in an error. What you 
00091    * <it>can</it> do with a null vector is
00092    * <ul>
00093    * <li> assign another vector to it
00094    * \code
00095    * Vector<double> x = space.createVector();
00096    * Vector<Scalar> y;
00097    * y = x.copy();
00098    * \endcode
00099    * <li> assign the result of a vector operation to it
00100    * \code
00101    * Vector<Scalar> z = a*x + b*y;
00102    * \endcode
00103    */
00104   template <class Scalar>
00105   class Vector : public Sundance::Handle<Thyra::VectorBase<Scalar> >
00106   {
00107   public:
00108     /** \name Constructors, Destructors, and Assignment Operators */
00109     //@{
00110     HANDLE_CTORS(Vector<Scalar>, Thyra::VectorBase<Scalar>);
00111 
00112     /** Construct a vector from a 2-term LC */
00113     template<class Node1, class Node2>
00114     Vector(const TSFExtendedOps::LC2<Scalar, Node1, Node2>& x);
00115 
00116     /** Construct a vector from an operator times a linear combination */
00117     template<class Node>
00118     Vector(const TSFExtendedOps::OpTimesLC<Scalar, Node>& x);
00119 
00120     /** Assign a linear combination of vectors to this vector */
00121     template<class Node1, class Node2>
00122     Vector& operator=(const TSFExtendedOps::LC2<Scalar, Node1, Node2>& x);
00123 
00124     /** Assign a scaled linear combination to this vector */
00125     template<class Node>
00126     Vector& operator=(const TSFExtendedOps::OpTimesLC<Scalar, Node>& x);
00127     //@}
00128 
00129     /** */
00130     VectorSpace<Scalar> space() const 
00131     {return this->ptr()->space();}
00132 
00133     /** Return the dimension of the vector  */
00134     int dim() const
00135     {
00136       return this->ptr()->space()->dim();
00137     }
00138       
00139 
00140     /** \name ProductVector operations */
00141     //@{
00142 
00143     /** set block  */
00144     void setBlock(int i, const Vector<Scalar>& v);
00145       
00146     /** get block */
00147     Vector<Scalar> getBlock(int i) const;
00148 
00149     //const Vector<Scalar> getBlock(int i) const;
00150 
00151     /** \name Math operations */
00152     //@{
00153     /** Multiply this vector by a constant scalar factor 
00154      * \code
00155      * this = alpha * this;
00156      * \endcode
00157      */
00158     Vector<Scalar>& scale(const Scalar& alpha);
00159 
00160     /** 
00161      * Add a scaled vector to this vector:
00162      * \code
00163      * this = this + alpha*x 
00164      * \endcode
00165      */
00166     Vector<Scalar>& update(const Scalar& alpha, const Vector<Scalar>& x);
00167 
00168     /** 
00169      * Add a scaled vector to this vector times a constant:
00170      * \code
00171      * this = gamma*this + alpha*x 
00172      * \endcode
00173      */
00174     Vector<Scalar>& update(const Scalar& alpha, const Vector<Scalar>& x, 
00175                            const Scalar& gamma);
00176     /** 
00177      * Add two scaled vectors to this vector times a constant:
00178      * \code
00179      * this = alpha*x + beta*y + gamma*this
00180      * \endcode
00181      */
00182     Vector<Scalar>& update(const Scalar& alpha, const Vector<Scalar>& x, 
00183                            const Scalar& beta, const Vector<Scalar>& y, 
00184                            const Scalar& gamma);
00185 
00186     /** 
00187      * Copy the values of another vector into this vector
00188      * \code
00189      * this = x
00190      * \endcode
00191      */
00192     Vector<Scalar>& acceptCopyOf(const Vector<Scalar>& x);
00193 
00194     /** 
00195      * Create a new vector that is a copy of this vector 
00196      */
00197     Vector<Scalar> copy() const ;
00198 
00199     /** 
00200      * Element-by-element product (Matlab dot-star operator)
00201      */
00202     Vector<Scalar> dotStar(const Vector<Scalar>& other) const ;
00203 
00204     /** 
00205      * Write the elementwise product of \f$a\f$ and \f$b\f$ into
00206      * <t>this.</t>
00207      */
00208     void dotStarInto(const Vector<Scalar>& a, const Vector<Scalar>& b) const ;
00209 
00210     /** 
00211      * Element-by-element division (Matlab dot-slash operator)
00212      */
00213     Vector<Scalar> dotSlash(const Vector<Scalar>& other) const ;
00214 
00215     /** 
00216      * Return element-by-element reciprocal as a new vector
00217      */
00218     Vector<Scalar> reciprocal() const ;
00219 
00220 
00221     /** 
00222      * Return element-by-element absolute value as a new vector
00223      */
00224     Vector<Scalar> abs() const ;
00225 
00226     /** 
00227      * Overwrite self with element-by-element reciprocal
00228      */
00229     Vector<Scalar>& reciprocal() ;
00230 
00231     /** 
00232      * Overwrite self with element-by-element absolute value 
00233      */
00234     Vector<Scalar>& abs() ;
00235 
00236     /** 
00237      * Set all elements to a constant value
00238      */
00239     void setToConstant(const Scalar& alpha) ;
00240 
00241       
00242     /** 
00243      * Take dot product with another vector
00244      */
00245     Scalar dot(const Vector<Scalar>& other) const ;
00246 
00247     /** 
00248      * Overloaded operator for dot product 
00249      */
00250     Scalar operator*(const Vector<Scalar>& other) const ;
00251 
00252     /**
00253      * Compute the 1-norm of this vector
00254      */
00255     Scalar norm1() const ;
00256 
00257     /**
00258      * Compute the 2-norm of this vector
00259      */
00260     Scalar norm2() const ;
00261 
00262     /**
00263      * Compute the weighted 2-norm of this vector
00264      */
00265     Scalar norm2(const Vector<Scalar>& weights) const ;    
00266 
00267 
00268     /**
00269      * Compute the infinity-norm of this vector
00270      */
00271     Scalar normInf() const ;
00272 
00273     /**
00274      * Set all elements to zero 
00275      */
00276     void zero();
00277 
00278 
00279     /** Retuen the max element */
00280     Scalar max() const;
00281 
00282     /** Return the max element and the corresponding index */
00283     Scalar max(int& index)const;
00284 
00285     /** Return the max element less than bound and the corresponding index */
00286     Scalar max(const Scalar& bound, int& index)const;
00287 
00288     /** Retuen the min element */
00289     Scalar min()const;
00290 
00291     /** Return the min element and the corresponding index */
00292     Scalar min(int& index)const;
00293 
00294     /** Return the min element greater than bound and the corresponding index */
00295     Scalar min(const Scalar& bound, int& index)const;
00296 
00297 
00298 
00299     //@}
00300 
00301 
00302     /** \name Element loading interface */
00303     //@{
00304     /** set a single element at the given global index */
00305     void setElement(OrdType globalIndex, const Scalar& value) ;
00306 
00307     /** add to the existing value of 
00308      * a single element at the given global index */
00309     void addToElement(OrdType globalIndex, const Scalar& value) ;
00310 
00311     /** set a group of elements */
00312     void setElements(OrdType numElems, const OrdType* globalIndices, 
00313                      const Scalar* values) 
00314     {castToLoadable()->setElements(numElems, globalIndices, values);}
00315 
00316     /** add to a group of elements */
00317     void addToElements(OrdType numElems, const OrdType* globalIndices, 
00318                        const Scalar* values)
00319     {castToLoadable()->addToElements(numElems, globalIndices, values);}
00320 
00321     /** Do whatever finalization steps are needed by the implementation,
00322         for instance, synchronizing border elements. The default implementation
00323         * is a no-op. */
00324     void finalizeAssembly() {castToLoadable()->finalizeAssembly();}
00325     //@}
00326 
00327     /** \name Element access interface */
00328     //@{
00329     /** get the element at the given global index */
00330     Scalar getElement(OrdType globalIndex) const ;
00331     //{return castToAccessible()->getElement(globalIndex);}
00332 
00333     /** Get a batch of elements */
00334     void getElements(const int* globalIndices, int numElems,
00335       Teuchos::Array<Scalar>& elems) const 
00336       {castToAccessible()->getElements(globalIndices, numElems, elems);}
00337 
00338 
00339     /** const bracket operator  */
00340     const Scalar& operator[](const SequentialIterator<Scalar>& index) const ;
00341     
00342     /** non - const bracket operator  */
00343     Scalar& operator[](const SequentialIterator<Scalar>& index);
00344 
00345     //@}
00346 
00347     /** \name Raw data access interface */
00348     //@{
00349     /** */
00350     const Scalar* dataPtr() const 
00351     {return castToRawDataAccessible()->dataPtr();}
00352 
00353     /** */
00354     Scalar* dataPtr() 
00355     {return castToRawDataAccessible()->dataPtr();}
00356     //@}
00357 
00358 
00359 
00360     /** Get a stopwtach for timing vector operations */
00361     static RCP<Time>& opTimer()
00362     {
00363       static RCP<Time> rtn 
00364         = TimeMonitor::getNewTimer("Low-level vector operations");
00365       return rtn;
00366     }
00367 
00368     
00369 
00370     Vector<Scalar> eval() const {return copy();}
00371 
00372     bool containsVector(const Thyra::VectorBase<Scalar>* vec) const
00373     {return this->ptr().get()==vec;}
00374 
00375     void evalInto(Vector<Scalar>& other) const {other.acceptCopyOf(*this);}
00376 
00377     void addInto(Vector<Scalar>& other, TSFExtendedOps::LCSign sign) const
00378     {
00379       other.update(sign, *this);
00380     }
00381 
00382     /** Describe the vector  */
00383     std::string description() const
00384     {
00385       const Describable* d = 
00386         dynamic_cast<const Describable* >(this->ptr().get());
00387       if (d != 0)
00388         {
00389           return d->description();
00390         }
00391       return "Vector not describable";
00392     }
00393 
00394     void print(std::ostream& os) const ;
00395     
00396 
00397   private:
00398 
00399     /** Cross-cast vector pointer to an accessible vector */
00400     const AccessibleVector<Scalar>* castToAccessible() const ;
00401 
00402     /** Cross-cast vector to a loadable vector */
00403     LoadableVector<Scalar>* castToLoadable()  ;
00404 
00405     /** Cross-cast vector pointer to a raw data accessible vector */
00406     const RawDataAccessibleVector<Scalar>* castToRawDataAccessible() const ;
00407 
00408     /** Cross-cast vector to a raw data accessible vector */
00409     RawDataAccessibleVector<Scalar>* castToRawDataAccessible();
00410 
00411     /** Test for valid index */
00412     void boundscheck(OrdType i, int dim) const ;
00413 
00414     /** */
00415     const Scalar& localElement(const OrdType& blockIndex, const OrdType& indexInBlock) const ;
00416 
00417     /** */
00418     Scalar& localElement(const OrdType& blockIndex, const OrdType& indexInBlock) ;
00419       
00420       
00421   };
00422 }
00423 
00424 template <class Scalar> inline
00425 std::ostream& operator<<(std::ostream& os, const TSFExtended::Vector<Scalar>& x) 
00426 {
00427   x.print(os);
00428   return os;
00429 }
00430 
00431 
00432 
00433 
00434 #endif

Site Contact