2009-05-10 16:24:39 +00:00
// This file is part of Eigen, a lightweight C++ template library
2009-05-22 20:25:33 +02:00
// for linear algebra.
2009-05-10 16:24:39 +00:00
//
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
2012-02-03 23:18:26 +01:00
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
2009-05-10 16:24:39 +00:00
//
2012-07-13 14:42:47 -04:00
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
2009-05-10 16:24:39 +00:00
# ifndef EIGEN_DIAGONAL_H
# define EIGEN_DIAGONAL_H
2021-03-05 13:16:43 +01:00
namespace Eigen {
2012-04-15 11:06:28 +01:00
2009-05-10 16:24:39 +00:00
/** \class Diagonal
2010-07-06 13:10:08 +01:00
* \ ingroup Core_Module
2009-05-10 16:24:39 +00:00
*
* \ brief Expression of a diagonal / subdiagonal / superdiagonal in a matrix
*
* \ param MatrixType the type of the object in which we are taking a sub / main / super diagonal
2010-05-30 16:00:58 -04:00
* \ param DiagIndex the index of the sub / super diagonal . The default is 0 and it means the main diagonal .
2009-05-10 16:24:39 +00:00
* A positive value means a superdiagonal , a negative value means a subdiagonal .
2017-01-21 22:09:59 +01:00
* You can also use DynamicIndex so the index can be set at runtime .
2009-05-10 16:24:39 +00:00
*
* The matrix is not required to be square .
*
* This class represents an expression of the main diagonal , or any sub / super diagonal
2010-05-30 16:00:58 -04:00
* of a square matrix . It is the return type of MatrixBase : : diagonal ( ) and MatrixBase : : diagonal ( Index ) and most of the
2009-05-10 16:24:39 +00:00
* time this is the only way it is used .
*
2010-05-30 16:00:58 -04:00
* \ sa MatrixBase : : diagonal ( ) , MatrixBase : : diagonal ( Index )
2009-05-10 16:24:39 +00:00
*/
2010-10-25 10:15:22 -04:00
namespace internal {
2010-05-30 16:00:58 -04:00
template < typename MatrixType , int DiagIndex >
2010-10-25 10:15:22 -04:00
struct traits < Diagonal < MatrixType , DiagIndex > >
: traits < MatrixType >
2009-05-10 16:24:39 +00:00
{
2015-06-19 17:56:39 +02:00
typedef typename ref_selector < MatrixType > : : type MatrixTypeNested ;
2010-10-25 22:13:49 +02:00
typedef typename remove_reference < MatrixTypeNested > : : type _MatrixTypeNested ;
2010-05-30 16:00:58 -04:00
typedef typename MatrixType : : StorageKind StorageKind ;
2009-05-10 16:24:39 +00:00
enum {
2012-07-10 23:04:17 +02:00
RowsAtCompileTime = ( int ( DiagIndex ) = = DynamicIndex | | int ( MatrixType : : SizeAtCompileTime ) = = Dynamic ) ? Dynamic
: ( EIGEN_PLAIN_ENUM_MIN ( MatrixType : : RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX ( - DiagIndex , 0 ) ,
MatrixType : : ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX ( DiagIndex , 0 ) ) ) ,
2009-05-10 16:24:39 +00:00
ColsAtCompileTime = 1 ,
MaxRowsAtCompileTime = int ( MatrixType : : MaxSizeAtCompileTime ) = = Dynamic ? Dynamic
2012-07-10 23:04:17 +02:00
: DiagIndex = = DynamicIndex ? EIGEN_SIZE_MIN_PREFER_FIXED ( MatrixType : : MaxRowsAtCompileTime ,
2012-07-10 22:39:05 +02:00
MatrixType : : MaxColsAtCompileTime )
: ( EIGEN_PLAIN_ENUM_MIN ( MatrixType : : MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX ( - DiagIndex , 0 ) ,
MatrixType : : MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX ( DiagIndex , 0 ) ) ) ,
2009-05-10 16:24:39 +00:00
MaxColsAtCompileTime = 1 ,
2014-03-12 13:34:11 +01:00
MaskLvalueBit = is_lvalue < MatrixType > : : value ? LvalueBit : 0 ,
Flags = ( unsigned int ) _MatrixTypeNested : : Flags & ( RowMajorBit | MaskLvalueBit | DirectAccessBit ) & ~ RowMajorBit , // FIXME DirectAccessBit should not be handled by expressions
2010-10-25 10:15:22 -04:00
MatrixTypeOuterStride = outer_stride_at_compile_time < MatrixType > : : ret ,
2010-05-08 14:19:04 -04:00
InnerStrideAtCompileTime = MatrixTypeOuterStride = = Dynamic ? Dynamic : MatrixTypeOuterStride + 1 ,
OuterStrideAtCompileTime = 0
2009-05-10 16:24:39 +00:00
} ;
} ;
2010-10-25 10:15:22 -04:00
}
2009-05-10 16:24:39 +00:00
2012-07-06 14:50:03 +01:00
template < typename MatrixType , int _DiagIndex > class Diagonal
: public internal : : dense_xpr_base < Diagonal < MatrixType , _DiagIndex > > : : type
2009-05-10 16:24:39 +00:00
{
public :
2012-07-06 14:50:03 +01:00
enum { DiagIndex = _DiagIndex } ;
2010-10-25 10:15:22 -04:00
typedef typename internal : : dense_xpr_base < Diagonal > : : type Base ;
2010-01-22 10:15:41 +01:00
EIGEN_DENSE_PUBLIC_INTERFACE ( Diagonal )
2009-05-10 16:24:39 +00:00
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2018-04-03 16:15:43 +02:00
explicit inline Diagonal ( MatrixType & matrix , Index a_index = DiagIndex ) : m_matrix ( matrix ) , m_index ( a_index )
{
eigen_assert ( a_index < = m_matrix . cols ( ) & & - a_index < = m_matrix . rows ( ) ) ;
}
2009-05-10 16:24:39 +00:00
EIGEN_INHERIT_ASSIGNMENT_OPERATORS ( Diagonal )
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2015-02-13 18:57:41 +01:00
inline Index rows ( ) const
2014-01-24 12:50:29 +01:00
{
2015-02-13 18:57:41 +01:00
return m_index . value ( ) < 0 ? numext : : mini < Index > ( m_matrix . cols ( ) , m_matrix . rows ( ) + m_index . value ( ) )
: numext : : mini < Index > ( m_matrix . rows ( ) , m_matrix . cols ( ) - m_index . value ( ) ) ;
2014-01-24 12:50:29 +01:00
}
2009-07-21 11:19:52 +02:00
2021-03-05 13:16:43 +01:00
EIGEN_DEVICE_FUNC
inline Index cols ( ) const { return 1 ; }
2009-05-10 16:24:39 +00:00
2021-03-05 13:16:43 +01:00
EIGEN_DEVICE_FUNC
inline Index innerStride ( ) const
{
2010-05-08 14:19:04 -04:00
return m_matrix . outerStride ( ) + 1 ;
}
2021-03-05 13:16:43 +01:00
EIGEN_DEVICE_FUNC
inline Index outerStride ( ) const
{
return 0 ;
}
2010-05-08 14:19:04 -04:00
2012-01-31 12:44:59 +01:00
typedef typename internal : : conditional <
internal : : is_lvalue < MatrixType > : : value ,
Scalar ,
const Scalar
> : : type ScalarWithConstIfNotLvalue ;
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2016-01-28 21:43:20 +01:00
inline ScalarWithConstIfNotLvalue * data ( ) { return & ( m_matrix . coeffRef ( rowOffset ( ) , colOffset ( ) ) ) ; }
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2016-01-28 21:43:20 +01:00
inline const Scalar * data ( ) const { return & ( m_matrix . coeffRef ( rowOffset ( ) , colOffset ( ) ) ) ; }
2012-01-31 12:44:59 +01:00
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2010-05-30 16:00:58 -04:00
inline Scalar & coeffRef ( Index row , Index )
2009-05-10 16:24:39 +00:00
{
2011-02-06 11:57:04 -05:00
EIGEN_STATIC_ASSERT_LVALUE ( MatrixType )
2016-01-28 21:43:20 +01:00
return m_matrix . coeffRef ( row + rowOffset ( ) , row + colOffset ( ) ) ;
2009-05-10 16:24:39 +00:00
}
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2010-12-22 17:45:37 -05:00
inline const Scalar & coeffRef ( Index row , Index ) const
{
2016-01-28 21:43:20 +01:00
return m_matrix . coeffRef ( row + rowOffset ( ) , row + colOffset ( ) ) ;
2010-12-22 17:45:37 -05:00
}
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2010-05-30 16:00:58 -04:00
inline CoeffReturnType coeff ( Index row , Index ) const
2009-05-10 16:24:39 +00:00
{
return m_matrix . coeff ( row + rowOffset ( ) , row + colOffset ( ) ) ;
}
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2012-06-22 16:32:45 +02:00
inline Scalar & coeffRef ( Index idx )
2009-05-10 16:24:39 +00:00
{
2011-02-06 11:57:04 -05:00
EIGEN_STATIC_ASSERT_LVALUE ( MatrixType )
2016-01-28 21:43:20 +01:00
return m_matrix . coeffRef ( idx + rowOffset ( ) , idx + colOffset ( ) ) ;
2009-05-10 16:24:39 +00:00
}
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2012-06-22 16:32:45 +02:00
inline const Scalar & coeffRef ( Index idx ) const
2010-12-22 17:45:37 -05:00
{
2016-01-28 21:43:20 +01:00
return m_matrix . coeffRef ( idx + rowOffset ( ) , idx + colOffset ( ) ) ;
2010-12-22 17:45:37 -05:00
}
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2012-06-22 16:32:45 +02:00
inline CoeffReturnType coeff ( Index idx ) const
2009-05-10 16:24:39 +00:00
{
2012-06-22 16:32:45 +02:00
return m_matrix . coeff ( idx + rowOffset ( ) , idx + colOffset ( ) ) ;
2009-05-10 16:24:39 +00:00
}
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2021-03-05 13:16:43 +01:00
inline const typename internal : : remove_all < typename MatrixType : : Nested > : : type &
nestedExpression ( ) const
2011-04-22 22:36:45 +01:00
{
return m_matrix ;
}
2013-07-31 15:30:50 +02:00
EIGEN_DEVICE_FUNC
2015-02-13 18:57:41 +01:00
inline Index index ( ) const
2011-04-22 22:36:45 +01:00
{
return m_index . value ( ) ;
}
2009-05-10 16:24:39 +00:00
protected :
2016-01-28 21:43:20 +01:00
typename internal : : ref_selector < MatrixType > : : non_const_type m_matrix ;
2015-02-13 18:57:41 +01:00
const internal : : variable_if_dynamicindex < Index , DiagIndex > m_index ;
2010-05-30 16:00:58 -04:00
private :
// some compilers may fail to optimize std::max etc in case of compile-time constants...
2021-03-05 13:16:43 +01:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index absDiagIndex ( ) const { return m_index . value ( ) > 0 ? m_index . value ( ) : - m_index . value ( ) ; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index rowOffset ( ) const { return m_index . value ( ) > 0 ? 0 : - m_index . value ( ) ; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index colOffset ( ) const { return m_index . value ( ) > 0 ? m_index . value ( ) : 0 ; }
2015-08-07 12:01:39 +02:00
// trigger a compile-time error if someone try to call packet
2010-07-07 11:07:12 +02:00
template < int LoadMode > typename MatrixType : : PacketReturnType packet ( Index ) const ;
template < int LoadMode > typename MatrixType : : PacketReturnType packet ( Index , Index ) const ;
2009-05-10 16:24:39 +00:00
} ;
/** \returns an expression of the main diagonal of the matrix \c *this
*
* \ c * this is not required to be square .
*
* Example : \ include MatrixBase_diagonal . cpp
* Output : \ verbinclude MatrixBase_diagonal . out
*
* \ sa class Diagonal */
template < typename Derived >
2017-02-28 09:46:30 -08:00
EIGEN_DEVICE_FUNC inline typename MatrixBase < Derived > : : DiagonalReturnType
2009-05-10 16:24:39 +00:00
MatrixBase < Derived > : : diagonal ( )
{
2014-09-23 14:28:23 +02:00
return DiagonalReturnType ( derived ( ) ) ;
2009-05-10 16:24:39 +00:00
}
/** This is the const version of diagonal(). */
template < typename Derived >
2017-02-28 09:46:30 -08:00
EIGEN_DEVICE_FUNC inline typename MatrixBase < Derived > : : ConstDiagonalReturnType
2009-05-10 16:24:39 +00:00
MatrixBase < Derived > : : diagonal ( ) const
{
2011-01-18 09:14:14 -05:00
return ConstDiagonalReturnType ( derived ( ) ) ;
2009-05-10 16:24:39 +00:00
}
2010-05-30 16:00:58 -04:00
/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
2009-05-10 16:24:39 +00:00
*
* \ c * this is not required to be square .
*
2010-05-30 16:00:58 -04:00
* The template parameter \ a DiagIndex represent a super diagonal if \ a DiagIndex > 0
* and a sub diagonal otherwise . \ a DiagIndex = = 0 is equivalent to the main diagonal .
2009-05-10 16:24:39 +00:00
*
* Example : \ include MatrixBase_diagonal_int . cpp
* Output : \ verbinclude MatrixBase_diagonal_int . out
*
* \ sa MatrixBase : : diagonal ( ) , class Diagonal */
template < typename Derived >
2017-02-28 09:46:30 -08:00
EIGEN_DEVICE_FUNC inline typename MatrixBase < Derived > : : DiagonalDynamicIndexReturnType
2010-05-30 16:00:58 -04:00
MatrixBase < Derived > : : diagonal ( Index index )
2009-05-10 16:24:39 +00:00
{
2014-12-02 14:35:31 +01:00
return DiagonalDynamicIndexReturnType ( derived ( ) , index ) ;
2009-05-10 16:24:39 +00:00
}
2010-05-30 16:00:58 -04:00
/** This is the const version of diagonal(Index). */
2009-05-10 16:24:39 +00:00
template < typename Derived >
2017-02-28 09:46:30 -08:00
EIGEN_DEVICE_FUNC inline typename MatrixBase < Derived > : : ConstDiagonalDynamicIndexReturnType
2010-05-30 16:00:58 -04:00
MatrixBase < Derived > : : diagonal ( Index index ) const
2009-05-10 16:24:39 +00:00
{
2014-12-02 14:35:31 +01:00
return ConstDiagonalDynamicIndexReturnType ( derived ( ) , index ) ;
2009-05-10 16:24:39 +00:00
}
2010-05-30 16:00:58 -04:00
/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
2009-05-10 16:24:39 +00:00
*
* \ c * this is not required to be square .
*
2010-05-30 16:00:58 -04:00
* The template parameter \ a DiagIndex represent a super diagonal if \ a DiagIndex > 0
* and a sub diagonal otherwise . \ a DiagIndex = = 0 is equivalent to the main diagonal .
2009-05-10 16:24:39 +00:00
*
* Example : \ include MatrixBase_diagonal_template_int . cpp
* Output : \ verbinclude MatrixBase_diagonal_template_int . out
*
* \ sa MatrixBase : : diagonal ( ) , class Diagonal */
template < typename Derived >
2014-09-23 14:28:23 +02:00
template < int Index_ >
2017-02-28 09:46:30 -08:00
EIGEN_DEVICE_FUNC
2014-09-23 14:28:23 +02:00
inline typename MatrixBase < Derived > : : template DiagonalIndexReturnType < Index_ > : : Type
2009-05-10 16:24:39 +00:00
MatrixBase < Derived > : : diagonal ( )
{
2014-09-23 14:28:23 +02:00
return typename DiagonalIndexReturnType < Index_ > : : Type ( derived ( ) ) ;
2009-05-10 16:24:39 +00:00
}
/** This is the const version of diagonal<int>(). */
template < typename Derived >
2014-09-23 14:28:23 +02:00
template < int Index_ >
2017-02-28 09:46:30 -08:00
EIGEN_DEVICE_FUNC
2014-09-23 14:28:23 +02:00
inline typename MatrixBase < Derived > : : template ConstDiagonalIndexReturnType < Index_ > : : Type
2009-05-10 16:24:39 +00:00
MatrixBase < Derived > : : diagonal ( ) const
{
2014-09-23 14:28:23 +02:00
return typename ConstDiagonalIndexReturnType < Index_ > : : Type ( derived ( ) ) ;
2009-05-10 16:24:39 +00:00
}
2012-04-15 11:06:28 +01:00
} // end namespace Eigen
2009-05-10 16:24:39 +00:00
# endif // EIGEN_DIAGONAL_H