Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #ifndef EIGEN_CWISE_UNARY_VIEW_H
     11 #define EIGEN_CWISE_UNARY_VIEW_H
     12 
     13 namespace Eigen {
     14 
     15 /** \class CwiseUnaryView
     16   * \ingroup Core_Module
     17   *
     18   * \brief Generic lvalue expression of a coefficient-wise unary operator of a matrix or a vector
     19   *
     20   * \param ViewOp template functor implementing the view
     21   * \param MatrixType the type of the matrix we are applying the unary operator
     22   *
     23   * This class represents a lvalue expression of a generic unary view operator of a matrix or a vector.
     24   * It is the return type of real() and imag(), and most of the time this is the only way it is used.
     25   *
     26   * \sa MatrixBase::unaryViewExpr(const CustomUnaryOp &) const, class CwiseUnaryOp
     27   */
     28 
     29 namespace internal {
     30 template<typename ViewOp, typename MatrixType>
     31 struct traits<CwiseUnaryView<ViewOp, MatrixType> >
     32  : traits<MatrixType>
     33 {
     34   typedef typename result_of<
     35                      ViewOp(typename traits<MatrixType>::Scalar)
     36                    >::type Scalar;
     37   typedef typename MatrixType::Nested MatrixTypeNested;
     38   typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
     39   enum {
     40     Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)),
     41     CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits<ViewOp>::Cost,
     42     MatrixTypeInnerStride =  inner_stride_at_compile_time<MatrixType>::ret,
     43     // need to cast the sizeof's from size_t to int explicitly, otherwise:
     44     // "error: no integral type can represent all of the enumerator values
     45     InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic
     46                              ? int(Dynamic)
     47                              : int(MatrixTypeInnerStride) * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
     48     OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret == Dynamic
     49                              ? int(Dynamic)
     50                              : outer_stride_at_compile_time<MatrixType>::ret * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar))
     51   };
     52 };
     53 }
     54 
     55 template<typename ViewOp, typename MatrixType, typename StorageKind>
     56 class CwiseUnaryViewImpl;
     57 
     58 template<typename ViewOp, typename MatrixType>
     59 class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
     60 {
     61   public:
     62 
     63     typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
     64     EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView)
     65 
     66     inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp())
     67       : m_matrix(mat), m_functor(func) {}
     68 
     69     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
     70 
     71     EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
     72     EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
     73 
     74     /** \returns the functor representing unary operation */
     75     const ViewOp& functor() const { return m_functor; }
     76 
     77     /** \returns the nested expression */
     78     const typename internal::remove_all<typename MatrixType::Nested>::type&
     79     nestedExpression() const { return m_matrix; }
     80 
     81     /** \returns the nested expression */
     82     typename internal::remove_all<typename MatrixType::Nested>::type&
     83     nestedExpression() { return m_matrix.const_cast_derived(); }
     84 
     85   protected:
     86     // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC
     87     typename internal::nested<MatrixType>::type m_matrix;
     88     ViewOp m_functor;
     89 };
     90 
     91 template<typename ViewOp, typename MatrixType>
     92 class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
     93   : public internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type
     94 {
     95   public:
     96 
     97     typedef CwiseUnaryView<ViewOp, MatrixType> Derived;
     98     typedef typename internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type Base;
     99 
    100     EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
    101     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
    102 
    103     inline Scalar* data() { return &coeffRef(0); }
    104     inline const Scalar* data() const { return &coeff(0); }
    105 
    106     inline Index innerStride() const
    107     {
    108       return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
    109     }
    110 
    111     inline Index outerStride() const
    112     {
    113       return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
    114     }
    115 
    116     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
    117     {
    118       return derived().functor()(derived().nestedExpression().coeff(row, col));
    119     }
    120 
    121     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
    122     {
    123       return derived().functor()(derived().nestedExpression().coeff(index));
    124     }
    125 
    126     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
    127     {
    128       return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col));
    129     }
    130 
    131     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
    132     {
    133       return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
    134     }
    135 };
    136 
    137 } // end namespace Eigen
    138 
    139 #endif // EIGEN_CWISE_UNARY_VIEW_H
    140