cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

IndexedView.h (9620B)


      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@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_INDEXED_VIEW_H
     11 #define EIGEN_INDEXED_VIEW_H
     12 
     13 namespace Eigen {
     14 
     15 namespace internal {
     16 
     17 template<typename XprType, typename RowIndices, typename ColIndices>
     18 struct traits<IndexedView<XprType, RowIndices, ColIndices> >
     19  : traits<XprType>
     20 {
     21   enum {
     22     RowsAtCompileTime = int(array_size<RowIndices>::value),
     23     ColsAtCompileTime = int(array_size<ColIndices>::value),
     24     MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : Dynamic,
     25     MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : Dynamic,
     26 
     27     XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
     28     IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
     29                : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
     30                : XprTypeIsRowMajor,
     31 
     32     RowIncr = int(get_compile_time_incr<RowIndices>::value),
     33     ColIncr = int(get_compile_time_incr<ColIndices>::value),
     34     InnerIncr = IsRowMajor ? ColIncr : RowIncr,
     35     OuterIncr = IsRowMajor ? RowIncr : ColIncr,
     36 
     37     HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
     38     XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret),
     39     XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret),
     40 
     41     InnerSize = XprTypeIsRowMajor ? ColsAtCompileTime : RowsAtCompileTime,
     42     IsBlockAlike = InnerIncr==1 && OuterIncr==1,
     43     IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange<InnerSize>,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value,
     44 
     45     InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr,
     46     OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr,
     47 
     48     ReturnAsScalar = is_same<RowIndices,SingleRange>::value && is_same<ColIndices,SingleRange>::value,
     49     ReturnAsBlock = (!ReturnAsScalar) && IsBlockAlike,
     50     ReturnAsIndexedView = (!ReturnAsScalar) && (!ReturnAsBlock),
     51 
     52     // FIXME we deal with compile-time strides if and only if we have DirectAccessBit flag,
     53     // but this is too strict regarding negative strides...
     54     DirectAccessMask = (int(InnerIncr)!=UndefinedIncr && int(OuterIncr)!=UndefinedIncr && InnerIncr>=0 && OuterIncr>=0) ? DirectAccessBit : 0,
     55     FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
     56     FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
     57     FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
     58     Flags = (traits<XprType>::Flags & (HereditaryBits | DirectAccessMask )) | FlagsLvalueBit | FlagsRowMajorBit | FlagsLinearAccessBit
     59   };
     60 
     61   typedef Block<XprType,RowsAtCompileTime,ColsAtCompileTime,IsInnerPannel> BlockType;
     62 };
     63 
     64 }
     65 
     66 template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
     67 class IndexedViewImpl;
     68 
     69 
     70 /** \class IndexedView
     71   * \ingroup Core_Module
     72   *
     73   * \brief Expression of a non-sequential sub-matrix defined by arbitrary sequences of row and column indices
     74   *
     75   * \tparam XprType the type of the expression in which we are taking the intersections of sub-rows and sub-columns
     76   * \tparam RowIndices the type of the object defining the sequence of row indices
     77   * \tparam ColIndices the type of the object defining the sequence of column indices
     78   *
     79   * This class represents an expression of a sub-matrix (or sub-vector) defined as the intersection
     80   * of sub-sets of rows and columns, that are themself defined by generic sequences of row indices \f$ \{r_0,r_1,..r_{m-1}\} \f$
     81   * and column indices \f$ \{c_0,c_1,..c_{n-1} \}\f$. Let \f$ A \f$  be the nested matrix, then the resulting matrix \f$ B \f$ has \c m
     82   * rows and \c n columns, and its entries are given by: \f$ B(i,j) = A(r_i,c_j) \f$.
     83   *
     84   * The \c RowIndices and \c ColIndices types must be compatible with the following API:
     85   * \code
     86   * <integral type> operator[](Index) const;
     87   * Index size() const;
     88   * \endcode
     89   *
     90   * Typical supported types thus include:
     91   *  - std::vector<int>
     92   *  - std::valarray<int>
     93   *  - std::array<int>
     94   *  - Plain C arrays: int[N]
     95   *  - Eigen::ArrayXi
     96   *  - decltype(ArrayXi::LinSpaced(...))
     97   *  - Any view/expressions of the previous types
     98   *  - Eigen::ArithmeticSequence
     99   *  - Eigen::internal::AllRange      (helper for Eigen::all)
    100   *  - Eigen::internal::SingleRange  (helper for single index)
    101   *  - etc.
    102   *
    103   * In typical usages of %Eigen, this class should never be used directly. It is the return type of
    104   * DenseBase::operator()(const RowIndices&, const ColIndices&).
    105   *
    106   * \sa class Block
    107   */
    108 template<typename XprType, typename RowIndices, typename ColIndices>
    109 class IndexedView : public IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>
    110 {
    111 public:
    112   typedef typename IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>::Base Base;
    113   EIGEN_GENERIC_PUBLIC_INTERFACE(IndexedView)
    114   EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedView)
    115 
    116   typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
    117   typedef typename internal::remove_all<XprType>::type NestedExpression;
    118 
    119   template<typename T0, typename T1>
    120   IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices)
    121     : m_xpr(xpr), m_rowIndices(rowIndices), m_colIndices(colIndices)
    122   {}
    123 
    124   /** \returns number of rows */
    125   Index rows() const { return internal::size(m_rowIndices); }
    126 
    127   /** \returns number of columns */
    128   Index cols() const { return internal::size(m_colIndices); }
    129 
    130   /** \returns the nested expression */
    131   const typename internal::remove_all<XprType>::type&
    132   nestedExpression() const { return m_xpr; }
    133 
    134   /** \returns the nested expression */
    135   typename internal::remove_reference<XprType>::type&
    136   nestedExpression() { return m_xpr; }
    137 
    138   /** \returns a const reference to the object storing/generating the row indices */
    139   const RowIndices& rowIndices() const { return m_rowIndices; }
    140 
    141   /** \returns a const reference to the object storing/generating the column indices */
    142   const ColIndices& colIndices() const { return m_colIndices; }
    143 
    144 protected:
    145   MatrixTypeNested m_xpr;
    146   RowIndices m_rowIndices;
    147   ColIndices m_colIndices;
    148 };
    149 
    150 
    151 // Generic API dispatcher
    152 template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
    153 class IndexedViewImpl
    154   : public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type
    155 {
    156 public:
    157   typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type Base;
    158 };
    159 
    160 namespace internal {
    161 
    162 
    163 template<typename ArgType, typename RowIndices, typename ColIndices>
    164 struct unary_evaluator<IndexedView<ArgType, RowIndices, ColIndices>, IndexBased>
    165   : evaluator_base<IndexedView<ArgType, RowIndices, ColIndices> >
    166 {
    167   typedef IndexedView<ArgType, RowIndices, ColIndices> XprType;
    168 
    169   enum {
    170     CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of row/col index */,
    171 
    172     FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1) ? LinearAccessBit : 0,
    173 
    174     FlagsRowMajorBit = traits<XprType>::FlagsRowMajorBit, 
    175 
    176     Flags = (evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit /*| LinearAccessBit | DirectAccessBit*/)) | FlagsLinearAccessBit | FlagsRowMajorBit,
    177 
    178     Alignment = 0
    179   };
    180 
    181   EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
    182   {
    183     EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
    184   }
    185 
    186   typedef typename XprType::Scalar Scalar;
    187   typedef typename XprType::CoeffReturnType CoeffReturnType;
    188 
    189   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    190   CoeffReturnType coeff(Index row, Index col) const
    191   {
    192     return m_argImpl.coeff(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
    193   }
    194 
    195   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    196   Scalar& coeffRef(Index row, Index col)
    197   {
    198     return m_argImpl.coeffRef(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
    199   }
    200 
    201   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    202   Scalar& coeffRef(Index index)
    203   {
    204     EIGEN_STATIC_ASSERT_LVALUE(XprType)
    205     Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
    206     Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
    207     return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
    208   }
    209 
    210   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    211   const Scalar& coeffRef(Index index) const
    212   {
    213     Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
    214     Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
    215     return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
    216   }
    217 
    218   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    219   const CoeffReturnType coeff(Index index) const
    220   {
    221     Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
    222     Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
    223     return m_argImpl.coeff( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
    224   }
    225 
    226 protected:
    227 
    228   evaluator<ArgType> m_argImpl;
    229   const XprType& m_xpr;
    230 
    231 };
    232 
    233 } // end namespace internal
    234 
    235 } // end namespace Eigen
    236 
    237 #endif // EIGEN_INDEXED_VIEW_H