Skip to content
Snippets Groups Projects
fvector.hh 25.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oliver Sander's avatar
    Oliver Sander committed
    // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    // vi: set et ts=4 sw=2 sts=2:
    
    Markus Blatt's avatar
    Markus Blatt committed
    // $Id$
    
    #ifndef DUNE_FVECTOR_HH
    #define DUNE_FVECTOR_HH
    
    #include <cmath>
    #include <cstddef>
    
    #include <cstdlib>
    
    Oliver Sander's avatar
    Oliver Sander committed
    #include <complex>
    
    
    Peter Bastian's avatar
    Peter Bastian committed
    #include "exceptions.hh"
    
    #include "genericiterator.hh"
    
    #ifdef DUNE_EXPRESSIONTEMPLATES
    #include "exprtmpl.hh"
    #endif
    
    
    Oliver Sander's avatar
    Oliver Sander committed
    namespace Dune {
    
    
    #ifndef DUNE_EXPRESSIONTEMPLATES
    
    
      /** @defgroup DenseMatVec Dense Matrix and Vector Template Library
    
    Markus Blatt's avatar
    Markus Blatt committed
      /*! \file
       * \brief This file implements a vector constructed from a given type
         representing a field and a compile-time given size.
       */
    
    
    Oliver Sander's avatar
    Oliver Sander committed
      // forward declaration of template
    
      template<class K, int SIZE> class FieldVector;
    
    #endif
    
    #ifndef DUNE_EXPRESSIONTEMPLATES
    
    
    Christian Engwer's avatar
    Christian Engwer committed
      /**
         \private
         \memberof FieldVector
       */
    
    Oliver Sander's avatar
    Oliver Sander committed
      template<class K>
      inline double fvmeta_absreal (const K& k)
      {
    
    Christian Engwer's avatar
    Christian Engwer committed
      /**
         \private
         \memberof FieldVector
       */
    
    Oliver Sander's avatar
    Oliver Sander committed
      template<class K>
      inline double fvmeta_absreal (const std::complex<K>& c)
      {
        return fvmeta_abs(c.real()) + fvmeta_abs(c.imag());
      }
    
    
    Christian Engwer's avatar
    Christian Engwer committed
      /**
         \private
         \memberof FieldVector
       */
    
    Oliver Sander's avatar
    Oliver Sander committed
      template<class K>
      inline double fvmeta_abs2 (const K& k)
      {
        return k*k;
      }
    
    
    Christian Engwer's avatar
    Christian Engwer committed
      /**
         \private
         \memberof FieldVector
       */
    
    Oliver Sander's avatar
    Oliver Sander committed
      template<class K>
      inline double fvmeta_abs2 (const std::complex<K>& c)
      {
        return c.real()*c.real() + c.imag()*c.imag();
      }
    
    
      //! Iterator class for sequential access to FieldVector and FieldMatrix
      template<class C, class T>
      class FieldIterator :
        public Dune::RandomAccessIteratorFacade<FieldIterator<C,T>,T, T&, int>
      {
    
        friend class FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >;
        friend class FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >;
    
    
      public:
    
        /**
         * @brief The type of the difference between two positions.
         */
    
        typedef std::ptrdiff_t DifferenceType;
    
    
        // Constructors needed by the base iterators.
        FieldIterator()
          : container_(0), position_(0)
        {}
    
        FieldIterator(C& cont, DifferenceType pos)
          : container_(&cont), position_(pos)
        {}
    
    
        FieldIterator(const FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >& other)
    
          : container_(other.container_), position_(other.position_)
        {}
    
    
        FieldIterator(const FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >& other)
    
          : container_(other.container_), position_(other.position_)
        {}
    
    #endif
    #if 0
        FieldIterator(const FieldIterator<C,T>& other)
          : container_(other.container_), position_(other.position_)
        {}
    #endif
    
        // Methods needed by the forward iterator
    
        bool equals(const FieldIterator<typename remove_const<C>::type,typename remove_const<T>::type>& other) const
    
        {
          return position_ == other.position_ && container_ == other.container_;
        }
    
    
    
        bool equals(const FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type>& other) const
    
        {
          return position_ == other.position_ && container_ == other.container_;
        }
    
        T& dereference() const {
          return container_->operator[](position_);
        }
    
        void increment(){
          ++position_;
        }
    
        // Additional function needed by BidirectionalIterator
        void decrement(){
          --position_;
        }
    
        // Additional function needed by RandomAccessIterator
        T& elementAt(DifferenceType i) const {
          return container_->operator[](position_+i);
        }
    
        void advance(DifferenceType n){
          position_=position_+n;
        }
    
    
        std::ptrdiff_t distanceTo(FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type> other) const
    
        {
          assert(other.container_==container_);
          return other.position_ - position_;
        }
    
    
        std::ptrdiff_t distanceTo(FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type> other) const
    
        {
          assert(other.container_==container_);
          return other.position_ - position_;
        }
    
        //! return index
    
        DifferenceType index () const
    
        {
          return this->position_;
        }
    
      private:
        C *container_;
        DifferenceType position_;
      };
    
    
      //! Type Traits for Vector::Iterator vs (const Vector)::ConstIterator
      template<class T>
      struct IteratorType
      {
        typedef typename T::Iterator type;
      };
    
      template<class T>
      struct IteratorType<const T>
      {
        typedef typename T::ConstIterator type;
      };
    
    #ifdef DUNE_EXPRESSIONTEMPLATES
      //! Iterator class for flat sequential access to a nested Vector
      template<class V>
      class FlatIterator :
        public ForwardIteratorFacade<FlatIterator<V>,
            typename Dune::FieldType<V>::type,
            typename Dune::FieldType<V>::type&,
            int>
      {
      public:
        typedef typename IteratorType<V>::type BlockIterator;
        typedef std::ptrdiff_t DifferenceType;
        //    typedef typename BlockIterator::DifferenceType DifferenceType;
        typedef typename BlockType<V>::type block_type;
        typedef typename FieldType<V>::type field_type;
        typedef FlatIterator<block_type> SubBlockIterator;
        FlatIterator(const BlockIterator & i) :
          it(i), bit(i->begin()), bend(i->end()) {};
        void increment ()
        {
          ++bit;
          if (bit == bend)
          {
            ++it;
            bit = it->begin();
            bend = it->end();
          }
        }
        bool equals (const FlatIterator & fit) const
        {
    
          return fit.it == it && fit.bit == bit;
    
        }
        field_type& dereference() const
        {
          return *bit;
        }
        //! return index
    
        DifferenceType index () const
    
        {
          return bit.index();
        }
      private:
        BlockIterator it;
        SubBlockIterator bit;
        SubBlockIterator bend;
      };
    
      //! Specialization for FieldVector
      //! acts as the end of the recursive template
      template<class K, int N>
      class FlatIterator< FieldVector<K,N> > :
        public ForwardIteratorFacade<FlatIterator< FieldVector<K,N> >,
            K, K&, int>
      {
      public:
        typedef typename FieldVector<K,N>::Iterator BlockIterator;
        typedef std::ptrdiff_t DifferenceType;
        //    typedef typename BlockIterator::DifferenceType DifferenceType;
        typedef typename FieldVector<K,N>::field_type field_type;
        FlatIterator(const BlockIterator & i) : it(i) {};
        void increment ()
        {
          ++it;
        }
        bool equals (const FlatIterator & fit) const
        {
          return fit.it == it;
        }
        field_type& dereference() const
        {
          return *it;
        }
        //! return index
    
        DifferenceType index () const
    
        {
          return it.index();
        }
      private:
        BlockIterator it;
      };
    
      //! Specialization for const FieldVector
      //! acts as the end of the recursive template
      template<class K, int N>
      class FlatIterator< const FieldVector<K,N> > :
        public ForwardIteratorFacade<FlatIterator< const FieldVector<K,N> >,
            const K, const K&, int>
      {
      public:
        typedef typename FieldVector<K,N>::ConstIterator BlockIterator;
        typedef std::ptrdiff_t DifferenceType;
        //    typedef typename BlockIterator::DifferenceType DifferenceType;
        typedef typename FieldVector<K,N>::field_type field_type;
        FlatIterator(const BlockIterator & i) : it(i) {};
        void increment ()
        {
          ++it;
        }
        bool equals (const FlatIterator & fit) const
        {
          return fit.it == it;
        }
        const field_type& dereference() const
        {
          return *it;
        }
        //! return index
    
        DifferenceType index () const
    
        {
          return it.index();
        }
      private:
        BlockIterator it;
      };
    #endif
    
    
      /** \brief Construct a vector space out of a tensor product of fields.
    
       *
       *  K is the field type (use float, double, complex, etc) and SIZE
       *  is the number of components.
       *
       *  It is generally assumed that K is a numerical type compatible with double
       *  (E.g. norms are always computed in double precision).
    
      template< class K, int SIZE >
    
    #ifdef DUNE_EXPRESSIONTEMPLATES
        : public Dune :: ExprTmpl :: Vector< FieldVector< K, SIZE > >
    
    Oliver Sander's avatar
    Oliver Sander committed
      {
      public:
    
        // remember size of vector
        enum { dimension = SIZE };
    
        // standard constructor and everything is sufficient ...
    
    Oliver Sander's avatar
    Oliver Sander committed
    
        //===== type definitions and constants
    
        //! export the type representing the field
        typedef K field_type;
    
        //! export the type representing the components
        typedef K block_type;
    
    
        //! The type used for the index access and size operation
        typedef std::size_t size_type;
    
    
    Oliver Sander's avatar
    Oliver Sander committed
        //! We are at the leaf of the block recursion
    
        enum {
          //! The number of block levels we contain
          blocklevel = 1
        };
    
    Oliver Sander's avatar
    Oliver Sander committed
    
        //! export size
    
        enum {
          //! The size of this vector.
    
    Oliver Sander's avatar
    Oliver Sander committed
    
        //! Constructor making uninitialized vector
        FieldVector() {}
    
    
    #ifndef DUNE_EXPRESSIONTEMPLATES
    
    Oliver Sander's avatar
    Oliver Sander committed
        //! Constructor making vector with identical coordinates
        explicit FieldVector (const K& t)
        {
    
          for (size_type i=0; i<SIZE; i++) p[i] = t;
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //===== assignment from scalar
    
        //! Assignment operator for scalar
    
    Adrian Burri's avatar
    Adrian Burri committed
        FieldVector& operator= (const K& k)
    
          //fvmeta_assignscalar<SIZE-1>::assignscalar(*this,k);
          for (size_type i=0; i<SIZE; i++)
            p[i] = k;
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
    
    #else
        //! Constructor making vector with identical coordinates
        explicit FieldVector (const K& t)
        {
    #ifdef DUNE_VVERBOSE
          Dune::dvverb << INDENT << "FieldVector Copy Constructor Scalar\n";
    #endif
          assignFrom(t);
        }
        //! Assignment operator for scalar
        FieldVector& operator= (const K& k)
        {
    #ifdef DUNE_VVERBOSE
          Dune::dvverb << INDENT << "FieldVector Assignment Operator Scalar\n";
    #endif
          return assignFrom(k);
        }
    
        template <class E>
        FieldVector (Dune::ExprTmpl::Expression<E> op) {
    
          Dune::dvverb << INDENT << "FieldVector Copy Constructor Expression\n";
    
          assignFrom(op);
        }
        template <class V>
        FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
    
          Dune::dvverb << INDENT << "FieldVector Copy Operator Vector\n";
    
          assignFrom(op);
        }
        template <class E>
        FieldVector&  operator = (Dune::ExprTmpl::Expression<E> op) {
    
          Dune::dvverb << INDENT << "FieldVector Assignment Operator Expression\n";
    
          return assignFrom(op);
        }
        template <class V>
        FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
    
          Dune::dvverb << INDENT << "FieldVector Assignment Operator Vector\n";
    
        /** \brief copy constructor */
        FieldVector ( const FieldVector &other )
        {
          for( size_type i = 0; i < SIZE; ++i )
            p[ i ] = other[ i ];
        }
    
    
        /** \brief Assigment from other vector */
        FieldVector& operator= (const FieldVector& other) {
          for (size_type i=0; i<SIZE; i++)
            p[i] = other[i];
    
          return *this;
    
    Oliver Sander's avatar
    Oliver Sander committed
        //===== access to components
    
        //! random access
    
    Oliver Sander's avatar
    Oliver Sander committed
        {
    #ifdef DUNE_ISTL_WITH_CHECKING
    
          if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
    
    Oliver Sander's avatar
    Oliver Sander committed
    #endif
          return p[i];
        }
    
        //! same for read only access
    
        const K& operator[] (size_type i) const
    
    Oliver Sander's avatar
    Oliver Sander committed
        {
    #ifdef DUNE_ISTL_WITH_CHECKING
    
          if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
    
    Oliver Sander's avatar
    Oliver Sander committed
    #endif
          return p[i];
        }
    
        //! Iterator class for sequential access
    
        typedef FieldIterator<FieldVector<K,SIZE>,K> Iterator;
    
        //! typedef for stl compliant access
        typedef Iterator iterator;
    
    Oliver Sander's avatar
    Oliver Sander committed
    
        //! begin iterator
        Iterator begin ()
        {
    
          return Iterator(*this,0);
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! end iterator
        Iterator end ()
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! begin iterator
        Iterator rbegin ()
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! end iterator
        Iterator rend ()
        {
    
          return Iterator(*this,-1);
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! return iterator to given element or end()
    
            return Iterator(*this,i);
    
    Oliver Sander's avatar
    Oliver Sander committed
          else
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! ConstIterator class for sequential access
    
        typedef FieldIterator<const FieldVector<K,SIZE>,const K> ConstIterator;
    
        //! typedef for stl compliant access
        typedef ConstIterator const_iterator;
    
    Oliver Sander's avatar
    Oliver Sander committed
    
        //! begin ConstIterator
        ConstIterator begin () const
        {
    
          return ConstIterator(*this,0);
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! end ConstIterator
        ConstIterator end () const
        {
    
          return ConstIterator(*this,SIZE);
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! begin ConstIterator
        ConstIterator rbegin () const
        {
    
          return ConstIterator(*this,SIZE-1);
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! end ConstIterator
        ConstIterator rend () const
        {
    
          return ConstIterator(*this,-1);
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! return iterator to given element or end()
    
        ConstIterator find (size_type i) const
    
            return ConstIterator(*this,i);
    
    Oliver Sander's avatar
    Oliver Sander committed
          else
    
            return ConstIterator(*this,SIZE);
    
    #ifndef DUNE_EXPRESSIONTEMPLATES
    
    Oliver Sander's avatar
    Oliver Sander committed
        //===== vector space arithmetic
    
        //! vector space addition
        FieldVector& operator+= (const FieldVector& y)
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
        //! vector space subtraction
        FieldVector& operator-= (const FieldVector& y)
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
        //! Binary vector addition
        FieldVector<K, size> operator+ (const FieldVector<K, size>& b) const
        {
          FieldVector<K, size> z = *this;
          return (z+=b);
        }
    
        //! Binary vector subtraction
        FieldVector<K, size> operator- (const FieldVector<K, size>& b) const
        {
          FieldVector<K, size> z = *this;
          return (z-=b);
        }
    
        //! vector space add scalar to all comps
        FieldVector& operator+= (const K& k)
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
        //! vector space subtract scalar from all comps
        FieldVector& operator-= (const K& k)
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
        //! vector space multiplication with scalar
        FieldVector& operator*= (const K& k)
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
        //! vector space division by scalar
        FieldVector& operator/= (const K& k)
        {
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
    
    Jorrit Fahlke's avatar
    Jorrit Fahlke committed
        //! Binary vector comparison
        bool operator== (const FieldVector& y) const
        {
    
          for (size_type i=0; i<SIZE; i++)
            if (p[i]!=y.p[i])
              return false;
    
          return true;
    
    Markus Blatt's avatar
    Markus Blatt committed
        //! Binary vector incomparison
        bool operator!= (const FieldVector& y) const
        {
          return !operator==(y);
        }
    
    
    
    Christian Engwer's avatar
    Christian Engwer committed
        //! vector space axpy operation ( *this += a y )
    
    Oliver Sander's avatar
    Oliver Sander committed
        FieldVector& axpy (const K& a, const FieldVector& y)
        {
    
    #ifndef DUNE_EXPRESSIONTEMPLATES
    
          for (size_type i=0; i<SIZE; i++)
            p[i] += a*y.p[i];
    
    Oliver Sander's avatar
    Oliver Sander committed
          return *this;
        }
    
    
    #ifndef DUNE_EXPRESSIONTEMPLATES
    
    Oliver Sander's avatar
    Oliver Sander committed
        //===== Euclidean scalar product
    
    
        //! scalar product (x^T y)
    
        K operator* (const FieldVector& y) const
    
          K result = 0;
          for (int i=0; i<size; i++)
            result += p[i]*y[i];
          return result;
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //===== norms
    
        //! one norm (sum over absolute values of entries)
    
        double one_norm() const {
          double result = 0;
          for (int i=0; i<size; i++)
            result += std::abs(p[i]);
          return result;
    
    Oliver Sander's avatar
    Oliver Sander committed
        //! simplified one norm (uses Manhattan norm for complex values)
        double one_norm_real () const
        {
    
          double result = 0;
          for (int i=0; i<size; i++)
            result += fvmeta_absreal(p[i]);
          return result;
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! two norm sqrt(sum over squared values of entries)
        double two_norm () const
        {
    
          double result = 0;
          for (int i=0; i<size; i++)
            result += fvmeta_abs2(p[i]);
          return std::sqrt(result);
    
        //! square of two norm (sum over squared values of entries), need for block recursion
    
    Oliver Sander's avatar
    Oliver Sander committed
        double two_norm2 () const
        {
    
          double result = 0;
          for (int i=0; i<size; i++)
            result += fvmeta_abs2(p[i]);
          return result;
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! infinity norm (maximum of absolute values of entries)
        double infinity_norm () const
        {
    
          double result = 0;
          for (int i=0; i<size; i++)
    
    Oliver Sander's avatar
    Oliver Sander committed
            result = std::max(result, std::abs(p[i]));
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! simplified infinity norm (uses Manhattan norm for complex values)
        double infinity_norm_real () const
        {
    
          double result = 0;
          for (int i=0; i<size; i++)
    
    Oliver Sander's avatar
    Oliver Sander committed
            result = std::max(result, fvmeta_absreal(p[i]));
    
    Oliver Sander's avatar
    Oliver Sander committed
    
        //===== sizes
    
        //! number of blocks in the vector (are of size 1 here)
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
        //! dimension of the vector space
    
    Oliver Sander's avatar
    Oliver Sander committed
        }
    
      private:
        // the data, very simply a built in array
    
      /** \brief Write a FieldVector to an output stream
       *  \relates FieldVector
       *
       *  \param[in]  s  std :: ostream to write to
       *  \param[in]  v  FieldVector to write
       *
       *  \returns the output stream (s)
       */
    
      template<typename K, int n>
      std::ostream& operator<< (std::ostream& s, const FieldVector<K,n>& v)
      {
    
        for (typename FieldVector<K,n>::size_type i=0; i<n; i++)
          s << ((i>0) ? " " : "") << v[i];
    
      /** \brief Read a FieldVector from an input stream
       *  \relates FieldVector
       *
       *  \note This operator is STL compilant, i.e., the content of v is only
       *        changed if the read operation is successful.
       *
       *  \param[in]  in  std :: istream to read from
       *  \param[out] v   FieldVector to be read
       *
       *  \returns the input stream (in)
       */
      template< class K, int SIZE >
      inline std :: istream &operator>> ( std :: istream &in,
                                          FieldVector< K, SIZE > &v )
      {
        FieldVector< K, SIZE > w;
        for( typename FieldVector< K, SIZE > :: size_type i = 0; i < SIZE; ++i )
          in >> w[ i ];
        if( in )
          v = w;
        return in;
      }
    
    
    
      // forward declarations
      template<class K, int n, int m> class FieldMatrix;
    
    
    
    
      /** \brief Vectors containing only one component
    
      template< class K >
      class FieldVector< K, 1 >
    #ifdef DUNE_EXPRESSIONTEMPLATES
        : public Dune :: ExprTmpl :: Vector< FieldVector< K, 1 > >
    
      {
        enum { n = 1 };
      public:
        friend class FieldMatrix<K,1,1>;
    
        //===== type definitions and constants
    
        //! export the type representing the field
        typedef K field_type;
    
        //! export the type representing the components
        typedef K block_type;
    
    
        //! The type for the index access and size operations.
    
    Markus Blatt's avatar
    Markus Blatt committed
        typedef std::size_t size_type;
    
        //! We are at the leaf of the block recursion
        enum {blocklevel = 1};
    
        //! export size
        enum {size = 1};
    
    
        //! export size
        enum {dimension = 1};
    
    
        //===== construction
    
        /** \brief Default constructor */
        FieldVector ()
        {       }
    
        /** \brief Constructor with a given scalar */
        FieldVector (const K& k)
        {
          p = k;
        }
    
        /** \brief Assignment from the base type */
        FieldVector& operator= (const K& k)
        {
          p = k;
          return *this;
        }
    
    
    #ifdef DUNE_EXPRESSIONTEMPLATES
        template <class E>
        FieldVector (Dune::ExprTmpl::Expression<E> op) {
    
          Dune::dvverb << INDENT << "FieldVector<1> Copy Constructor Expression\n";
    
          assignFrom(op);
        }
        template <class V>
        FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
    
          Dune::dvverb << INDENT << "FieldVector<1> Copy Operator Vector\n";
    
          assignFrom(op);
        }
        template <class E>
        FieldVector&  operator = (Dune::ExprTmpl::Expression<E> op) {
    
          Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Expression\n";
    
          return assignFrom(op);
        }
        template <class V>
        FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
    
          Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Vector\n";
    
        //===== access to components
    
        //! random access
    
        {
    #ifdef DUNE_ISTL_WITH_CHECKING
          if (i != 0) DUNE_THROW(MathError,"index out of range");
    #endif
          return p;
        }
    
        //! same for read only access
    
        const K& operator[] (size_type i) const
    
        {
    #ifdef DUNE_ISTL_WITH_CHECKING
          if (i != 0) DUNE_THROW(MathError,"index out of range");
    #endif
          return p;
        }
    
        //! Iterator class for sequential access
    
        typedef FieldIterator<FieldVector<K,n>,K> Iterator;
    
        //! typedef for stl compliant access
        typedef Iterator iterator;
    
        //! begin iterator
        Iterator begin ()
        {
          return Iterator(*this,0);
        }
    
        //! end iterator
        Iterator end ()
        {
          return Iterator(*this,n);
        }
    
        //! begin iterator
        Iterator rbegin ()
        {
          return Iterator(*this,n-1);
        }
    
        //! end iterator
        Iterator rend ()
        {
          return Iterator(*this,-1);
        }
    
        //! return iterator to given element or end()
    
            return Iterator(*this,i);
          else
            return Iterator(*this,n);
        }
    
        //! ConstIterator class for sequential access
    
        typedef FieldIterator<const FieldVector<K,n>,const K> ConstIterator;
    
        //! typedef for stl compliant access
        typedef ConstIterator const_iterator;
    
        //! begin ConstIterator
        ConstIterator begin () const
        {
          return ConstIterator(*this,0);
        }
    
        //! end ConstIterator
        ConstIterator end () const
        {
          return ConstIterator(*this,n);
        }
    
        //! begin ConstIterator
        ConstIterator rbegin () const
        {
          return ConstIterator(*this,n-1);
        }
    
        //! end ConstIterator
        ConstIterator rend () const
        {
          return ConstIterator(*this,-1);
        }
    
        //! return iterator to given element or end()
    
        ConstIterator find (size_type i) const
    
            return ConstIterator(*this,i);
          else
            return ConstIterator(*this,n);
        }
        //===== vector space arithmetic
    
        //! vector space add scalar to each comp
        FieldVector& operator+= (const K& k)
        {
          p += k;
          return *this;
        }
    
        //! vector space subtract scalar from each comp
        FieldVector& operator-= (const K& k)
        {
          p -= k;
          return *this;
        }
    
        //! vector space multiplication with scalar
        FieldVector& operator*= (const K& k)
        {
          p *= k;
          return *this;
        }
    
        //! vector space division by scalar
        FieldVector& operator/= (const K& k)
        {
          p /= k;
          return *this;
        }
    
    
    Christian Engwer's avatar
    Christian Engwer committed
        //! vector space axpy operation ( *this += a y )
    
        FieldVector& axpy (const K& a, const FieldVector& y)
        {
          p += a*y.p;
          return *this;
        }
    
    
        //! scalar product (x^T y)
    
        inline K operator* ( const K & k ) const
    
        //===== norms
    
        //! one norm (sum over absolute values of entries)
        double one_norm () const
        {
    
        }
    
        //! simplified one norm (uses Manhattan norm for complex values)
        double one_norm_real () const
        {
          return fvmeta_abs_real(p);
        }
    
        //! two norm sqrt(sum over squared values of entries)
        double two_norm () const
        {
          return sqrt(fvmeta_abs2(p));
        }
    
        //! square of two norm (sum over squared values of entries), need for block recursion
        double two_norm2 () const
        {
          return fvmeta_abs2(p);