Skip to content
Snippets Groups Projects
orthogonalmatrix.hh 5.06 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef ORTHOGONAL_MATRIX_HH
    #define ORTHOGONAL_MATRIX_HH
    
    #include <dune/common/fmatrix.hh>
    
    
    #include <dune/gfe/skewmatrix.hh>
    
    
    /** \brief An orthogonal \f$ n \times n \f$ matrix
     * \tparam T Type of the matrix entries
     * \tparam N Space dimension
     */
    template <class T, int N>
    class OrthogonalMatrix
    {
    public:
    
      /** \brief The type used for coordinates */
      typedef T ctype;
    
      /** \brief Dimension of the manifold formed by the orthogonal matrices */
      static const int dim = N*(N-1)/2;
    
      /** \brief Coordinates are embedded into a Euclidean space of N x N - matrices */
      static const int embeddedDim = N*N;
    
      /** \brief The type used for global coordinates */
      typedef Dune::FieldVector<T,embeddedDim> CoordinateType;
    
      /** \brief Member of the corresponding Lie algebra.  This really is a skew-symmetric matrix */
      typedef Dune::FieldVector<T,dim> TangentVector;
    
      /** \brief A tangent vector as a vector in the surrounding coordinate space */
      typedef Dune::FieldVector<T,embeddedDim> EmbeddedTangentVector;
    
    
        /** \brief Default constructor -- leaves the matrix uninitialized */
        OrthogonalMatrix()
        {}
        
    
        /** \brief Constructor from a general matrix
         * 
    
         * It is not checked whether the matrix is really orthogonal
    
         */
        explicit OrthogonalMatrix(const Dune::FieldMatrix<T,N,N>& matrix)
        : data_(matrix)
    
        /** \brief Copy constructor
         *
         * It is not checked whether the matrix is really orthogonal
         */
        explicit OrthogonalMatrix(const CoordinateType& other)
        {
          DUNE_THROW(Dune::NotImplemented, "constructor");
        }
    
    
        /** \brief Const access to the matrix entries */
        const Dune::FieldMatrix<T,N,N>& data() const
        {
            return data_;
        }
        
        /** \brief Project the input matrix onto the tangent space at "this"
         * 
         * See Absil, Mahoney, Sepulche, Example 5.3.2 for the formula
    
         * \f[ P_X \xi = X \operatorname{skew} (X^T \xi)  \f]
         *
    
         */
        Dune::FieldMatrix<T,N,N> projectOntoTangentSpace(const Dune::FieldMatrix<T,N,N>& matrix) const
        {
            // rename to get the same notation as Absil & Co
            const Dune::FieldMatrix<T,N,N>& X = data_;
            
            // X^T \xi
            Dune::FieldMatrix<T,N,N> XTxi(0);
            for (int i=0; i<N; i++)
                for (int j=0; j<N; j++)
                    for (int k=0; k<N; k++)
                        XTxi[i][j] += X[k][i] * matrix[k][j];
                    
            // skew (X^T \xi)
            Dune::FieldMatrix<T,N,N> skewXTxi(0);
            for (int i=0; i<N; i++)
                for (int j=0; j<N; j++)
                    skewXTxi[i][j] = 0.5 * ( XTxi[i][j] - XTxi[j][i] );
                    
            // X skew (X^T \xi)
    
            Dune::FieldMatrix<T,N,N> result(0);
    
            for (int i=0; i<N; i++)
                for (int j=0; j<N; j++)
                    for (int k=0; k<N; k++)
    
                        result[i][j] += X[i][k] * skewXTxi[k][j];
    
                    
            return result;
        }
    
    
        /** \brief Rebind the OrthogonalMatrix to another coordinate type */
        template<class U>
        struct rebind
        {
          typedef OrthogonalMatrix<U,N> other;
        };
    
        OrthogonalMatrix& operator= (const CoordinateType& other)
        {
          std::size_t idx = 0;
          for (int i=0; i<N; i++)
            for (int j=0; j<N; j++)
              data_[i][j] = other[idx++];
          return *this;
        }
    
      /** \brief The exponential map from a given point $p \in SO(n)$.
    
        \param v A tangent vector.
       */
      static OrthogonalMatrix<T,3> exp(const OrthogonalMatrix<T,N>& p, const TangentVector& v)
      {
        DUNE_THROW(Dune::NotImplemented, "exp");
      }
    
        /** \brief Return the actual matrix */
        void matrix(Dune::FieldMatrix<T,N,N>& m) const
      {
          m = data_;
      }
    
      /** \brief Project tangent vector of R^n onto the normal space space */
      EmbeddedTangentVector projectOntoNormalSpace(const EmbeddedTangentVector& v) const
      {
        DUNE_THROW(Dune::NotImplemented, "projectOntoNormalSpace");
      }
    
      /** \brief The Weingarten map */
      EmbeddedTangentVector weingarten(const EmbeddedTangentVector& z, const EmbeddedTangentVector& v) const
      {
        EmbeddedTangentVector result;
        DUNE_THROW(Dune::NotImplemented, "weingarten");
        return result;
      }
    
      static OrthogonalMatrix<T,N> projectOnto(const CoordinateType& p)
      {
        DUNE_THROW(Dune::NotImplemented, "projectOnto");
      }
    
      // TODO return type is wrong
      static Dune::FieldMatrix<T,1,1> derivativeOfProjection(const CoordinateType& p)
      {
        Dune::FieldMatrix<T,1,1> result;
        return result;
      }
    
      /** \brief The global coordinates, if you really want them */
      CoordinateType globalCoordinates() const
      {
        CoordinateType result;
        std::size_t idx = 0;
    
        for (int i=0; i<N; i++)
          for (int j=0; j<N; j++)
            result[idx++] = data_[i][j];
    
        return result;
      }
    
      /** \brief Compute an orthonormal basis of the tangent space of SO(n). */
      Dune::FieldMatrix<T,dim,embeddedDim> orthonormalFrame() const
      {
        Dune::FieldMatrix<T,dim,embeddedDim> result;
        DUNE_THROW(Dune::NotImplemented, "orthonormalFrame");
        return result;
      }
    
    
    private:
        
        /** \brief The actual data */
        Dune::FieldMatrix<T,N,N> data_;
        
    };
    
    
    #endif // ORTHOGONAL_MATRIX_HH