Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:56:13

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
0005 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
0006 //
0007 // This Source Code Form is subject to the terms of the Mozilla
0008 // Public License v. 2.0. If a copy of the MPL was not distributed
0009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0010 
0011 #ifndef EIGEN_DIAGONAL_H
0012 #define EIGEN_DIAGONAL_H
0013 
0014 namespace Eigen {
0015 
0016 /** \class Diagonal
0017   * \ingroup Core_Module
0018   *
0019   * \brief Expression of a diagonal/subdiagonal/superdiagonal in a matrix
0020   *
0021   * \param MatrixType the type of the object in which we are taking a sub/main/super diagonal
0022   * \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal.
0023   *              A positive value means a superdiagonal, a negative value means a subdiagonal.
0024   *              You can also use DynamicIndex so the index can be set at runtime.
0025   *
0026   * The matrix is not required to be square.
0027   *
0028   * This class represents an expression of the main diagonal, or any sub/super diagonal
0029   * of a square matrix. It is the return type of MatrixBase::diagonal() and MatrixBase::diagonal(Index) and most of the
0030   * time this is the only way it is used.
0031   *
0032   * \sa MatrixBase::diagonal(), MatrixBase::diagonal(Index)
0033   */
0034 
0035 namespace internal {
0036 template<typename MatrixType, int DiagIndex>
0037 struct traits<Diagonal<MatrixType,DiagIndex> >
0038  : traits<MatrixType>
0039 {
0040   typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
0041   typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
0042   typedef typename MatrixType::StorageKind StorageKind;
0043   enum {
0044     RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic
0045                       : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
0046                                               MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
0047     ColsAtCompileTime = 1,
0048     MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
0049                          : DiagIndex == DynamicIndex ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime,
0050                                                                               MatrixType::MaxColsAtCompileTime)
0051                          : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
0052                                                  MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
0053     MaxColsAtCompileTime = 1,
0054     MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
0055     Flags = (unsigned int)_MatrixTypeNested::Flags & (RowMajorBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, // FIXME DirectAccessBit should not be handled by expressions
0056     MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret,
0057     InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
0058     OuterStrideAtCompileTime = 0
0059   };
0060 };
0061 }
0062 
0063 template<typename MatrixType, int _DiagIndex> class Diagonal
0064    : public internal::dense_xpr_base< Diagonal<MatrixType,_DiagIndex> >::type
0065 {
0066   public:
0067 
0068     enum { DiagIndex = _DiagIndex };
0069     typedef typename internal::dense_xpr_base<Diagonal>::type Base;
0070     EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
0071 
0072     EIGEN_DEVICE_FUNC
0073     explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index)
0074     {
0075       eigen_assert( a_index <= m_matrix.cols() && -a_index <= m_matrix.rows() );
0076     }
0077 
0078     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
0079 
0080     EIGEN_DEVICE_FUNC
0081     inline Index rows() const
0082     {
0083       return m_index.value()<0 ? numext::mini<Index>(m_matrix.cols(),m_matrix.rows()+m_index.value())
0084                                : numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
0085     }
0086 
0087     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0088     inline Index cols() const EIGEN_NOEXCEPT { return 1; }
0089 
0090     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0091     inline Index innerStride() const EIGEN_NOEXCEPT {
0092       return m_matrix.outerStride() + 1;
0093     }
0094 
0095     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0096     inline Index outerStride() const EIGEN_NOEXCEPT { return 0; }
0097 
0098     typedef typename internal::conditional<
0099                        internal::is_lvalue<MatrixType>::value,
0100                        Scalar,
0101                        const Scalar
0102                      >::type ScalarWithConstIfNotLvalue;
0103 
0104     EIGEN_DEVICE_FUNC
0105     inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.coeffRef(rowOffset(), colOffset())); }
0106     EIGEN_DEVICE_FUNC
0107     inline const Scalar* data() const { return &(m_matrix.coeffRef(rowOffset(), colOffset())); }
0108 
0109     EIGEN_DEVICE_FUNC
0110     inline Scalar& coeffRef(Index row, Index)
0111     {
0112       EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
0113       return m_matrix.coeffRef(row+rowOffset(), row+colOffset());
0114     }
0115 
0116     EIGEN_DEVICE_FUNC
0117     inline const Scalar& coeffRef(Index row, Index) const
0118     {
0119       return m_matrix.coeffRef(row+rowOffset(), row+colOffset());
0120     }
0121 
0122     EIGEN_DEVICE_FUNC
0123     inline CoeffReturnType coeff(Index row, Index) const
0124     {
0125       return m_matrix.coeff(row+rowOffset(), row+colOffset());
0126     }
0127 
0128     EIGEN_DEVICE_FUNC
0129     inline Scalar& coeffRef(Index idx)
0130     {
0131       EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
0132       return m_matrix.coeffRef(idx+rowOffset(), idx+colOffset());
0133     }
0134 
0135     EIGEN_DEVICE_FUNC
0136     inline const Scalar& coeffRef(Index idx) const
0137     {
0138       return m_matrix.coeffRef(idx+rowOffset(), idx+colOffset());
0139     }
0140 
0141     EIGEN_DEVICE_FUNC
0142     inline CoeffReturnType coeff(Index idx) const
0143     {
0144       return m_matrix.coeff(idx+rowOffset(), idx+colOffset());
0145     }
0146 
0147     EIGEN_DEVICE_FUNC
0148     inline const typename internal::remove_all<typename MatrixType::Nested>::type&
0149     nestedExpression() const
0150     {
0151       return m_matrix;
0152     }
0153 
0154     EIGEN_DEVICE_FUNC
0155     inline Index index() const
0156     {
0157       return m_index.value();
0158     }
0159 
0160   protected:
0161     typename internal::ref_selector<MatrixType>::non_const_type m_matrix;
0162     const internal::variable_if_dynamicindex<Index, DiagIndex> m_index;
0163 
0164   private:
0165     // some compilers may fail to optimize std::max etc in case of compile-time constants...
0166     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
0167     Index absDiagIndex() const EIGEN_NOEXCEPT { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
0168     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
0169     Index rowOffset() const EIGEN_NOEXCEPT { return m_index.value()>0 ? 0 : -m_index.value(); }
0170     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
0171     Index colOffset() const EIGEN_NOEXCEPT { return m_index.value()>0 ? m_index.value() : 0; }
0172     // trigger a compile-time error if someone try to call packet
0173     template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const;
0174     template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
0175 };
0176 
0177 /** \returns an expression of the main diagonal of the matrix \c *this
0178   *
0179   * \c *this is not required to be square.
0180   *
0181   * Example: \include MatrixBase_diagonal.cpp
0182   * Output: \verbinclude MatrixBase_diagonal.out
0183   *
0184   * \sa class Diagonal */
0185 template<typename Derived>
0186 EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalReturnType
0187 MatrixBase<Derived>::diagonal()
0188 {
0189   return DiagonalReturnType(derived());
0190 }
0191 
0192 /** This is the const version of diagonal(). */
0193 template<typename Derived>
0194 EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalReturnType
0195 MatrixBase<Derived>::diagonal() const
0196 {
0197   return ConstDiagonalReturnType(derived());
0198 }
0199 
0200 /** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
0201   *
0202   * \c *this is not required to be square.
0203   *
0204   * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0
0205   * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal.
0206   *
0207   * Example: \include MatrixBase_diagonal_int.cpp
0208   * Output: \verbinclude MatrixBase_diagonal_int.out
0209   *
0210   * \sa MatrixBase::diagonal(), class Diagonal */
0211 template<typename Derived>
0212 EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
0213 MatrixBase<Derived>::diagonal(Index index)
0214 {
0215   return DiagonalDynamicIndexReturnType(derived(), index);
0216 }
0217 
0218 /** This is the const version of diagonal(Index). */
0219 template<typename Derived>
0220 EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
0221 MatrixBase<Derived>::diagonal(Index index) const
0222 {
0223   return ConstDiagonalDynamicIndexReturnType(derived(), index);
0224 }
0225 
0226 /** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
0227   *
0228   * \c *this is not required to be square.
0229   *
0230   * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0
0231   * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal.
0232   *
0233   * Example: \include MatrixBase_diagonal_template_int.cpp
0234   * Output: \verbinclude MatrixBase_diagonal_template_int.out
0235   *
0236   * \sa MatrixBase::diagonal(), class Diagonal */
0237 template<typename Derived>
0238 template<int Index_>
0239 EIGEN_DEVICE_FUNC
0240 inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index_>::Type
0241 MatrixBase<Derived>::diagonal()
0242 {
0243   return typename DiagonalIndexReturnType<Index_>::Type(derived());
0244 }
0245 
0246 /** This is the const version of diagonal<int>(). */
0247 template<typename Derived>
0248 template<int Index_>
0249 EIGEN_DEVICE_FUNC
0250 inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index_>::Type
0251 MatrixBase<Derived>::diagonal() const
0252 {
0253   return typename ConstDiagonalIndexReturnType<Index_>::Type(derived());
0254 }
0255 
0256 } // end namespace Eigen
0257 
0258 #endif // EIGEN_DIAGONAL_H