2009-12-17 13:37:00 +01:00
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
2010-06-24 23:21:58 +02:00
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
2009-12-17 13:37:00 +01:00
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
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-12-17 13:37:00 +01:00
# ifndef EIGEN_DENSESTORAGEBASE_H
# define EIGEN_DENSESTORAGEBASE_H
2013-02-07 18:07:07 +01:00
# if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
2013-02-22 15:09:03 +01:00
# define EIGEN_INITIALIZE_COEFFS
2021-03-29 09:25:39 -07:00
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(Index i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
2013-02-07 18:07:07 +01:00
# elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
2013-02-22 15:09:03 +01:00
# define EIGEN_INITIALIZE_COEFFS
2021-03-29 09:25:39 -07:00
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(Index i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
2009-12-17 13:37:00 +01:00
# else
2013-02-22 15:09:03 +01:00
# undef EIGEN_INITIALIZE_COEFFS
2013-02-07 18:07:07 +01:00
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
2009-12-17 13:37:00 +01:00
# endif
2012-04-15 11:06:28 +01:00
namespace Eigen {
2010-10-25 10:15:22 -04:00
namespace internal {
2012-06-26 22:16:07 +02:00
template < int MaxSizeAtCompileTime > struct check_rows_cols_for_overflow {
template < typename Index >
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2012-06-26 22:16:07 +02:00
static EIGEN_ALWAYS_INLINE void run ( Index , Index )
{
}
} ;
template < > struct check_rows_cols_for_overflow < Dynamic > {
template < typename Index >
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2012-06-26 22:16:07 +02:00
static EIGEN_ALWAYS_INLINE void run ( Index rows , Index cols )
{
// http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
// we assume Index is signed
2017-01-23 22:02:53 +01:00
Index max_index = ( std : : size_t ( 1 ) < < ( 8 * sizeof ( Index ) - 1 ) ) - 1 ; // assume Index is signed
2012-06-26 22:16:07 +02:00
bool error = ( rows = = 0 | | cols = = 0 ) ? false
: ( rows > max_index / cols ) ;
if ( error )
throw_std_bad_alloc ( ) ;
}
} ;
2011-10-16 16:12:19 -04:00
2013-10-16 12:07:33 +02:00
template < typename Derived ,
typename OtherDerived = Derived ,
bool IsVector = bool ( Derived : : IsVectorAtCompileTime ) & & bool ( OtherDerived : : IsVectorAtCompileTime ) >
struct conservative_resize_like_impl ;
2010-10-25 10:15:22 -04:00
template < typename MatrixTypeA , typename MatrixTypeB , bool SwapPointers > struct matrix_swap_impl ;
} // end namespace internal
2009-12-17 13:37:00 +01:00
2011-12-19 22:13:11 +01:00
# ifdef EIGEN_PARSED_BY_DOXYGEN
2016-06-01 09:38:49 +02:00
namespace doxygen {
2011-12-19 22:13:11 +01:00
2017-01-04 22:02:39 +01:00
// This is a workaround to doxygen not being able to understand the inheritance logic
2011-12-19 22:13:11 +01:00
// when it is hidden by the dense_xpr_base helper struct.
2017-01-04 22:02:39 +01:00
// Moreover, doxygen fails to include members that are not documented in the declaration body of
// MatrixBase if we inherits MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >,
// this is why we simply inherits MatrixBase, though this does not make sense.
2015-06-05 14:40:07 +02:00
/** This class is just a workaround for Doxygen and it does not not actually exist. */
2016-06-01 09:38:49 +02:00
template < typename Derived > struct dense_xpr_base_dispatcher ;
2011-12-19 22:13:11 +01:00
/** This class is just a workaround for Doxygen and it does not not actually exist. */
template < typename _Scalar , int _Rows , int _Cols , int _Options , int _MaxRows , int _MaxCols >
2016-06-01 09:38:49 +02:00
struct dense_xpr_base_dispatcher < Matrix < _Scalar , _Rows , _Cols , _Options , _MaxRows , _MaxCols > >
2017-01-04 22:02:39 +01:00
: public MatrixBase { } ;
2011-12-19 22:13:11 +01:00
/** This class is just a workaround for Doxygen and it does not not actually exist. */
template < typename _Scalar , int _Rows , int _Cols , int _Options , int _MaxRows , int _MaxCols >
2016-06-01 09:38:49 +02:00
struct dense_xpr_base_dispatcher < Array < _Scalar , _Rows , _Cols , _Options , _MaxRows , _MaxCols > >
2017-01-04 22:02:39 +01:00
: public ArrayBase { } ;
2011-12-19 22:13:11 +01:00
2016-06-01 09:38:49 +02:00
} // namespace doxygen
2011-12-19 22:13:11 +01:00
2017-01-04 22:02:39 +01:00
/** \class PlainObjectBase
* \ ingroup Core_Module
* \ brief % Dense storage base class for matrices and arrays .
*
* This class can be extended with the help of the plugin mechanism described on the page
* \ ref TopicCustomizing_Plugins by defining the preprocessor symbol \ c EIGEN_PLAINOBJECTBASE_PLUGIN .
*
* \ tparam Derived is the derived type , e . g . , a Matrix or Array
*
* \ sa \ ref TopicClassHierarchy
*/
2011-12-19 22:13:11 +01:00
template < typename Derived >
2016-06-01 09:38:49 +02:00
class PlainObjectBase : public doxygen : : dense_xpr_base_dispatcher < Derived >
2011-12-19 22:13:11 +01:00
# else
2010-04-16 10:13:32 -04:00
template < typename Derived >
2010-10-25 10:15:22 -04:00
class PlainObjectBase : public internal : : dense_xpr_base < Derived > : : type
2011-12-19 22:13:11 +01:00
# endif
2009-12-17 13:37:00 +01:00
{
public :
2010-10-25 10:15:22 -04:00
enum { Options = internal : : traits < Derived > : : Options } ;
typedef typename internal : : dense_xpr_base < Derived > : : type Base ;
2010-05-30 16:00:58 -04:00
2010-10-25 10:15:22 -04:00
typedef typename internal : : traits < Derived > : : StorageKind StorageKind ;
typedef typename internal : : traits < Derived > : : Scalar Scalar ;
2018-09-18 04:15:01 -04:00
2010-10-25 10:15:22 -04:00
typedef typename internal : : packet_traits < Scalar > : : type PacketScalar ;
2010-05-30 16:00:58 -04:00
typedef typename NumTraits < Scalar > : : Real RealScalar ;
2011-01-28 13:04:23 -05:00
typedef Derived DenseType ;
2010-05-30 16:00:58 -04:00
2009-12-17 13:37:00 +01:00
using Base : : RowsAtCompileTime ;
using Base : : ColsAtCompileTime ;
using Base : : SizeAtCompileTime ;
using Base : : MaxRowsAtCompileTime ;
using Base : : MaxColsAtCompileTime ;
using Base : : MaxSizeAtCompileTime ;
using Base : : IsVectorAtCompileTime ;
using Base : : Flags ;
2009-12-17 14:48:26 +01:00
2010-12-22 17:45:37 -05:00
typedef Eigen : : Map < Derived , Unaligned > MapType ;
typedef const Eigen : : Map < const Derived , Unaligned > ConstMapType ;
2015-08-17 21:50:52 +02:00
typedef Eigen : : Map < Derived , AlignedMax > AlignedMapType ;
First part of a big refactoring of alignment control to enable the handling of arbitrarily aligned buffers. It includes:
- AlignedBit flag is deprecated. Alignment is now specified by the evaluator through the 'Alignment' enum, e.g., evaluator<Xpr>::Alignment. Its value is in Bytes.
- Add several enums to specify alignment: Aligned8, Aligned16, Aligned32, Aligned64, Aligned128. AlignedMax corresponds to EIGEN_MAX_ALIGN_BYTES. Such enums are used to define the above Alignment value, and as the 'Options' template parameter of Map<> and Ref<>.
- The Aligned enum is now deprecated. It is now an alias for Aligned16.
- Currently, traits<Matrix<>>, traits<Array<>>, traits<Ref<>>, traits<Map<>>, and traits<Block<>> also expose the Alignment enum.
2015-08-06 15:31:07 +02:00
typedef const Eigen : : Map < const Derived , AlignedMax > ConstAlignedMapType ;
2011-02-03 10:05:45 -05:00
template < typename StrideType > struct StridedMapType { typedef Eigen : : Map < Derived , Unaligned , StrideType > type ; } ;
template < typename StrideType > struct StridedConstMapType { typedef Eigen : : Map < const Derived , Unaligned , StrideType > type ; } ;
First part of a big refactoring of alignment control to enable the handling of arbitrarily aligned buffers. It includes:
- AlignedBit flag is deprecated. Alignment is now specified by the evaluator through the 'Alignment' enum, e.g., evaluator<Xpr>::Alignment. Its value is in Bytes.
- Add several enums to specify alignment: Aligned8, Aligned16, Aligned32, Aligned64, Aligned128. AlignedMax corresponds to EIGEN_MAX_ALIGN_BYTES. Such enums are used to define the above Alignment value, and as the 'Options' template parameter of Map<> and Ref<>.
- The Aligned enum is now deprecated. It is now an alias for Aligned16.
- Currently, traits<Matrix<>>, traits<Array<>>, traits<Ref<>>, traits<Map<>>, and traits<Block<>> also expose the Alignment enum.
2015-08-06 15:31:07 +02:00
template < typename StrideType > struct StridedAlignedMapType { typedef Eigen : : Map < Derived , AlignedMax , StrideType > type ; } ;
template < typename StrideType > struct StridedConstAlignedMapType { typedef Eigen : : Map < const Derived , AlignedMax , StrideType > type ; } ;
2009-12-17 13:37:00 +01:00
protected :
2010-10-20 09:34:13 -04:00
DenseStorage < Scalar , Base : : MaxSizeAtCompileTime , Base : : RowsAtCompileTime , Base : : ColsAtCompileTime , Options > m_storage ;
2009-12-17 13:37:00 +01:00
public :
First part of a big refactoring of alignment control to enable the handling of arbitrarily aligned buffers. It includes:
- AlignedBit flag is deprecated. Alignment is now specified by the evaluator through the 'Alignment' enum, e.g., evaluator<Xpr>::Alignment. Its value is in Bytes.
- Add several enums to specify alignment: Aligned8, Aligned16, Aligned32, Aligned64, Aligned128. AlignedMax corresponds to EIGEN_MAX_ALIGN_BYTES. Such enums are used to define the above Alignment value, and as the 'Options' template parameter of Map<> and Ref<>.
- The Aligned enum is now deprecated. It is now an alias for Aligned16.
- Currently, traits<Matrix<>>, traits<Array<>>, traits<Ref<>>, traits<Map<>>, and traits<Block<>> also expose the Alignment enum.
2015-08-06 15:31:07 +02:00
enum { NeedsToAlign = ( SizeAtCompileTime ! = Dynamic ) & & ( internal : : traits < Derived > : : Alignment > 0 ) } ;
2009-12-17 13:37:00 +01:00
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF ( NeedsToAlign )
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2009-12-17 13:37:00 +01:00
Base & base ( ) { return * static_cast < Base * > ( this ) ; }
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2009-12-17 13:37:00 +01:00
const Base & base ( ) const { return * static_cast < const Base * > ( this ) ; }
2021-03-08 12:39:11 -05:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index rows ( ) const EIGEN_NOEXCEPT { return m_storage . rows ( ) ; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index cols ( ) const EIGEN_NOEXCEPT { return m_storage . cols ( ) ; }
2009-12-17 13:37:00 +01:00
2016-06-01 09:38:49 +02:00
/** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
* provided to by - pass the creation of an evaluator of the expression , thus saving compilation efforts .
*
* See DenseCoeffsBase < Derived , ReadOnlyAccessors > : : coeff ( Index ) const for details . */
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2012-06-22 16:32:45 +02:00
EIGEN_STRONG_INLINE const Scalar & coeff ( Index rowId , Index colId ) const
2009-12-17 13:37:00 +01:00
{
if ( Flags & RowMajorBit )
2012-06-22 16:32:45 +02:00
return m_storage . data ( ) [ colId + rowId * m_storage . cols ( ) ] ;
2009-12-17 13:37:00 +01:00
else // column-major
2012-06-22 16:32:45 +02:00
return m_storage . data ( ) [ rowId + colId * m_storage . rows ( ) ] ;
2009-12-17 13:37:00 +01:00
}
2016-06-01 09:38:49 +02:00
/** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const
* provided to by - pass the creation of an evaluator of the expression , thus saving compilation efforts .
*
* See DenseCoeffsBase < Derived , ReadOnlyAccessors > : : coeff ( Index ) const for details . */
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2010-05-30 16:00:58 -04:00
EIGEN_STRONG_INLINE const Scalar & coeff ( Index index ) const
2009-12-17 13:37:00 +01:00
{
return m_storage . data ( ) [ index ] ;
}
2016-06-01 09:38:49 +02:00
/** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const
* provided to by - pass the creation of an evaluator of the expression , thus saving compilation efforts .
*
* See DenseCoeffsBase < Derived , WriteAccessors > : : coeffRef ( Index , Index ) const for details . */
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2012-06-22 16:32:45 +02:00
EIGEN_STRONG_INLINE Scalar & coeffRef ( Index rowId , Index colId )
2009-12-17 13:37:00 +01:00
{
if ( Flags & RowMajorBit )
2012-06-22 16:32:45 +02:00
return m_storage . data ( ) [ colId + rowId * m_storage . cols ( ) ] ;
2009-12-17 13:37:00 +01:00
else // column-major
2012-06-22 16:32:45 +02:00
return m_storage . data ( ) [ rowId + colId * m_storage . rows ( ) ] ;
2009-12-17 13:37:00 +01:00
}
2016-06-01 09:38:49 +02:00
/** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const
* provided to by - pass the creation of an evaluator of the expression , thus saving compilation efforts .
*
* See DenseCoeffsBase < Derived , WriteAccessors > : : coeffRef ( Index ) const for details . */
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2010-05-30 16:00:58 -04:00
EIGEN_STRONG_INLINE Scalar & coeffRef ( Index index )
2009-12-17 13:37:00 +01:00
{
return m_storage . data ( ) [ index ] ;
}
2016-06-01 09:38:49 +02:00
/** This is the const version of coeffRef(Index,Index) which is thus synonym of coeff(Index,Index).
* It is provided for convenience . */
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2012-06-22 16:32:45 +02:00
EIGEN_STRONG_INLINE const Scalar & coeffRef ( Index rowId , Index colId ) const
2010-12-22 17:45:37 -05:00
{
if ( Flags & RowMajorBit )
2012-06-22 16:32:45 +02:00
return m_storage . data ( ) [ colId + rowId * m_storage . cols ( ) ] ;
2010-12-22 17:45:37 -05:00
else // column-major
2012-06-22 16:32:45 +02:00
return m_storage . data ( ) [ rowId + colId * m_storage . rows ( ) ] ;
2010-12-22 17:45:37 -05:00
}
2016-06-01 09:38:49 +02:00
/** This is the const version of coeffRef(Index) which is thus synonym of coeff(Index).
* It is provided for convenience . */
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2010-12-22 17:45:37 -05:00
EIGEN_STRONG_INLINE const Scalar & coeffRef ( Index index ) const
{
return m_storage . data ( ) [ index ] ;
}
2011-02-01 16:14:53 +01:00
/** \internal */
2009-12-17 13:37:00 +01:00
template < int LoadMode >
2012-06-22 16:32:45 +02:00
EIGEN_STRONG_INLINE PacketScalar packet ( Index rowId , Index colId ) const
2009-12-17 13:37:00 +01:00
{
2010-10-25 10:15:22 -04:00
return internal : : ploadt < PacketScalar , LoadMode >
2009-12-17 13:37:00 +01:00
( m_storage . data ( ) + ( Flags & RowMajorBit
2012-06-22 16:32:45 +02:00
? colId + rowId * m_storage . cols ( )
: rowId + colId * m_storage . rows ( ) ) ) ;
2009-12-17 13:37:00 +01:00
}
2011-02-01 16:14:53 +01:00
/** \internal */
2009-12-17 13:37:00 +01:00
template < int LoadMode >
2010-05-30 16:00:58 -04:00
EIGEN_STRONG_INLINE PacketScalar packet ( Index index ) const
2009-12-17 13:37:00 +01:00
{
2010-10-25 10:15:22 -04:00
return internal : : ploadt < PacketScalar , LoadMode > ( m_storage . data ( ) + index ) ;
2009-12-17 13:37:00 +01:00
}
2011-02-01 16:14:53 +01:00
/** \internal */
2009-12-17 13:37:00 +01:00
template < int StoreMode >
2012-06-22 16:32:45 +02:00
EIGEN_STRONG_INLINE void writePacket ( Index rowId , Index colId , const PacketScalar & val )
2009-12-17 13:37:00 +01:00
{
2010-10-25 10:15:22 -04:00
internal : : pstoret < Scalar , PacketScalar , StoreMode >
2009-12-17 13:37:00 +01:00
( m_storage . data ( ) + ( Flags & RowMajorBit
2012-06-22 16:32:45 +02:00
? colId + rowId * m_storage . cols ( )
: rowId + colId * m_storage . rows ( ) ) , val ) ;
2009-12-17 13:37:00 +01:00
}
2011-02-01 16:14:53 +01:00
/** \internal */
2009-12-17 13:37:00 +01:00
template < int StoreMode >
2012-06-22 16:32:45 +02:00
EIGEN_STRONG_INLINE void writePacket ( Index index , const PacketScalar & val )
2009-12-17 13:37:00 +01:00
{
2012-06-22 16:32:45 +02:00
internal : : pstoret < Scalar , PacketScalar , StoreMode > ( m_storage . data ( ) + index , val ) ;
2009-12-17 13:37:00 +01:00
}
/** \returns a const pointer to the data array of this matrix */
2014-10-13 17:18:26 +02:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data ( ) const
2009-12-17 13:37:00 +01:00
{ return m_storage . data ( ) ; }
/** \returns a pointer to the data array of this matrix */
2014-10-13 17:18:26 +02:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar * data ( )
2009-12-17 13:37:00 +01:00
{ return m_storage . data ( ) ; }
/** Resizes \c *this to a \a rows x \a cols matrix.
*
* This method is intended for dynamic - size matrices , although it is legal to call it on any
* matrix as long as fixed dimensions are left unchanged . If you only want to change the number
2010-05-30 16:00:58 -04:00
* of rows and / or of columns , you can use resize ( NoChange_t , Index ) , resize ( Index , NoChange_t ) .
2009-12-17 13:37:00 +01:00
*
* If the current number of coefficients of \ c * this exactly matches the
* product \ a rows * \ a cols , then no memory allocation is performed and
* the current values are left unchanged . In all other cases , including
* shrinking , the data is reallocated and all previous values are lost .
*
* Example : \ include Matrix_resize_int_int . cpp
* Output : \ verbinclude Matrix_resize_int_int . out
*
2010-05-30 16:00:58 -04:00
* \ sa resize ( Index ) for vectors , resize ( NoChange_t , Index ) , resize ( Index , NoChange_t )
2009-12-17 13:37:00 +01:00
*/
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
EIGEN_STRONG_INLINE void resize ( Index rows , Index cols )
{
eigen_assert ( EIGEN_IMPLIES ( RowsAtCompileTime ! = Dynamic , rows = = RowsAtCompileTime )
& & EIGEN_IMPLIES ( ColsAtCompileTime ! = Dynamic , cols = = ColsAtCompileTime )
& & EIGEN_IMPLIES ( RowsAtCompileTime = = Dynamic & & MaxRowsAtCompileTime ! = Dynamic , rows < = MaxRowsAtCompileTime )
& & EIGEN_IMPLIES ( ColsAtCompileTime = = Dynamic & & MaxColsAtCompileTime ! = Dynamic , cols < = MaxColsAtCompileTime )
& & rows > = 0 & & cols > = 0 & & " Invalid sizes when resizing a matrix or array. " ) ;
internal : : check_rows_cols_for_overflow < MaxSizeAtCompileTime > : : run ( rows , cols ) ;
2013-02-22 15:09:03 +01:00
# ifdef EIGEN_INITIALIZE_COEFFS
2015-06-09 13:32:12 +02:00
Index size = rows * cols ;
2009-12-22 22:51:08 +01:00
bool size_changed = size ! = this - > size ( ) ;
2015-06-09 13:32:12 +02:00
m_storage . resize ( size , rows , cols ) ;
2013-02-07 18:07:07 +01:00
if ( size_changed ) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
2009-12-22 22:51:08 +01:00
# else
2015-06-09 13:32:12 +02:00
m_storage . resize ( rows * cols , rows , cols ) ;
2009-12-22 22:51:08 +01:00
# endif
2009-12-17 13:37:00 +01:00
}
/** Resizes \c *this to a vector of length \a size
*
* \ only_for_vectors . This method does not work for
* partially dynamic matrices when the static dimension is anything other
* than 1. For example it will not work with Matrix < double , 2 , Dynamic > .
*
* Example : \ include Matrix_resize_int . cpp
* Output : \ verbinclude Matrix_resize_int . out
*
2010-05-30 16:00:58 -04:00
* \ sa resize ( Index , Index ) , resize ( NoChange_t , Index ) , resize ( Index , NoChange_t )
2009-12-17 13:37:00 +01:00
*/
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2010-05-30 16:00:58 -04:00
inline void resize ( Index size )
2009-12-17 13:37:00 +01:00
{
2010-10-20 09:34:13 -04:00
EIGEN_STATIC_ASSERT_VECTOR_ONLY ( PlainObjectBase )
2012-06-26 22:16:07 +02:00
eigen_assert ( ( ( SizeAtCompileTime = = Dynamic & & ( MaxSizeAtCompileTime = = Dynamic | | size < = MaxSizeAtCompileTime ) ) | | SizeAtCompileTime = = size ) & & size > = 0 ) ;
2013-02-22 15:09:03 +01:00
# ifdef EIGEN_INITIALIZE_COEFFS
2009-12-22 22:51:08 +01:00
bool size_changed = size ! = this - > size ( ) ;
# endif
2009-12-17 13:37:00 +01:00
if ( RowsAtCompileTime = = 1 )
m_storage . resize ( size , 1 , size ) ;
else
m_storage . resize ( size , size , 1 ) ;
2013-02-22 15:09:03 +01:00
# ifdef EIGEN_INITIALIZE_COEFFS
2013-02-07 18:07:07 +01:00
if ( size_changed ) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
2009-12-22 22:51:08 +01:00
# endif
2009-12-17 13:37:00 +01:00
}
/** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
* as in the example below .
*
* Example : \ include Matrix_resize_NoChange_int . cpp
* Output : \ verbinclude Matrix_resize_NoChange_int . out
*
2010-05-30 16:00:58 -04:00
* \ sa resize ( Index , Index )
2009-12-17 13:37:00 +01:00
*/
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
inline void resize ( NoChange_t , Index cols )
2009-12-17 13:37:00 +01:00
{
2015-06-09 13:32:12 +02:00
resize ( rows ( ) , cols ) ;
2009-12-17 13:37:00 +01:00
}
/** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
* as in the example below .
*
* Example : \ include Matrix_resize_int_NoChange . cpp
* Output : \ verbinclude Matrix_resize_int_NoChange . out
*
2010-05-30 16:00:58 -04:00
* \ sa resize ( Index , Index )
2009-12-17 13:37:00 +01:00
*/
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
inline void resize ( Index rows , NoChange_t )
2009-12-17 13:37:00 +01:00
{
2015-06-09 13:32:12 +02:00
resize ( rows , cols ( ) ) ;
2009-12-17 13:37:00 +01:00
}
/** Resizes \c *this to have the same dimensions as \a other.
* Takes care of doing all the checking that ' s needed .
*
* Note that copying a row - vector into a vector ( and conversely ) is allowed .
* The resizing , if any , is then done in the appropriate way so that row - vectors
* remain row - vectors and vectors remain vectors .
*/
template < typename OtherDerived >
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2010-03-08 10:34:59 -05:00
EIGEN_STRONG_INLINE void resizeLike ( const EigenBase < OtherDerived > & _other )
2009-12-17 13:37:00 +01:00
{
2010-03-08 10:34:59 -05:00
const OtherDerived & other = _other . derived ( ) ;
2012-06-26 22:16:07 +02:00
internal : : check_rows_cols_for_overflow < MaxSizeAtCompileTime > : : run ( other . rows ( ) , other . cols ( ) ) ;
2010-05-30 16:00:58 -04:00
const Index othersize = other . rows ( ) * other . cols ( ) ;
2009-12-17 13:37:00 +01:00
if ( RowsAtCompileTime = = 1 )
{
2010-10-25 10:15:22 -04:00
eigen_assert ( other . rows ( ) = = 1 | | other . cols ( ) = = 1 ) ;
2010-03-08 10:34:59 -05:00
resize ( 1 , othersize ) ;
2009-12-17 13:37:00 +01:00
}
else if ( ColsAtCompileTime = = 1 )
{
2010-10-25 10:15:22 -04:00
eigen_assert ( other . rows ( ) = = 1 | | other . cols ( ) = = 1 ) ;
2010-03-08 10:34:59 -05:00
resize ( othersize , 1 ) ;
2009-12-17 13:37:00 +01:00
}
else resize ( other . rows ( ) , other . cols ( ) ) ;
}
2011-02-24 15:48:41 +01:00
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
2009-12-17 13:37:00 +01:00
*
2011-02-24 15:48:41 +01:00
* The method is intended for matrices of dynamic size . If you only want to change the number
* of rows and / or of columns , you can use conservativeResize ( NoChange_t , Index ) or
2010-05-30 16:00:58 -04:00
* conservativeResize ( Index , NoChange_t ) .
2009-12-17 13:37:00 +01:00
*
2018-09-18 04:15:01 -04:00
* Matrices are resized relative to the top - left element . In case values need to be
2011-02-24 15:48:41 +01:00
* appended to the matrix they will be uninitialized .
2009-12-17 13:37:00 +01:00
*/
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
EIGEN_STRONG_INLINE void conservativeResize ( Index rows , Index cols )
2010-01-15 13:34:28 +01:00
{
2015-06-09 13:32:12 +02:00
internal : : conservative_resize_like_impl < Derived > : : run ( * this , rows , cols ) ;
2009-12-17 13:37:00 +01:00
}
2011-02-24 15:48:41 +01:00
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
*
* As opposed to conservativeResize ( Index rows , Index cols ) , this version leaves
* the number of columns unchanged .
*
* In case the matrix is growing , new rows will be uninitialized .
*/
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
EIGEN_STRONG_INLINE void conservativeResize ( Index rows , NoChange_t )
2009-12-17 13:37:00 +01:00
{
2010-05-30 16:00:58 -04:00
// Note: see the comment in conservativeResize(Index,Index)
2015-06-09 13:32:12 +02:00
conservativeResize ( rows , cols ( ) ) ;
2009-12-17 13:37:00 +01:00
}
2011-02-24 15:48:41 +01:00
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
*
* As opposed to conservativeResize ( Index rows , Index cols ) , this version leaves
* the number of rows unchanged .
*
* In case the matrix is growing , new columns will be uninitialized .
*/
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
EIGEN_STRONG_INLINE void conservativeResize ( NoChange_t , Index cols )
2009-12-17 13:37:00 +01:00
{
2010-05-30 16:00:58 -04:00
// Note: see the comment in conservativeResize(Index,Index)
2015-06-09 13:32:12 +02:00
conservativeResize ( rows ( ) , cols ) ;
2009-12-17 13:37:00 +01:00
}
2011-02-24 15:48:41 +01:00
/** Resizes the vector to \a size while retaining old values.
2009-12-17 13:37:00 +01:00
*
* \ only_for_vectors . This method does not work for
* partially dynamic matrices when the static dimension is anything other
* than 1. For example it will not work with Matrix < double , 2 , Dynamic > .
*
* When values are appended , they will be uninitialized .
*/
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2010-05-30 16:00:58 -04:00
EIGEN_STRONG_INLINE void conservativeResize ( Index size )
2009-12-17 13:37:00 +01:00
{
2010-10-25 10:15:22 -04:00
internal : : conservative_resize_like_impl < Derived > : : run ( * this , size ) ;
2009-12-17 13:37:00 +01:00
}
2011-02-24 15:48:41 +01:00
/** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
*
* The method is intended for matrices of dynamic size . If you only want to change the number
* of rows and / or of columns , you can use conservativeResize ( NoChange_t , Index ) or
* conservativeResize ( Index , NoChange_t ) .
*
2018-09-18 04:15:01 -04:00
* Matrices are resized relative to the top - left element . In case values need to be
2011-02-24 15:48:41 +01:00
* appended to the matrix they will copied from \ c other .
*/
2009-12-17 13:37:00 +01:00
template < typename OtherDerived >
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2009-12-17 13:37:00 +01:00
EIGEN_STRONG_INLINE void conservativeResizeLike ( const DenseBase < OtherDerived > & other )
{
2010-10-25 10:15:22 -04:00
internal : : conservative_resize_like_impl < Derived , OtherDerived > : : run ( * this , other ) ;
2009-12-17 13:37:00 +01:00
}
/** This is a special case of the templated operator=. Its purpose is to
* prevent a default operator = from hiding the templated operator = .
*/
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2010-10-20 09:34:13 -04:00
EIGEN_STRONG_INLINE Derived & operator = ( const PlainObjectBase & other )
2009-12-17 13:37:00 +01:00
{
return _set ( other ) ;
}
/** \sa MatrixBase::lazyAssign() */
template < typename OtherDerived >
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2009-12-17 19:28:54 +01:00
EIGEN_STRONG_INLINE Derived & lazyAssign ( const DenseBase < OtherDerived > & other )
2009-12-17 13:37:00 +01:00
{
_resize_to_match ( other ) ;
return Base : : lazyAssign ( other . derived ( ) ) ;
}
template < typename OtherDerived >
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2009-12-17 13:37:00 +01:00
EIGEN_STRONG_INLINE Derived & operator = ( const ReturnByValue < OtherDerived > & func )
{
resize ( func . rows ( ) , func . cols ( ) ) ;
return Base : : operator = ( func ) ;
}
2015-12-09 15:47:08 +01:00
// Prevent user from trying to instantiate PlainObjectBase objects
// by making all its constructor protected. See bug 1074.
protected :
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2013-06-12 13:05:23 +02:00
EIGEN_STRONG_INLINE PlainObjectBase ( ) : m_storage ( )
2009-12-17 13:37:00 +01:00
{
// _check_template_params();
2013-02-07 18:07:07 +01:00
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
2009-12-17 13:37:00 +01:00
}
# ifndef EIGEN_PARSED_BY_DOXYGEN
// FIXME is it still needed ?
/** \internal */
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2014-09-23 14:28:23 +02:00
explicit PlainObjectBase ( internal : : constructor_without_unaligned_array_assert )
2010-10-25 10:15:22 -04:00
: m_storage ( internal : : constructor_without_unaligned_array_assert ( ) )
2009-12-17 13:37:00 +01:00
{
2013-02-07 18:07:07 +01:00
// _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
2009-12-17 13:37:00 +01:00
}
# endif
2016-05-20 14:54:20 +02:00
# if EIGEN_HAS_RVALUE_REFERENCES
2013-11-05 10:31:59 +01:00
EIGEN_DEVICE_FUNC
2016-06-03 14:28:25 +02:00
PlainObjectBase ( PlainObjectBase & & other ) EIGEN_NOEXCEPT
2013-08-02 19:59:43 +02:00
: m_storage ( std : : move ( other . m_storage ) )
{
}
2013-11-05 10:31:59 +01:00
EIGEN_DEVICE_FUNC
2016-06-03 14:28:25 +02:00
PlainObjectBase & operator = ( PlainObjectBase & & other ) EIGEN_NOEXCEPT
2013-08-02 19:59:43 +02:00
{
2021-03-05 12:54:26 -08:00
_check_template_params ( ) ;
m_storage = std : : move ( other . m_storage ) ;
2013-08-02 19:59:43 +02:00
return * this ;
}
# endif
2015-04-16 13:25:20 +02:00
/** Copy constructor */
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE PlainObjectBase ( const PlainObjectBase & other )
: Base ( ) , m_storage ( other . m_storage ) { }
2013-02-07 19:06:14 +01:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
EIGEN_STRONG_INLINE PlainObjectBase ( Index size , Index rows , Index cols )
: m_storage ( size , rows , cols )
2009-12-17 13:37:00 +01:00
{
// _check_template_params();
2013-02-07 18:07:07 +01:00
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
2009-12-17 13:37:00 +01:00
}
2019-01-24 10:24:45 +01:00
# if EIGEN_HAS_CXX11
2019-01-23 00:07:19 +01:00
/** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients. \cpp11
2019-01-22 17:08:47 +01:00
*
* \ only_for_vectors
2021-03-08 12:39:11 -05:00
*
2019-01-24 10:24:45 +01:00
* This constructor is for 1 D array or vectors with more than 4 coefficients .
2019-07-12 19:46:37 +02:00
* There exists C + + 98 analogue constructors for fixed - size array / vector having 1 , 2 , 3 , or 4 coefficients .
2021-03-08 12:39:11 -05:00
*
* \ warning To construct a column ( resp . row ) vector of fixed length , the number of values passed to this
2019-01-23 00:07:19 +01:00
* constructor must match the the fixed number of rows ( resp . columns ) of \ c * this .
2019-01-22 17:08:47 +01:00
*/
2019-01-23 00:07:19 +01:00
template < typename . . . ArgTypes >
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
PlainObjectBase ( const Scalar & a0 , const Scalar & a1 , const Scalar & a2 , const Scalar & a3 , const ArgTypes & . . . args )
PR 572: Add initializer list constructors to Matrix and Array (include unit tests and doc)
- {1,2,3,4,5,...} for fixed-size vectors only
- {{1,2,3},{4,5,6}} for the general cases
- {{1,2,3,4,5,....}} is allowed for both row and column-vector
2019-01-21 16:25:57 +01:00
: m_storage ( )
{
_check_template_params ( ) ;
2019-01-23 00:07:19 +01:00
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE ( PlainObjectBase , sizeof . . . ( args ) + 4 ) ;
m_storage . data ( ) [ 0 ] = a0 ;
m_storage . data ( ) [ 1 ] = a1 ;
m_storage . data ( ) [ 2 ] = a2 ;
m_storage . data ( ) [ 3 ] = a3 ;
2021-03-29 09:25:39 -07:00
Index i = 4 ;
2019-01-23 00:07:19 +01:00
auto x = { ( m_storage . data ( ) [ i + + ] = args , 0 ) . . . } ;
static_cast < void > ( x ) ;
PR 572: Add initializer list constructors to Matrix and Array (include unit tests and doc)
- {1,2,3,4,5,...} for fixed-size vectors only
- {{1,2,3},{4,5,6}} for the general cases
- {{1,2,3,4,5,....}} is allowed for both row and column-vector
2019-01-21 16:25:57 +01:00
}
2019-01-24 10:24:45 +01:00
/** \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer
* lists \ cpp11
*/
PR 572: Add initializer list constructors to Matrix and Array (include unit tests and doc)
- {1,2,3,4,5,...} for fixed-size vectors only
- {{1,2,3},{4,5,6}} for the general cases
- {{1,2,3,4,5,....}} is allowed for both row and column-vector
2019-01-21 16:25:57 +01:00
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE PlainObjectBase ( const std : : initializer_list < std : : initializer_list < Scalar > > & list )
: m_storage ( )
{
_check_template_params ( ) ;
size_t list_size = 0 ;
if ( list . begin ( ) ! = list . end ( ) ) {
list_size = list . begin ( ) - > size ( ) ;
}
// This is to allow syntax like VectorXi {{1, 2, 3, 4}}
if ( ColsAtCompileTime = = 1 & & list . size ( ) = = 1 ) {
eigen_assert ( list_size = = static_cast < size_t > ( RowsAtCompileTime ) | | RowsAtCompileTime = = Dynamic ) ;
resize ( list_size , ColsAtCompileTime ) ;
std : : copy ( list . begin ( ) - > begin ( ) , list . begin ( ) - > end ( ) , m_storage . data ( ) ) ;
} else {
eigen_assert ( list . size ( ) = = static_cast < size_t > ( RowsAtCompileTime ) | | RowsAtCompileTime = = Dynamic ) ;
eigen_assert ( list_size = = static_cast < size_t > ( ColsAtCompileTime ) | | ColsAtCompileTime = = Dynamic ) ;
resize ( list . size ( ) , list_size ) ;
2021-03-08 12:39:11 -05:00
PR 572: Add initializer list constructors to Matrix and Array (include unit tests and doc)
- {1,2,3,4,5,...} for fixed-size vectors only
- {{1,2,3},{4,5,6}} for the general cases
- {{1,2,3,4,5,....}} is allowed for both row and column-vector
2019-01-21 16:25:57 +01:00
Index row_index = 0 ;
for ( const std : : initializer_list < Scalar > & row : list ) {
eigen_assert ( list_size = = row . size ( ) ) ;
Index col_index = 0 ;
for ( const Scalar & e : row ) {
coeffRef ( row_index , col_index ) = e ;
+ + col_index ;
}
+ + row_index ;
}
}
}
# endif // end EIGEN_HAS_CXX11
2015-04-16 13:25:20 +02:00
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
template < typename OtherDerived >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE PlainObjectBase ( const DenseBase < OtherDerived > & other )
: m_storage ( )
{
_check_template_params ( ) ;
resizeLike ( other ) ;
_set_noalias ( other ) ;
}
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
2009-12-17 13:37:00 +01:00
template < typename OtherDerived >
2015-12-09 15:47:08 +01:00
EIGEN_DEVICE_FUNC
2010-10-20 09:34:13 -04:00
EIGEN_STRONG_INLINE PlainObjectBase ( const EigenBase < OtherDerived > & other )
2015-04-16 13:25:20 +02:00
: m_storage ( )
2009-12-17 13:37:00 +01:00
{
_check_template_params ( ) ;
2015-04-16 13:25:20 +02:00
resizeLike ( other ) ;
* this = other . derived ( ) ;
}
/** \brief Copy constructor with in-place evaluation */
template < typename OtherDerived >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE PlainObjectBase ( const ReturnByValue < OtherDerived > & other )
{
_check_template_params ( ) ;
// FIXME this does not automatically transpose vectors if necessary
resize ( other . rows ( ) , other . cols ( ) ) ;
other . evalTo ( this - > derived ( ) ) ;
2009-12-17 13:37:00 +01:00
}
2015-12-09 15:47:08 +01:00
public :
2017-01-04 23:27:33 +01:00
/** \brief Copies the generic expression \a other into *this.
* \ copydetails DenseBase : : operator = ( const EigenBase < OtherDerived > & other )
2015-12-09 15:47:08 +01:00
*/
template < typename OtherDerived >
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2015-12-09 15:47:08 +01:00
EIGEN_STRONG_INLINE Derived & operator = ( const EigenBase < OtherDerived > & other )
{
_resize_to_match ( other ) ;
Base : : operator = ( other . derived ( ) ) ;
return this - > derived ( ) ;
}
2009-12-17 13:37:00 +01:00
/** \name Map
* These are convenience functions returning Map objects . The Map ( ) static functions return unaligned Map objects ,
* while the AlignedMap ( ) functions return aligned Map objects and thus should be called only with 16 - byte - aligned
* \ a data pointers .
*
2017-08-22 17:18:43 +02:00
* Here is an example using strides :
* \ include Matrix_Map_stride . cpp
* Output : \ verbinclude Matrix_Map_stride . out
*
2009-12-17 13:37:00 +01:00
* \ see class Map
*/
//@{
2012-01-31 12:58:52 +01:00
static inline ConstMapType Map ( const Scalar * data )
2010-12-10 02:09:58 -05:00
{ return ConstMapType ( data ) ; }
2012-01-31 12:58:52 +01:00
static inline MapType Map ( Scalar * data )
2010-12-10 02:09:58 -05:00
{ return MapType ( data ) ; }
2012-01-31 12:58:52 +01:00
static inline ConstMapType Map ( const Scalar * data , Index size )
2010-12-10 02:09:58 -05:00
{ return ConstMapType ( data , size ) ; }
2012-01-31 12:58:52 +01:00
static inline MapType Map ( Scalar * data , Index size )
2010-12-10 02:09:58 -05:00
{ return MapType ( data , size ) ; }
2012-01-31 12:58:52 +01:00
static inline ConstMapType Map ( const Scalar * data , Index rows , Index cols )
2010-12-10 02:09:58 -05:00
{ return ConstMapType ( data , rows , cols ) ; }
2012-01-31 12:58:52 +01:00
static inline MapType Map ( Scalar * data , Index rows , Index cols )
2010-12-10 02:09:58 -05:00
{ return MapType ( data , rows , cols ) ; }
2012-01-31 12:58:52 +01:00
static inline ConstAlignedMapType MapAligned ( const Scalar * data )
2010-12-10 02:09:58 -05:00
{ return ConstAlignedMapType ( data ) ; }
2012-01-31 12:58:52 +01:00
static inline AlignedMapType MapAligned ( Scalar * data )
2009-12-17 14:48:26 +01:00
{ return AlignedMapType ( data ) ; }
2012-01-31 12:58:52 +01:00
static inline ConstAlignedMapType MapAligned ( const Scalar * data , Index size )
2010-12-10 02:09:58 -05:00
{ return ConstAlignedMapType ( data , size ) ; }
2012-01-31 12:58:52 +01:00
static inline AlignedMapType MapAligned ( Scalar * data , Index size )
2009-12-17 14:48:26 +01:00
{ return AlignedMapType ( data , size ) ; }
2012-01-31 12:58:52 +01:00
static inline ConstAlignedMapType MapAligned ( const Scalar * data , Index rows , Index cols )
2010-12-10 02:09:58 -05:00
{ return ConstAlignedMapType ( data , rows , cols ) ; }
2012-01-31 12:58:52 +01:00
static inline AlignedMapType MapAligned ( Scalar * data , Index rows , Index cols )
2009-12-17 14:48:26 +01:00
{ return AlignedMapType ( data , rows , cols ) ; }
2011-02-03 10:05:45 -05:00
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedConstMapType < Stride < Outer , Inner > > : : type Map ( const Scalar * data , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedConstMapType < Stride < Outer , Inner > > : : type ( data , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedMapType < Stride < Outer , Inner > > : : type Map ( Scalar * data , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedMapType < Stride < Outer , Inner > > : : type ( data , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedConstMapType < Stride < Outer , Inner > > : : type Map ( const Scalar * data , Index size , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedConstMapType < Stride < Outer , Inner > > : : type ( data , size , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedMapType < Stride < Outer , Inner > > : : type Map ( Scalar * data , Index size , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedMapType < Stride < Outer , Inner > > : : type ( data , size , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedConstMapType < Stride < Outer , Inner > > : : type Map ( const Scalar * data , Index rows , Index cols , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedConstMapType < Stride < Outer , Inner > > : : type ( data , rows , cols , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedMapType < Stride < Outer , Inner > > : : type Map ( Scalar * data , Index rows , Index cols , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedMapType < Stride < Outer , Inner > > : : type ( data , rows , cols , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedConstAlignedMapType < Stride < Outer , Inner > > : : type MapAligned ( const Scalar * data , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedConstAlignedMapType < Stride < Outer , Inner > > : : type ( data , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedAlignedMapType < Stride < Outer , Inner > > : : type MapAligned ( Scalar * data , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedAlignedMapType < Stride < Outer , Inner > > : : type ( data , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedConstAlignedMapType < Stride < Outer , Inner > > : : type MapAligned ( const Scalar * data , Index size , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedConstAlignedMapType < Stride < Outer , Inner > > : : type ( data , size , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedAlignedMapType < Stride < Outer , Inner > > : : type MapAligned ( Scalar * data , Index size , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedAlignedMapType < Stride < Outer , Inner > > : : type ( data , size , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedConstAlignedMapType < Stride < Outer , Inner > > : : type MapAligned ( const Scalar * data , Index rows , Index cols , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedConstAlignedMapType < Stride < Outer , Inner > > : : type ( data , rows , cols , stride ) ; }
template < int Outer , int Inner >
2012-01-31 12:58:52 +01:00
static inline typename StridedAlignedMapType < Stride < Outer , Inner > > : : type MapAligned ( Scalar * data , Index rows , Index cols , const Stride < Outer , Inner > & stride )
2011-02-03 10:05:45 -05:00
{ return typename StridedAlignedMapType < Stride < Outer , Inner > > : : type ( data , rows , cols , stride ) ; }
2009-12-17 13:37:00 +01:00
//@}
using Base : : setConstant ;
2015-12-30 16:04:24 +01:00
EIGEN_DEVICE_FUNC Derived & setConstant ( Index size , const Scalar & val ) ;
EIGEN_DEVICE_FUNC Derived & setConstant ( Index rows , Index cols , const Scalar & val ) ;
2021-01-28 15:13:07 +01:00
EIGEN_DEVICE_FUNC Derived & setConstant ( NoChange_t , Index cols , const Scalar & val ) ;
EIGEN_DEVICE_FUNC Derived & setConstant ( Index rows , NoChange_t , const Scalar & val ) ;
2009-12-17 13:37:00 +01:00
using Base : : setZero ;
2013-06-05 15:38:33 +02:00
EIGEN_DEVICE_FUNC Derived & setZero ( Index size ) ;
EIGEN_DEVICE_FUNC Derived & setZero ( Index rows , Index cols ) ;
2021-01-28 01:10:36 +01:00
EIGEN_DEVICE_FUNC Derived & setZero ( NoChange_t , Index cols ) ;
EIGEN_DEVICE_FUNC Derived & setZero ( Index rows , NoChange_t ) ;
2009-12-17 13:37:00 +01:00
using Base : : setOnes ;
2013-06-05 15:38:33 +02:00
EIGEN_DEVICE_FUNC Derived & setOnes ( Index size ) ;
EIGEN_DEVICE_FUNC Derived & setOnes ( Index rows , Index cols ) ;
2021-01-28 01:10:36 +01:00
EIGEN_DEVICE_FUNC Derived & setOnes ( NoChange_t , Index cols ) ;
EIGEN_DEVICE_FUNC Derived & setOnes ( Index rows , NoChange_t ) ;
2009-12-17 13:37:00 +01:00
using Base : : setRandom ;
2010-05-30 16:00:58 -04:00
Derived & setRandom ( Index size ) ;
Derived & setRandom ( Index rows , Index cols ) ;
2021-01-28 01:10:36 +01:00
Derived & setRandom ( NoChange_t , Index cols ) ;
Derived & setRandom ( Index rows , NoChange_t ) ;
2009-12-17 13:37:00 +01:00
2010-12-29 19:12:39 +00:00
# ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
# include EIGEN_PLAINOBJECTBASE_PLUGIN
2009-12-17 13:37:00 +01:00
# endif
protected :
/** \internal Resizes *this in preparation for assigning \a other to it.
* Takes care of doing all the checking that ' s needed .
*
* Note that copying a row - vector into a vector ( and conversely ) is allowed .
* The resizing , if any , is then done in the appropriate way so that row - vectors
* remain row - vectors and vectors remain vectors .
*/
template < typename OtherDerived >
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2010-03-08 10:34:59 -05:00
EIGEN_STRONG_INLINE void _resize_to_match ( const EigenBase < OtherDerived > & other )
2009-12-17 13:37:00 +01:00
{
# ifdef EIGEN_NO_AUTOMATIC_RESIZING
2010-10-25 10:15:22 -04:00
eigen_assert ( ( this - > size ( ) = = 0 | | ( IsVectorAtCompileTime ? ( this - > size ( ) = = other . size ( ) )
2009-12-17 13:37:00 +01:00
: ( rows ( ) = = other . rows ( ) & & cols ( ) = = other . cols ( ) ) ) )
& & " Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined " ) ;
2012-12-20 11:21:47 +01:00
EIGEN_ONLY_USED_FOR_DEBUG ( other ) ;
2010-07-06 10:11:18 +02:00
# else
2009-12-17 13:37:00 +01:00
resizeLike ( other ) ;
2010-07-06 10:11:18 +02:00
# endif
2009-12-17 13:37:00 +01:00
}
2010-01-15 13:34:28 +01:00
/**
2010-01-13 17:51:09 +01:00
* \ brief Copies the value of the expression \ a other into \ c * this with automatic resizing .
2009-12-17 13:37:00 +01:00
*
* * this might be resized to match the dimensions of \ a other . If * this was a null matrix ( not already initialized ) ,
* it will be initialized .
*
* Note that copying a row - vector into a vector ( and conversely ) is allowed .
* The resizing , if any , is then done in the appropriate way so that row - vectors
* remain row - vectors and vectors remain vectors .
*
* \ sa operator = ( const MatrixBase < OtherDerived > & ) , _set_noalias ( )
2010-01-13 17:51:09 +01:00
*
* \ internal
2009-12-17 13:37:00 +01:00
*/
2018-09-18 04:15:01 -04:00
// aliasing is dealt once in internal::call_assignment
2014-02-17 16:11:55 +01:00
// so at this stage we have to assume aliasing... and resising has to be done later.
template < typename OtherDerived >
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2014-02-17 16:11:55 +01:00
EIGEN_STRONG_INLINE Derived & _set ( const DenseBase < OtherDerived > & other )
{
internal : : call_assignment ( this - > derived ( ) , other . derived ( ) ) ;
return this - > derived ( ) ;
}
2009-12-17 13:37:00 +01:00
/** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
* is the case when creating a new matrix ) so one can enforce lazy evaluation .
*
* \ sa operator = ( const MatrixBase < OtherDerived > & ) , _set ( )
*/
template < typename OtherDerived >
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2009-12-17 13:37:00 +01:00
EIGEN_STRONG_INLINE Derived & _set_noalias ( const DenseBase < OtherDerived > & other )
{
2010-06-02 19:17:41 +02:00
// I don't think we need this resize call since the lazyAssign will anyways resize
// and lazyAssign will be called by the assign selector.
//_resize_to_match(other);
2009-12-17 13:37:00 +01:00
// the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
// it wouldn't allow to copy a row-vector into a column-vector.
Relax mixing-type constraints for binary coefficient-wise operators:
- Replace internal::scalar_product_traits<A,B> by Eigen::ScalarBinaryOpTraits<A,B,OP>
- Remove the "functor_is_product_like" helper (was pretty ugly)
- Currently, OP is not used, but it is available to the user for fine grained tuning
- Currently, only the following operators have been generalized: *,/,+,-,=,*=,/=,+=,-=
- TODO: generalize all other binray operators (comparisons,pow,etc.)
- TODO: handle "scalar op array" operators (currently only * is handled)
- TODO: move the handling of the "void" scalar type to ScalarBinaryOpTraits
2016-06-06 15:11:41 +02:00
internal : : call_assignment_no_alias ( this - > derived ( ) , other . derived ( ) , internal : : assign_op < Scalar , typename OtherDerived : : Scalar > ( ) ) ;
2014-02-17 16:11:55 +01:00
return this - > derived ( ) ;
2009-12-17 13:37:00 +01:00
}
template < typename T0 , typename T1 >
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2015-06-09 13:32:12 +02:00
EIGEN_STRONG_INLINE void _init2 ( Index rows , Index cols , typename internal : : enable_if < Base : : SizeAtCompileTime ! = 2 , T0 > : : type * = 0 )
2009-12-17 13:37:00 +01:00
{
2019-03-17 21:59:30 +01:00
const bool t0_is_integer_alike = internal : : is_valid_index_type < T0 > : : value ;
const bool t1_is_integer_alike = internal : : is_valid_index_type < T1 > : : value ;
EIGEN_STATIC_ASSERT ( t0_is_integer_alike & &
t1_is_integer_alike ,
2011-11-05 23:56:48 -04:00
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED )
2015-06-09 13:32:12 +02:00
resize ( rows , cols ) ;
2009-12-17 13:37:00 +01:00
}
2018-09-18 04:15:01 -04:00
2009-12-17 13:37:00 +01:00
template < typename T0 , typename T1 >
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2016-05-22 18:17:04 +02:00
EIGEN_STRONG_INLINE void _init2 ( const T0 & val0 , const T1 & val1 , typename internal : : enable_if < Base : : SizeAtCompileTime = = 2 , T0 > : : type * = 0 )
2009-12-17 13:37:00 +01:00
{
2010-10-20 09:34:13 -04:00
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE ( PlainObjectBase , 2 )
2016-05-22 18:17:04 +02:00
m_storage . data ( ) [ 0 ] = Scalar ( val0 ) ;
m_storage . data ( ) [ 1 ] = Scalar ( val1 ) ;
2009-12-17 13:37:00 +01:00
}
2018-09-18 04:15:01 -04:00
2014-07-22 16:57:14 +02:00
template < typename T0 , typename T1 >
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2014-07-22 18:28:19 +02:00
EIGEN_STRONG_INLINE void _init2 ( const Index & val0 , const Index & val1 ,
typename internal : : enable_if < ( ! internal : : is_same < Index , Scalar > : : value )
& & ( internal : : is_same < T0 , Index > : : value )
& & ( internal : : is_same < T1 , Index > : : value )
& & Base : : SizeAtCompileTime = = 2 , T1 > : : type * = 0 )
2014-07-22 16:57:14 +02:00
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE ( PlainObjectBase , 2 )
m_storage . data ( ) [ 0 ] = Scalar ( val0 ) ;
m_storage . data ( ) [ 1 ] = Scalar ( val1 ) ;
}
2009-12-17 13:37:00 +01:00
2014-09-19 13:25:28 +02:00
// The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
// then the argument is meant to be the size of the object.
2014-06-23 11:15:42 +02:00
template < typename T >
EIGEN_DEVICE_FUNC
2014-09-19 13:25:28 +02:00
EIGEN_STRONG_INLINE void _init1 ( Index size , typename internal : : enable_if < ( Base : : SizeAtCompileTime ! = 1 | | ! internal : : is_convertible < T , Scalar > : : value )
& & ( ( ! internal : : is_same < typename internal : : traits < Derived > : : XprKind , ArrayXpr > : : value | | Base : : SizeAtCompileTime = = Dynamic ) ) , T > : : type * = 0 )
2014-06-23 11:15:42 +02:00
{
2014-08-02 02:47:30 +02:00
// NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
2019-03-17 21:59:30 +01:00
const bool is_integer_alike = internal : : is_valid_index_type < T > : : value ;
EIGEN_UNUSED_VARIABLE ( is_integer_alike ) ;
EIGEN_STATIC_ASSERT ( is_integer_alike ,
2014-06-23 11:15:42 +02:00
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED )
resize ( size ) ;
}
2018-09-18 04:15:01 -04:00
2018-03-11 10:01:44 -04:00
// We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitly converted)
2014-06-23 11:15:42 +02:00
template < typename T >
EIGEN_DEVICE_FUNC
2014-07-04 12:52:55 +02:00
EIGEN_STRONG_INLINE void _init1 ( const Scalar & val0 , typename internal : : enable_if < Base : : SizeAtCompileTime = = 1 & & internal : : is_convertible < T , Scalar > : : value , T > : : type * = 0 )
2014-06-23 11:15:42 +02:00
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE ( PlainObjectBase , 1 )
m_storage . data ( ) [ 0 ] = val0 ;
}
2018-09-18 04:15:01 -04:00
2014-09-19 13:25:28 +02:00
// We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type match the index type)
2014-07-20 14:03:22 +02:00
template < typename T >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const Index & val0 ,
2014-07-22 18:28:19 +02:00
typename internal : : enable_if < ( ! internal : : is_same < Index , Scalar > : : value )
& & ( internal : : is_same < Index , T > : : value )
& & Base : : SizeAtCompileTime = = 1
2014-07-22 17:01:34 +02:00
& & internal : : is_convertible < T , Scalar > : : value , T * > : : type * = 0 )
2014-07-20 14:03:22 +02:00
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE ( PlainObjectBase , 1 )
m_storage . data ( ) [ 0 ] = Scalar ( val0 ) ;
}
2014-06-23 11:15:42 +02:00
2014-09-19 13:25:28 +02:00
// Initialize a fixed size matrix from a pointer to raw data
2014-06-23 11:15:42 +02:00
template < typename T >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const Scalar * data ) {
this - > _set_noalias ( ConstMapType ( data ) ) ;
}
2014-09-19 13:25:28 +02:00
// Initialize an arbitrary matrix from a dense expression
2014-06-23 11:15:42 +02:00
template < typename T , typename OtherDerived >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const DenseBase < OtherDerived > & other ) {
this - > _set_noalias ( other ) ;
}
2017-02-17 14:10:57 +01:00
// Initialize an arbitrary matrix from an object convertible to the Derived type.
template < typename T >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const Derived & other ) {
this - > _set_noalias ( other ) ;
}
2014-09-19 13:25:28 +02:00
// Initialize an arbitrary matrix from a generic Eigen expression
2014-06-23 11:15:42 +02:00
template < typename T , typename OtherDerived >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const EigenBase < OtherDerived > & other ) {
this - > derived ( ) = other ;
}
template < typename T , typename OtherDerived >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const ReturnByValue < OtherDerived > & other )
{
resize ( other . rows ( ) , other . cols ( ) ) ;
other . evalTo ( this - > derived ( ) ) ;
}
template < typename T , typename OtherDerived , int ColsAtCompileTime >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const RotationBase < OtherDerived , ColsAtCompileTime > & r )
{
this - > derived ( ) = r ;
}
2018-09-18 04:15:01 -04:00
2017-02-17 14:10:57 +01:00
// For fixed-size Array<Scalar,...>
2014-09-19 13:25:28 +02:00
template < typename T >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const Scalar & val0 ,
typename internal : : enable_if < Base : : SizeAtCompileTime ! = Dynamic
& & Base : : SizeAtCompileTime ! = 1
& & internal : : is_convertible < T , Scalar > : : value
& & internal : : is_same < typename internal : : traits < Derived > : : XprKind , ArrayXpr > : : value , T > : : type * = 0 )
{
Base : : setConstant ( val0 ) ;
}
2018-09-18 04:15:01 -04:00
2017-02-17 14:10:57 +01:00
// For fixed-size Array<Index,...>
2014-09-19 13:25:28 +02:00
template < typename T >
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _init1 ( const Index & val0 ,
typename internal : : enable_if < ( ! internal : : is_same < Index , Scalar > : : value )
& & ( internal : : is_same < Index , T > : : value )
& & Base : : SizeAtCompileTime ! = Dynamic
& & Base : : SizeAtCompileTime ! = 1
& & internal : : is_convertible < T , Scalar > : : value
& & internal : : is_same < typename internal : : traits < Derived > : : XprKind , ArrayXpr > : : value , T * > : : type * = 0 )
{
Base : : setConstant ( val0 ) ;
}
2018-09-18 04:15:01 -04:00
2009-12-17 13:37:00 +01:00
template < typename MatrixTypeA , typename MatrixTypeB , bool SwapPointers >
2010-10-25 10:15:22 -04:00
friend struct internal : : matrix_swap_impl ;
2009-12-17 13:37:00 +01:00
2014-11-06 09:25:26 +01:00
public :
2018-09-18 04:15:01 -04:00
2014-11-06 09:25:26 +01:00
# ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal
* \ brief Override DenseBase : : swap ( ) since for dynamic - sized matrices
* of same type it is enough to swap the data pointers .
2009-12-17 13:37:00 +01:00
*/
template < typename OtherDerived >
2019-02-15 16:35:35 +01:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
2014-11-06 09:25:26 +01:00
void swap ( DenseBase < OtherDerived > & other )
2009-12-17 13:37:00 +01:00
{
2010-10-25 22:13:49 +02:00
enum { SwapPointers = internal : : is_same < Derived , OtherDerived > : : value & & Base : : SizeAtCompileTime = = Dynamic } ;
2014-11-06 09:25:26 +01:00
internal : : matrix_swap_impl < Derived , OtherDerived , bool ( SwapPointers ) > : : run ( this - > derived ( ) , other . derived ( ) ) ;
2009-12-17 13:37:00 +01:00
}
2018-09-18 04:15:01 -04:00
2014-11-06 09:25:26 +01:00
/** \internal
* \ brief const version forwarded to DenseBase : : swap
*/
template < typename OtherDerived >
2019-02-15 16:35:35 +01:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
2014-11-06 09:25:26 +01:00
void swap ( DenseBase < OtherDerived > const & other )
{ Base : : swap ( other . derived ( ) ) ; }
2018-09-18 04:15:01 -04:00
EIGEN_DEVICE_FUNC
2012-01-31 12:58:52 +01:00
static EIGEN_STRONG_INLINE void _check_template_params ( )
2010-03-09 00:16:07 -05:00
{
2021-02-24 14:12:27 -08:00
EIGEN_STATIC_ASSERT ( ( EIGEN_IMPLIES ( MaxRowsAtCompileTime = = 1 & & MaxColsAtCompileTime ! = 1 , ( int ( Options ) & RowMajor ) = = RowMajor )
& & EIGEN_IMPLIES ( MaxColsAtCompileTime = = 1 & & MaxRowsAtCompileTime ! = 1 , ( int ( Options ) & RowMajor ) = = 0 )
2010-06-11 07:56:50 -04:00
& & ( ( RowsAtCompileTime = = Dynamic ) | | ( RowsAtCompileTime > = 0 ) )
& & ( ( ColsAtCompileTime = = Dynamic ) | | ( ColsAtCompileTime > = 0 ) )
& & ( ( MaxRowsAtCompileTime = = Dynamic ) | | ( MaxRowsAtCompileTime > = 0 ) )
& & ( ( MaxColsAtCompileTime = = Dynamic ) | | ( MaxColsAtCompileTime > = 0 ) )
2010-03-09 00:16:07 -05:00
& & ( MaxRowsAtCompileTime = = RowsAtCompileTime | | RowsAtCompileTime = = Dynamic )
& & ( MaxColsAtCompileTime = = ColsAtCompileTime | | ColsAtCompileTime = = Dynamic )
2010-04-16 10:13:32 -04:00
& & ( Options & ( DontAlign | RowMajor ) ) = = Options ) ,
2010-03-09 00:16:07 -05:00
INVALID_MATRIX_TEMPLATE_PARAMETERS )
}
2010-12-22 17:45:37 -05:00
2014-11-06 09:25:26 +01:00
enum { IsPlainObjectBase = 1 } ;
2021-03-11 11:23:00 -08:00
# endif
public :
// These apparently need to be down here for nvcc+icc to prevent duplicate
// Map symbol.
template < typename PlainObjectType , int MapOptions , typename StrideType > friend class Eigen : : Map ;
friend class Eigen : : Map < Derived , Unaligned > ;
friend class Eigen : : Map < const Derived , Unaligned > ;
# if EIGEN_MAX_ALIGN_BYTES>0
// for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
friend class Eigen : : Map < Derived , AlignedMax > ;
friend class Eigen : : Map < const Derived , AlignedMax > ;
2014-11-06 09:25:26 +01:00
# endif
2009-12-17 13:37:00 +01:00
} ;
2013-10-16 12:07:33 +02:00
namespace internal {
2010-01-10 23:11:05 +01:00
template < typename Derived , typename OtherDerived , bool IsVector >
2013-10-16 12:07:33 +02:00
struct conservative_resize_like_impl
2009-12-17 13:37:00 +01:00
{
2018-07-18 23:33:07 +02:00
# if EIGEN_HAS_TYPE_TRAITS
static const bool IsRelocatable = std : : is_trivially_copyable < typename Derived : : Scalar > : : value ;
# else
2018-07-19 18:47:38 +02:00
static const bool IsRelocatable = ! NumTraits < typename Derived : : Scalar > : : RequireInitialization ;
2018-07-18 23:33:07 +02:00
# endif
2010-05-30 16:00:58 -04:00
static void run ( DenseBase < Derived > & _this , Index rows , Index cols )
2009-12-17 13:37:00 +01:00
{
2010-01-10 20:02:26 +01:00
if ( _this . rows ( ) = = rows & & _this . cols ( ) = = cols ) return ;
2009-12-17 13:37:00 +01:00
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE ( Derived )
2010-02-27 17:25:07 +01:00
2018-07-18 23:33:07 +02:00
if ( IsRelocatable
& & ( ( Derived : : IsRowMajor & & _this . cols ( ) = = cols ) | | // row-major and we change only the number of rows
( ! Derived : : IsRowMajor & & _this . rows ( ) = = rows ) ) ) // column-major and we change only the number of columns
2010-02-27 17:25:07 +01:00
{
2012-06-26 22:16:07 +02:00
internal : : check_rows_cols_for_overflow < Derived : : MaxSizeAtCompileTime > : : run ( rows , cols ) ;
2010-02-27 17:25:07 +01:00
_this . derived ( ) . m_storage . conservativeResize ( rows * cols , rows , cols ) ;
}
else
{
// The storage order does not allow us to use reallocation.
2021-05-10 11:43:49 +01:00
Derived tmp ( rows , cols ) ;
2016-10-13 15:00:22 +01:00
const Index common_rows = numext : : mini ( rows , _this . rows ( ) ) ;
const Index common_cols = numext : : mini ( cols , _this . cols ( ) ) ;
2010-02-27 17:25:07 +01:00
tmp . block ( 0 , 0 , common_rows , common_cols ) = _this . block ( 0 , 0 , common_rows , common_cols ) ;
_this . derived ( ) . swap ( tmp ) ;
}
2009-12-17 13:37:00 +01:00
}
2010-01-10 23:11:05 +01:00
static void run ( DenseBase < Derived > & _this , const DenseBase < OtherDerived > & other )
{
if ( _this . rows ( ) = = other . rows ( ) & & _this . cols ( ) = = other . cols ( ) ) return ;
2010-05-30 16:00:58 -04:00
// Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
2010-01-10 23:11:05 +01:00
// neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
2010-05-30 16:00:58 -04:00
// dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
// conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
2010-01-10 23:11:05 +01:00
// EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE ( Derived )
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE ( OtherDerived )
2018-07-18 23:33:07 +02:00
if ( IsRelocatable & &
( ( Derived : : IsRowMajor & & _this . cols ( ) = = other . cols ( ) ) | | // row-major and we change only the number of rows
( ! Derived : : IsRowMajor & & _this . rows ( ) = = other . rows ( ) ) ) ) // column-major and we change only the number of columns
2010-02-27 17:25:07 +01:00
{
2010-05-30 16:00:58 -04:00
const Index new_rows = other . rows ( ) - _this . rows ( ) ;
const Index new_cols = other . cols ( ) - _this . cols ( ) ;
2010-02-27 17:25:07 +01:00
_this . derived ( ) . m_storage . conservativeResize ( other . size ( ) , other . rows ( ) , other . cols ( ) ) ;
if ( new_rows > 0 )
2010-04-22 14:11:18 -04:00
_this . bottomRightCorner ( new_rows , other . cols ( ) ) = other . bottomRows ( new_rows ) ;
2010-02-27 17:25:07 +01:00
else if ( new_cols > 0 )
2010-04-22 14:11:18 -04:00
_this . bottomRightCorner ( other . rows ( ) , new_cols ) = other . rightCols ( new_cols ) ;
2010-02-27 17:25:07 +01:00
}
else
{
// The storage order does not allow us to use reallocation.
2021-05-10 11:43:49 +01:00
Derived tmp ( other ) ;
2016-10-13 15:00:22 +01:00
const Index common_rows = numext : : mini ( tmp . rows ( ) , _this . rows ( ) ) ;
const Index common_cols = numext : : mini ( tmp . cols ( ) , _this . cols ( ) ) ;
2010-02-27 17:25:07 +01:00
tmp . block ( 0 , 0 , common_rows , common_cols ) = _this . block ( 0 , 0 , common_rows , common_cols ) ;
_this . derived ( ) . swap ( tmp ) ;
}
2010-01-10 23:11:05 +01:00
}
2009-12-17 13:37:00 +01:00
} ;
2013-10-16 12:07:33 +02:00
// Here, the specialization for vectors inherits from the general matrix case
// to allow calling .conservativeResize(rows,cols) on vectors.
2010-01-10 23:11:05 +01:00
template < typename Derived , typename OtherDerived >
2010-10-25 10:15:22 -04:00
struct conservative_resize_like_impl < Derived , OtherDerived , true >
2013-10-16 12:07:33 +02:00
: conservative_resize_like_impl < Derived , OtherDerived , false >
2009-12-17 13:37:00 +01:00
{
2018-07-18 23:33:07 +02:00
typedef conservative_resize_like_impl < Derived , OtherDerived , false > Base ;
using Base : : run ;
using Base : : IsRelocatable ;
2018-09-18 04:15:01 -04:00
2010-05-30 16:00:58 -04:00
static void run ( DenseBase < Derived > & _this , Index size )
2009-12-17 13:37:00 +01:00
{
2010-05-30 16:00:58 -04:00
const Index new_rows = Derived : : RowsAtCompileTime = = 1 ? 1 : size ;
const Index new_cols = Derived : : RowsAtCompileTime = = 1 ? size : 1 ;
2018-07-18 23:33:07 +02:00
if ( IsRelocatable )
_this . derived ( ) . m_storage . conservativeResize ( size , new_rows , new_cols ) ;
else
Base : : run ( _this . derived ( ) , new_rows , new_cols ) ;
2009-12-17 13:37:00 +01:00
}
2010-01-10 23:11:05 +01:00
static void run ( DenseBase < Derived > & _this , const DenseBase < OtherDerived > & other )
{
if ( _this . rows ( ) = = other . rows ( ) & & _this . cols ( ) = = other . cols ( ) ) return ;
2010-05-30 16:00:58 -04:00
const Index num_new_elements = other . size ( ) - _this . size ( ) ;
2010-02-27 17:25:07 +01:00
2010-05-30 16:00:58 -04:00
const Index new_rows = Derived : : RowsAtCompileTime = = 1 ? 1 : other . rows ( ) ;
const Index new_cols = Derived : : RowsAtCompileTime = = 1 ? other . cols ( ) : 1 ;
2018-07-18 23:33:07 +02:00
if ( IsRelocatable )
_this . derived ( ) . m_storage . conservativeResize ( other . size ( ) , new_rows , new_cols ) ;
else
Base : : run ( _this . derived ( ) , new_rows , new_cols ) ;
2010-03-03 18:47:58 +01:00
2010-02-27 17:25:07 +01:00
if ( num_new_elements > 0 )
_this . tail ( num_new_elements ) = other . tail ( num_new_elements ) ;
2010-01-10 23:11:05 +01:00
}
2009-12-17 13:37:00 +01:00
} ;
template < typename MatrixTypeA , typename MatrixTypeB , bool SwapPointers >
2010-10-25 10:15:22 -04:00
struct matrix_swap_impl
2009-12-17 13:37:00 +01:00
{
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2019-02-15 16:35:35 +01:00
static EIGEN_STRONG_INLINE void run ( MatrixTypeA & a , MatrixTypeB & b )
2009-12-17 13:37:00 +01:00
{
a . base ( ) . swap ( b ) ;
}
} ;
template < typename MatrixTypeA , typename MatrixTypeB >
2010-10-25 10:15:22 -04:00
struct matrix_swap_impl < MatrixTypeA , MatrixTypeB , true >
2009-12-17 13:37:00 +01:00
{
2013-08-01 16:26:57 +02:00
EIGEN_DEVICE_FUNC
2009-12-17 13:37:00 +01:00
static inline void run ( MatrixTypeA & a , MatrixTypeB & b )
{
2010-01-11 10:04:39 +00:00
static_cast < typename MatrixTypeA : : Base & > ( a ) . m_storage . swap ( static_cast < typename MatrixTypeB : : Base & > ( b ) . m_storage ) ;
2009-12-17 13:37:00 +01:00
}
} ;
2010-10-25 10:15:22 -04:00
} // end namespace internal
2012-04-15 11:06:28 +01:00
} // end namespace Eigen
2009-12-17 13:37:00 +01:00
# endif // EIGEN_DENSESTORAGEBASE_H