fvector.hh

Go to the documentation of this file.
00001 // $Id: fvector.hh 5328 2008-10-28 10:01:54Z robertk $
00002 #ifndef DUNE_FVECTOR_HH
00003 #define DUNE_FVECTOR_HH
00004 
00005 #include<cmath>
00006 #include<cstdlib>
00007 #include<cstddef>
00008 #include<complex>
00009 
00010 #include "exceptions.hh"
00011 #include "genericiterator.hh"
00012 
00013 #ifdef DUNE_EXPRESSIONTEMPLATES
00014 #include "exprtmpl.hh"
00015 #endif
00016 
00017 namespace Dune {
00018 
00019 #ifndef DUNE_EXPRESSIONTEMPLATES
00020   
00031   // forward declaration of template
00032   template<class K, int n> class FieldVector;
00033 
00034 #endif
00035   
00036 #ifndef DUNE_EXPRESSIONTEMPLATES
00037   
00038   template<class K>
00039   inline double fvmeta_absreal (const K& k)
00040   {
00041       return std::abs(k);
00042   }
00043 
00044   template<class K>
00045   inline double fvmeta_absreal (const std::complex<K>& c)
00046   {
00047         return fvmeta_abs(c.real()) + fvmeta_abs(c.imag());
00048   }
00049 
00050   template<class K>
00051   inline double fvmeta_abs2 (const K& k)
00052   {
00053         return k*k;
00054   }
00055 
00056   template<class K>
00057   inline double fvmeta_abs2 (const std::complex<K>& c)
00058   {
00059         return c.real()*c.real() + c.imag()*c.imag();
00060   }
00061 
00062 #endif
00063 
00065   template<class C, class T>
00066   class FieldIterator : 
00067     public Dune::RandomAccessIteratorFacade<FieldIterator<C,T>,T, T&, int>
00068   {
00069     friend class FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >;
00070     friend class FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >;
00071     
00072   public:
00073     
00077     typedef std::ptrdiff_t DifferenceType;
00078     
00079     // Constructors needed by the base iterators.
00080     FieldIterator()
00081       : container_(0), position_(0)
00082       {}
00083     
00084     FieldIterator(C& cont, DifferenceType pos)
00085       : container_(&cont), position_(pos)
00086       {}
00087     
00088     FieldIterator(const FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >& other)
00089       : container_(other.container_), position_(other.position_)
00090       {}
00091     
00092 #if 0    
00093     FieldIterator(const FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >& other)
00094       : container_(other.container_), position_(other.position_)
00095       {}
00096 #endif
00097 #if 0
00098     FieldIterator(const FieldIterator<C,T>& other)
00099       : container_(other.container_), position_(other.position_)
00100       {}
00101 #endif
00102     // Methods needed by the forward iterator
00103     bool equals(const FieldIterator<typename remove_const<C>::type,typename remove_const<T>::type>& other) const
00104       {
00105         return position_ == other.position_ && container_ == other.container_;
00106       }
00107     
00108     
00109     bool equals(const FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type>& other) const
00110       {
00111         return position_ == other.position_ && container_ == other.container_;
00112       }
00113     
00114     T& dereference() const{
00115       return container_->operator[](position_);
00116     }
00117     
00118     void increment(){
00119       ++position_;
00120     }
00121     
00122     // Additional function needed by BidirectionalIterator
00123     void decrement(){
00124       --position_;
00125     }
00126     
00127     // Additional function needed by RandomAccessIterator
00128     T& elementAt(DifferenceType i)const{
00129       return container_->operator[](position_+i);
00130     }
00131     
00132     void advance(DifferenceType n){
00133       position_=position_+n;
00134     }
00135     
00136     std::ptrdiff_t distanceTo(FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type> other)const
00137       {
00138         assert(other.container_==container_);
00139         return other.position_ - position_;
00140       }
00141     
00142     std::ptrdiff_t distanceTo(FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type> other)const
00143       {
00144         assert(other.container_==container_);
00145         return other.position_ - position_;
00146       }
00147     
00149     DifferenceType index () const
00150       {
00151         return this->position_;
00152       }
00153     
00154   private:
00155     C *container_;
00156     DifferenceType position_;
00157   };
00158 
00160   template<class T>
00161   struct IteratorType
00162   {
00163     typedef typename T::Iterator type;
00164   };
00165   
00166   template<class T>
00167   struct IteratorType<const T>
00168   {
00169     typedef typename T::ConstIterator type;
00170   };
00171   
00172 #ifdef DUNE_EXPRESSIONTEMPLATES
00174   template<class V>
00175   class FlatIterator :
00176     public ForwardIteratorFacade<FlatIterator<V>,
00177                                  typename Dune::FieldType<V>::type,
00178                                  typename Dune::FieldType<V>::type&,
00179                                  int>
00180   {
00181   public:
00182     typedef typename IteratorType<V>::type BlockIterator;
00183     typedef std::ptrdiff_t DifferenceType;
00184 //    typedef typename BlockIterator::DifferenceType DifferenceType;
00185     typedef typename BlockType<V>::type block_type;
00186     typedef typename FieldType<V>::type field_type;
00187     typedef FlatIterator<block_type> SubBlockIterator;
00188     FlatIterator(const BlockIterator & i) :
00189       it(i), bit(i->begin()), bend(i->end()) {};
00190     void increment ()
00191       {
00192         ++bit;
00193         if (bit == bend)
00194         {
00195           ++it;
00196           bit = it->begin();
00197           bend = it->end();
00198         }
00199       }
00200     bool equals (const FlatIterator & fit) const
00201       {
00202         return fit.it == it && fit.bit == bit;
00203       }
00204     field_type& dereference() const
00205       {
00206         return *bit;
00207       }
00209     DifferenceType index () const
00210       {
00211         return bit.index();
00212       }
00213   private:
00214     BlockIterator it;
00215     SubBlockIterator bit;
00216     SubBlockIterator bend;
00217   };
00218 
00221   template<class K, int N>
00222   class FlatIterator< FieldVector<K,N> > :
00223     public ForwardIteratorFacade<FlatIterator< FieldVector<K,N> >,
00224                                  K, K&, int>
00225   {
00226   public:
00227     typedef typename FieldVector<K,N>::Iterator BlockIterator;
00228     typedef std::ptrdiff_t DifferenceType;
00229 //    typedef typename BlockIterator::DifferenceType DifferenceType;
00230     typedef typename FieldVector<K,N>::field_type field_type;
00231     FlatIterator(const BlockIterator & i) : it(i) {};
00232     void increment ()
00233       {
00234         ++it;
00235       }
00236     bool equals (const FlatIterator & fit) const
00237       {
00238         return fit.it == it;
00239       }
00240     field_type& dereference() const
00241       {
00242         return *it;
00243       }
00245     DifferenceType index () const
00246       {
00247         return it.index();
00248       }
00249   private:
00250     BlockIterator it;
00251   };
00252 
00255   template<class K, int N>
00256   class FlatIterator< const FieldVector<K,N> > :
00257     public ForwardIteratorFacade<FlatIterator< const FieldVector<K,N> >,
00258                                  const K, const K&, int>
00259   {
00260   public:
00261     typedef typename FieldVector<K,N>::ConstIterator BlockIterator;
00262     typedef std::ptrdiff_t DifferenceType;
00263 //    typedef typename BlockIterator::DifferenceType DifferenceType;
00264     typedef typename FieldVector<K,N>::field_type field_type;
00265     FlatIterator(const BlockIterator & i) : it(i) {};
00266     void increment ()
00267       {
00268         ++it;
00269       }
00270     bool equals (const FlatIterator & fit) const
00271       {
00272         return fit.it == it;
00273       }
00274     const field_type& dereference() const
00275       {
00276         return *it;
00277       }
00279     DifferenceType index () const
00280       {
00281         return it.index();
00282       }
00283   private:
00284     BlockIterator it;
00285   };
00286 #endif
00287 
00288 #ifdef DUNE_EXPRESSIONTEMPLATES
00289 
00298   template<class K, int SIZE>
00299   class FieldVector
00300     : public Dune::ExprTmpl::Vector< FieldVector<K,SIZE> >
00301 #else
00311   template<class K, int SIZE>
00312   class FieldVector
00313 #endif
00314   {
00315   public:
00316         // remember size of vector 
00317         enum { dimension = SIZE };
00318 
00319         // standard constructor and everything is sufficient ...
00320 
00321         //===== type definitions and constants
00322 
00324         typedef K field_type;
00325 
00327         typedef K block_type;
00328 
00330     typedef std::size_t size_type;
00331     
00333         enum {
00335           blocklevel = 1
00336         };
00337 
00339         enum {
00341           size = SIZE
00342         };
00343 
00345         FieldVector() {}
00346 
00347 #ifndef DUNE_EXPRESSIONTEMPLATES
00349         explicit FieldVector (const K& t)
00350         {
00351           for (size_type i=0; i<SIZE; i++) p[i] = t;
00352         }
00353 
00354         //===== assignment from scalar
00356         FieldVector& operator= (const K& k)
00357         {
00358             //fvmeta_assignscalar<SIZE-1>::assignscalar(*this,k);
00359             for (size_type i=0; i<SIZE; i++)
00360                 p[i] = k;
00361           return *this;   
00362         }
00363 
00364 #else
00366         explicit FieldVector (const K& t)
00367         {
00368 #ifdef DUNE_VVERBOSE
00369       Dune::dvverb << INDENT << "FieldVector Copy Constructor Scalar\n";
00370 #endif
00371       assignFrom(t);
00372         }
00374         FieldVector& operator= (const K& k)
00375         {
00376 #ifdef DUNE_VVERBOSE
00377       Dune::dvverb << INDENT << "FieldVector Assignment Operator Scalar\n";
00378 #endif
00379       return assignFrom(k);
00380         }
00381     template <class E>
00382     FieldVector (Dune::ExprTmpl::Expression<E> op) {
00383 #ifdef DUNE_VVERBOSE
00384       Dune::dvverb << INDENT << "FieldVector Copy Constructor Expression\n";
00385 #endif
00386       assignFrom(op);
00387     }
00388     template <class V>
00389     FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
00390 #ifdef DUNE_VVERBOSE
00391       Dune::dvverb << INDENT << "FieldVector Copy Operator Vector\n";
00392 #endif
00393       assignFrom(op);
00394     }
00395     template <class E>
00396     FieldVector&  operator = (Dune::ExprTmpl::Expression<E> op) {
00397 #ifdef DUNE_VVERBOSE
00398       Dune::dvverb << INDENT << "FieldVector Assignment Operator Expression\n";
00399 #endif
00400       return assignFrom(op);
00401     }
00402     template <class V>
00403     FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
00404 #ifdef DUNE_VVERBOSE
00405       Dune::dvverb << INDENT << "FieldVector Assignment Operator Vector\n";
00406 #endif
00407       return assignFrom(op);
00408     }
00409 #endif
00410 
00411         //===== access to components
00412 
00414         K& operator[] (size_type i)
00415         {
00416 #ifdef DUNE_ISTL_WITH_CHECKING
00417           if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00418 #endif
00419           return p[i];
00420         }
00421 
00423         const K& operator[] (size_type i) const
00424         {
00425 #ifdef DUNE_ISTL_WITH_CHECKING
00426           if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00427 #endif
00428           return p[i];
00429         }
00430 
00432     typedef FieldIterator<FieldVector<K,SIZE>,K> Iterator;
00434     typedef Iterator iterator;
00435     
00437         Iterator begin ()
00438         {
00439           return Iterator(*this,0);
00440         }
00441 
00443         Iterator end ()
00444         {
00445           return Iterator(*this,SIZE);
00446         }
00447 
00449         Iterator rbegin ()
00450         {
00451           return Iterator(*this,SIZE-1);
00452         }
00453 
00455         Iterator rend ()
00456         {
00457           return Iterator(*this,-1);
00458         }
00459 
00461         Iterator find (size_type i)
00462         {
00463           if (i<SIZE)
00464                 return Iterator(*this,i);
00465           else
00466                 return Iterator(*this,SIZE);
00467         }
00468 
00470     typedef FieldIterator<const FieldVector<K,SIZE>,const K> ConstIterator;
00472     typedef ConstIterator const_iterator;
00473 
00475         ConstIterator begin () const
00476         {
00477           return ConstIterator(*this,0);
00478         }
00479 
00481         ConstIterator end () const
00482         {
00483           return ConstIterator(*this,SIZE);
00484         }
00485 
00487         ConstIterator rbegin () const
00488         {
00489           return ConstIterator(*this,SIZE-1);
00490         }
00491 
00493         ConstIterator rend () const
00494         {
00495           return ConstIterator(*this,-1);
00496         }
00497 
00499         ConstIterator find (size_type i) const
00500         {
00501           if (i<SIZE)
00502                 return ConstIterator(*this,i);
00503           else
00504                 return ConstIterator(*this,SIZE);
00505         }
00506     
00507 #ifndef DUNE_EXPRESSIONTEMPLATES
00508         //===== vector space arithmetic
00509 
00511         FieldVector& operator+= (const FieldVector& y)
00512         {
00513             for (size_type i=0; i<SIZE; i++)
00514                 p[i] += y.p[i];
00515           return *this;
00516         }
00517 
00519         FieldVector& operator-= (const FieldVector& y)
00520         {
00521             for (size_type i=0; i<SIZE; i++)
00522                 p[i] -= y.p[i];
00523           return *this;
00524         }
00525 
00527         FieldVector<K, size> operator+ (const FieldVector<K, size>& b) const
00528         {
00529           FieldVector<K, size> z = *this;
00530           return (z+=b);
00531         }
00532 
00534         FieldVector<K, size> operator- (const FieldVector<K, size>& b) const
00535         {
00536           FieldVector<K, size> z = *this;
00537           return (z-=b);
00538         }
00539 
00541         FieldVector& operator+= (const K& k)
00542         {
00543             for (size_type i=0; i<SIZE; i++)
00544                 p[i] += k;
00545           return *this;
00546         }
00547 
00549         FieldVector& operator-= (const K& k)
00550         {
00551             for (size_type i=0; i<SIZE; i++)
00552                 p[i] -= k;
00553           return *this;
00554         }
00555 
00557         FieldVector& operator*= (const K& k)
00558         {
00559             for (size_type i=0; i<SIZE; i++)
00560                 p[i] *= k;
00561           return *this;
00562         }
00563 
00565         FieldVector& operator/= (const K& k)
00566         {
00567           for (size_type i=0; i<SIZE; i++)
00568               p[i] /= k;
00569           return *this;
00570         }
00571 
00572 #endif
00573 
00575         bool operator== (const FieldVector& y) const
00576         {
00577             for (size_type i=0; i<SIZE; i++)
00578                 if (p[i]!=y.p[i])
00579                     return false;
00580 
00581             return true;
00582         }
00583 
00585         FieldVector& axpy (const K& a, const FieldVector& y)
00586         {
00587 #ifndef DUNE_EXPRESSIONTEMPLATES
00588             for (size_type i=0; i<SIZE; i++)
00589                 p[i] += a*y.p[i];
00590 #else
00591       *this += a*y;
00592 #endif
00593           return *this;
00594         }
00595 
00596 #ifndef DUNE_EXPRESSIONTEMPLATES
00597         //===== Euclidean scalar product
00598 
00600     K operator* (const FieldVector& y) const
00601         {
00602             K result = 0;
00603             for (int i=0; i<size; i++)
00604                 result += p[i]*y[i];
00605             return result;
00606         }
00607 
00608 
00609         //===== norms
00610 
00612       double one_norm() const {
00613           double result = 0;
00614           for (int i=0; i<size; i++)
00615               result += std::abs(p[i]);
00616           return result;
00617       }
00618 
00619 
00621     double one_norm_real () const
00622         {
00623           double result = 0;
00624           for (int i=0; i<size; i++)
00625               result += fvmeta_absreal(p[i]);
00626           return result;
00627         }
00628 
00630     double two_norm () const
00631         {
00632           double result = 0;
00633           for (int i=0; i<size; i++)
00634               result += fvmeta_abs2(p[i]);
00635           return std::sqrt(result);
00636         }
00637 
00639       double two_norm2 () const
00640         {
00641             double result = 0;
00642             for (int i=0; i<size; i++)
00643                 result += fvmeta_abs2(p[i]);
00644             return result;
00645         }
00646 
00648     double infinity_norm () const
00649         {
00650           double result = 0;
00651             for (int i=0; i<size; i++)
00652                 result = std::max(result, std::abs(p[i]));
00653             return result;
00654         }
00655 
00657         double infinity_norm_real () const
00658         {
00659             double result = 0;
00660             for (int i=0; i<size; i++)
00661                 result = std::max(result, fvmeta_absreal(p[i]));
00662             return result;
00663         }
00664 #endif
00665 
00666         //===== sizes
00667 
00669         size_type N () const
00670         {
00671           return SIZE;
00672         }
00673 
00675         size_type dim () const
00676         {
00677           return SIZE;
00678         }
00679 
00680   private:
00681         // the data, very simply a built in array
00682       K p[(SIZE > 0) ? SIZE : 1]; 
00683   };
00684 
00686   template<typename K, int n>
00687   std::ostream& operator<< (std::ostream& s, const FieldVector<K,n>& v)
00688   {
00689       for (typename FieldVector<K,n>::size_type i=0; i<n; i++)
00690               s << ((i>0) ? " " : "") << v[i];
00691       return s;
00692   }
00693 
00694   
00695   // forward declarations
00696   template<class K, int n, int m> class FieldMatrix;
00697 
00698 #ifdef DUNE_EXPRESSIONTEMPLATES
00699 
00701   template<class K>
00702   class FieldVector<K,1>
00703     : public Dune::ExprTmpl::Vector< FieldVector<K,1> >
00704 #else
00707   template<class K>
00708   class FieldVector<K,1>
00709 #endif
00710   {
00711     enum { n = 1 };
00712   public:
00713         friend class FieldMatrix<K,1,1>;
00714 
00715         //===== type definitions and constants
00716 
00718         typedef K field_type;
00719 
00721         typedef K block_type;
00722 
00724     typedef std::size_t size_type;
00725     
00727         enum {blocklevel = 1};
00728 
00730         enum {size = 1};
00731 
00733         enum {dimension = 1};
00734 
00735         //===== construction
00736 
00738         FieldVector ()
00739         {       }
00740 
00742         FieldVector (const K& k)
00743         {
00744           p = k;
00745         }
00746 
00748         FieldVector& operator= (const K& k)
00749         {
00750           p = k;
00751           return *this;   
00752         }
00753 
00754 #ifdef DUNE_EXPRESSIONTEMPLATES
00755     template <class E>
00756     FieldVector (Dune::ExprTmpl::Expression<E> op) {
00757 #ifdef DUNE_VVERBOSE
00758       Dune::dvverb << INDENT << "FieldVector<1> Copy Constructor Expression\n";
00759 #endif
00760       assignFrom(op);
00761     }
00762     template <class V>
00763     FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
00764 #ifdef DUNE_VVERBOSE
00765       Dune::dvverb << INDENT << "FieldVector<1> Copy Operator Vector\n";
00766 #endif
00767       assignFrom(op);
00768     }
00769     template <class E>
00770     FieldVector&  operator = (Dune::ExprTmpl::Expression<E> op) {
00771 #ifdef DUNE_VVERBOSE
00772       Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Expression\n";
00773 #endif
00774       return assignFrom(op);
00775     }
00776     template <class V>
00777     FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
00778 #ifdef DUNE_VVERBOSE
00779       Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Vector\n";
00780 #endif
00781       return assignFrom(op);
00782     }
00783 #endif
00784 
00785         //===== access to components
00786 
00788         K& operator[] (size_type i)
00789         {
00790 #ifdef DUNE_ISTL_WITH_CHECKING
00791           if (i != 0) DUNE_THROW(MathError,"index out of range");
00792 #endif
00793           return p;
00794         }
00795 
00797         const K& operator[] (size_type i) const
00798         {
00799 #ifdef DUNE_ISTL_WITH_CHECKING
00800           if (i != 0) DUNE_THROW(MathError,"index out of range");
00801 #endif
00802           return p;
00803         }
00804 
00806     typedef FieldIterator<FieldVector<K,n>,K> Iterator;
00808     typedef Iterator iterator;
00809     
00811         Iterator begin ()
00812         {
00813           return Iterator(*this,0);
00814         }
00815 
00817         Iterator end ()
00818         {
00819           return Iterator(*this,n);
00820         }
00821 
00823         Iterator rbegin ()
00824         {
00825           return Iterator(*this,n-1);
00826         }
00827 
00829         Iterator rend ()
00830         {
00831           return Iterator(*this,-1);
00832         }
00833 
00835         Iterator find (size_type i)
00836         {
00837           if (i<n)
00838                 return Iterator(*this,i);
00839           else
00840                 return Iterator(*this,n);
00841         }
00842 
00844     typedef FieldIterator<const FieldVector<K,n>,const K> ConstIterator;
00846     typedef ConstIterator const_iterator;
00847 
00849         ConstIterator begin () const
00850         {
00851           return ConstIterator(*this,0);
00852         }
00853 
00855         ConstIterator end () const
00856         {
00857           return ConstIterator(*this,n);
00858         }
00859 
00861         ConstIterator rbegin () const
00862         {
00863           return ConstIterator(*this,n-1);
00864         }
00865 
00867         ConstIterator rend () const
00868         {
00869           return ConstIterator(*this,-1);
00870         }
00871 
00873         ConstIterator find (size_type i) const
00874         {
00875           if (i<n)
00876                 return ConstIterator(*this,i);
00877           else
00878                 return ConstIterator(*this,n);
00879         }
00880         //===== vector space arithmetic
00881 
00883         FieldVector& operator+= (const FieldVector& y)
00884         {
00885           p += y.p;
00886           return *this;
00887         }
00888 
00890         FieldVector& operator-= (const FieldVector& y)
00891         {
00892           p -= y.p;
00893           return *this;
00894         }
00895 
00897         FieldVector& operator+= (const K& k)
00898         {
00899           p += k;
00900           return *this;
00901         }
00902 
00904         FieldVector& operator-= (const K& k)
00905         {
00906           p -= k;
00907           return *this;
00908         }
00909 
00911         FieldVector& operator*= (const K& k)
00912         {
00913           p *= k;
00914           return *this;
00915         }
00916 
00918         FieldVector& operator/= (const K& k)
00919         {
00920           p /= k;
00921           return *this;
00922         }
00923 
00925         FieldVector& axpy (const K& a, const FieldVector& y)
00926         {
00927           p += a*y.p;
00928           return *this;
00929         }
00930 
00931         //===== norms
00932 
00934     double one_norm () const
00935         {
00936             return std::abs(p);
00937         }
00938 
00940     double one_norm_real () const
00941         {
00942           return fvmeta_abs_real(p);
00943         }
00944 
00946     double two_norm () const
00947         {
00948           return sqrt(fvmeta_abs2(p));
00949         }
00950 
00952     double two_norm2 () const
00953         {
00954           return fvmeta_abs2(p);
00955         }
00956 
00958     double infinity_norm () const
00959         {
00960             return std::abs(p);
00961         }
00962 
00964         double infinity_norm_real () const
00965         {
00966           return fvmeta_abs_real(p);
00967         }
00968 
00969 
00970         //===== sizes
00971 
00973         size_type N () const
00974         {
00975           return 1;
00976         }
00977 
00979         size_type dim () const
00980         {
00981           return 1;
00982         }
00983 
00984         //===== conversion operator
00985 
00987         operator K () {return p;}
00988 
00990         operator K () const {return p;}
00991 
00992   private:
00993         // the data
00994         K p; 
00995   };
00996 
00997 #ifndef DUNE_EXPRESSIONTEMPLATES
00999   template<class K>
01000   inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
01001   {
01002     FieldVector<K,1> z = a;
01003     return (z+=b);
01004   }
01005   
01007   template<class K>
01008   inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
01009   {
01010     FieldVector<K,1> z = a;
01011     return (z-=b);
01012   }
01013   
01015   template<class K>
01016   inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
01017   {
01018     FieldVector<K,1> z = a;
01019     return (z[0]+=b);
01020   }
01021   
01023   template<class K>
01024   inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
01025   {
01026     FieldVector<K,1> z = a;
01027     return (z[0]-=b);
01028   }
01029 
01031   template<class K>
01032   inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
01033   {
01034     FieldVector<K,1> z = a;
01035     return (z[0]+=b);
01036   }
01037   
01039   template<class K>
01040   inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
01041   {
01042     FieldVector<K,1> z = a;
01043     return (z[0]-=b);
01044   }
01045 #endif
01046 
01047 
01050 } // end namespace
01051 
01052 #endif

Generated on 6 Nov 2008 with Doxygen (ver 1.5.6) [logfile].