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)
     48                                * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
     49     OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
     50   };
     51 };
     52 }
     53 
     54 template<typename ViewOp, typename MatrixType, typename StorageKind>
     55 class CwiseUnaryViewImpl;
     56 
     57 template<typename ViewOp, typename MatrixType>
     58 class CwiseUnaryView : internal::no_assignment_operator,
     59   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 
    102     inline Index innerStride() const
    103     {
    104       return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
    105     }
    106 
    107     inline Index outerStride() const
    108     {
    109       return derived().nestedExpression().outerStride();
    110     }
    111 
    112     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
    113     {
    114       return derived().functor()(derived().nestedExpression().coeff(row, col));
    115     }
    116 
    117     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
    118     {
    119       return derived().functor()(derived().nestedExpression().coeff(index));
    120     }
    121 
    122     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
    123     {
    124       return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col));
    125     }
    126 
    127     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
    128     {
    129       return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
    130     }
    131 };
    132 
    133 } // end namespace Eigen
    134 
    135 #endif // EIGEN_CWISE_UNARY_VIEW_H
    136