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) 2008-2010 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_CWISE_UNARY_OP_H
     12 #define EIGEN_CWISE_UNARY_OP_H
     13 
     14 namespace Eigen {
     15 
     16 /** \class CwiseUnaryOp
     17   * \ingroup Core_Module
     18   *
     19   * \brief Generic expression where a coefficient-wise unary operator is applied to an expression
     20   *
     21   * \param UnaryOp template functor implementing the operator
     22   * \param XprType the type of the expression to which we are applying the unary operator
     23   *
     24   * This class represents an expression where a unary operator is applied to an expression.
     25   * It is the return type of all operations taking exactly 1 input expression, regardless of the
     26   * presence of other inputs such as scalars. For example, the operator* in the expression 3*matrix
     27   * is considered unary, because only the right-hand side is an expression, and its
     28   * return type is a specialization of CwiseUnaryOp.
     29   *
     30   * Most of the time, this is the only way that it is used, so you typically don't have to name
     31   * CwiseUnaryOp types explicitly.
     32   *
     33   * \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp
     34   */
     35 
     36 namespace internal {
     37 template<typename UnaryOp, typename XprType>
     38 struct traits<CwiseUnaryOp<UnaryOp, XprType> >
     39  : traits<XprType>
     40 {
     41   typedef typename result_of<
     42                      UnaryOp(typename XprType::Scalar)
     43                    >::type Scalar;
     44   typedef typename XprType::Nested XprTypeNested;
     45   typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
     46   enum {
     47     Flags = _XprTypeNested::Flags & (
     48       HereditaryBits | LinearAccessBit | AlignedBit
     49       | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
     50     CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits<UnaryOp>::Cost
     51   };
     52 };
     53 }
     54 
     55 template<typename UnaryOp, typename XprType, typename StorageKind>
     56 class CwiseUnaryOpImpl;
     57 
     58 template<typename UnaryOp, typename XprType>
     59 class CwiseUnaryOp : internal::no_assignment_operator,
     60   public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>
     61 {
     62   public:
     63 
     64     typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base;
     65     EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
     66 
     67     inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
     68       : m_xpr(xpr), m_functor(func) {}
     69 
     70     EIGEN_STRONG_INLINE Index rows() const { return m_xpr.rows(); }
     71     EIGEN_STRONG_INLINE Index cols() const { return m_xpr.cols(); }
     72 
     73     /** \returns the functor representing the unary operation */
     74     const UnaryOp& functor() const { return m_functor; }
     75 
     76     /** \returns the nested expression */
     77     const typename internal::remove_all<typename XprType::Nested>::type&
     78     nestedExpression() const { return m_xpr; }
     79 
     80     /** \returns the nested expression */
     81     typename internal::remove_all<typename XprType::Nested>::type&
     82     nestedExpression() { return m_xpr.const_cast_derived(); }
     83 
     84   protected:
     85     typename XprType::Nested m_xpr;
     86     const UnaryOp m_functor;
     87 };
     88 
     89 // This is the generic implementation for dense storage.
     90 // It can be used for any expression types implementing the dense concept.
     91 template<typename UnaryOp, typename XprType>
     92 class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
     93   : public internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
     94 {
     95   public:
     96 
     97     typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
     98     typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
     99     EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
    100 
    101     EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
    102     {
    103       return derived().functor()(derived().nestedExpression().coeff(rowId, colId));
    104     }
    105 
    106     template<int LoadMode>
    107     EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
    108     {
    109       return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(rowId, colId));
    110     }
    111 
    112     EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
    113     {
    114       return derived().functor()(derived().nestedExpression().coeff(index));
    115     }
    116 
    117     template<int LoadMode>
    118     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
    119     {
    120       return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
    121     }
    122 };
    123 
    124 } // end namespace Eigen
    125 
    126 #endif // EIGEN_CWISE_UNARY_OP_H
    127