2014-04-28 10:32:27 -07:00
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// 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/.
# ifndef EIGEN_CXX11_TENSOR_TENSOR_MAP_H
# define EIGEN_CXX11_TENSOR_TENSOR_MAP_H
namespace Eigen {
/** \class TensorMap
* \ ingroup CXX11_Tensor_Module
*
* \ brief A tensor expression mapping an existing array of data .
*
*/
2014-05-16 15:08:05 -07:00
template < typename PlainObjectType , int Options_ > class TensorMap : public TensorBase < TensorMap < PlainObjectType , Options_ > >
2014-04-28 10:32:27 -07:00
{
public :
2014-05-16 15:08:05 -07:00
typedef TensorMap < PlainObjectType , Options_ > Self ;
2014-04-28 10:32:27 -07:00
typedef typename PlainObjectType : : Base Base ;
typedef typename Eigen : : internal : : nested < Self > : : type Nested ;
typedef typename internal : : traits < PlainObjectType > : : StorageKind StorageKind ;
typedef typename internal : : traits < PlainObjectType > : : Index Index ;
typedef typename internal : : traits < PlainObjectType > : : Scalar Scalar ;
typedef typename NumTraits < Scalar > : : Real RealScalar ;
typedef typename Base : : CoeffReturnType CoeffReturnType ;
/* typedef typename internal::conditional<
bool ( internal : : is_lvalue < PlainObjectType > : : value ) ,
Scalar * ,
const Scalar * > : : type
PointerType ; */
typedef Scalar * PointerType ;
typedef PointerType PointerArgType ;
2014-05-16 15:08:05 -07:00
static const int Options = Options_ ;
2014-10-13 17:02:09 -07:00
static const Index NumIndices = PlainObjectType : : NumIndices ;
2014-05-22 16:22:35 -07:00
typedef typename PlainObjectType : : Dimensions Dimensions ;
2014-05-16 15:08:05 -07:00
enum {
2014-10-13 17:02:09 -07:00
IsAligned = ( ( int ( Options_ ) & Aligned ) = = Aligned ) ,
2015-01-14 12:45:20 -08:00
Layout = PlainObjectType : : Layout ,
2016-01-19 17:05:10 -08:00
CoordAccess = true ,
RawAccess = true
2014-05-16 15:08:05 -07:00
} ;
2014-05-06 11:18:37 -07:00
2015-10-29 17:49:04 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr ) : m_data ( dataPtr ) , m_dimensions ( ) {
// The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
EIGEN_STATIC_ASSERT ( ( 0 = = NumIndices | | NumIndices = = Dynamic ) , YOU_MADE_A_PROGRAMMING_MISTAKE )
}
2016-05-20 15:05:38 +02:00
# if EIGEN_HAS_VARIADIC_TEMPLATES
2014-04-28 10:32:27 -07:00
template < typename . . . IndexTypes > EIGEN_DEVICE_FUNC
2014-10-13 17:02:09 -07:00
EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , Index firstDimension , IndexTypes . . . otherDimensions ) : m_data ( dataPtr ) , m_dimensions ( firstDimension , otherDimensions . . . ) {
2014-04-28 10:32:27 -07:00
// The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
2014-10-13 17:02:09 -07:00
EIGEN_STATIC_ASSERT ( ( sizeof . . . ( otherDimensions ) + 1 = = NumIndices | | NumIndices = = Dynamic ) , YOU_MADE_A_PROGRAMMING_MISTAKE )
2014-04-28 10:32:27 -07:00
}
2014-06-09 09:42:34 -07:00
# else
EIGEN_DEVICE_FUNC
2014-10-13 17:02:09 -07:00
EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , Index firstDimension ) : m_data ( dataPtr ) , m_dimensions ( firstDimension ) {
2014-06-09 09:42:34 -07:00
// The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
2014-10-13 17:02:09 -07:00
EIGEN_STATIC_ASSERT ( ( 1 = = NumIndices | | NumIndices = = Dynamic ) , YOU_MADE_A_PROGRAMMING_MISTAKE )
2014-06-09 09:42:34 -07:00
}
2015-01-14 12:45:20 -08:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , Index dim1 , Index dim2 ) : m_data ( dataPtr ) , m_dimensions ( dim1 , dim2 ) {
EIGEN_STATIC_ASSERT ( 2 = = NumIndices | | NumIndices = = Dynamic , YOU_MADE_A_PROGRAMMING_MISTAKE )
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , Index dim1 , Index dim2 , Index dim3 ) : m_data ( dataPtr ) , m_dimensions ( dim1 , dim2 , dim3 ) {
EIGEN_STATIC_ASSERT ( 3 = = NumIndices | | NumIndices = = Dynamic , YOU_MADE_A_PROGRAMMING_MISTAKE )
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , Index dim1 , Index dim2 , Index dim3 , Index dim4 ) : m_data ( dataPtr ) , m_dimensions ( dim1 , dim2 , dim3 , dim4 ) {
EIGEN_STATIC_ASSERT ( 4 = = NumIndices | | NumIndices = = Dynamic , YOU_MADE_A_PROGRAMMING_MISTAKE )
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , Index dim1 , Index dim2 , Index dim3 , Index dim4 , Index dim5 ) : m_data ( dataPtr ) , m_dimensions ( dim1 , dim2 , dim3 , dim4 , dim5 ) {
EIGEN_STATIC_ASSERT ( 5 = = NumIndices | | NumIndices = = Dynamic , YOU_MADE_A_PROGRAMMING_MISTAKE )
}
2014-04-28 10:32:27 -07:00
# endif
2015-10-22 11:48:02 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , const array < Index , NumIndices > & dimensions )
2015-01-14 12:45:20 -08:00
: m_data ( dataPtr ) , m_dimensions ( dimensions )
{ }
2014-10-16 14:52:50 -07:00
template < typename Dimensions >
2015-10-22 11:48:02 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap ( PointerArgType dataPtr , const Dimensions & dimensions )
2014-05-06 11:18:37 -07:00
: m_data ( dataPtr ) , m_dimensions ( dimensions )
{ }
2015-10-22 11:48:02 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap ( PlainObjectType & tensor )
: m_data ( tensor . data ( ) ) , m_dimensions ( tensor . dimensions ( ) )
{ }
2015-01-14 12:45:20 -08:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index rank ( ) const { return m_dimensions . rank ( ) ; }
2014-04-28 10:32:27 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index dimension ( Index n ) const { return m_dimensions [ n ] ; }
EIGEN_DEVICE_FUNC
2014-05-22 16:22:35 -07:00
EIGEN_STRONG_INLINE const Dimensions & dimensions ( ) const { return m_dimensions ; }
2014-05-06 11:18:37 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index size ( ) const { return m_dimensions . TotalSize ( ) ; }
2014-04-28 10:32:27 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Scalar * data ( ) { return m_data ; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar * data ( ) const { return m_data ; }
2014-05-16 15:08:05 -07:00
EIGEN_DEVICE_FUNC
2014-05-22 16:22:35 -07:00
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( const array < Index , NumIndices > & indices ) const
2014-05-16 15:08:05 -07:00
{
// eigen_assert(checkIndexRange(indices));
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = m_dimensions . IndexOfRowMajor ( indices ) ;
return m_data [ index ] ;
} else {
const Index index = m_dimensions . IndexOfColMajor ( indices ) ;
return m_data [ index ] ;
}
}
2015-10-29 17:49:04 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( ) const
{
EIGEN_STATIC_ASSERT ( NumIndices = = 0 , YOU_MADE_A_PROGRAMMING_MISTAKE )
return m_data [ 0 ] ;
}
2016-02-10 08:02:04 -08:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( Index index ) const
{
eigen_internal_assert ( index > = 0 & & index < size ( ) ) ;
return m_data [ index ] ;
}
2016-05-20 15:05:38 +02:00
# if EIGEN_HAS_VARIADIC_TEMPLATES
2014-05-16 15:08:05 -07:00
template < typename . . . IndexTypes > EIGEN_DEVICE_FUNC
2016-02-10 08:02:04 -08:00
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( Index firstIndex , Index secondIndex , IndexTypes . . . otherIndices ) const
2014-05-16 15:08:05 -07:00
{
2016-02-10 08:02:04 -08:00
EIGEN_STATIC_ASSERT ( sizeof . . . ( otherIndices ) + 2 = = NumIndices , YOU_MADE_A_PROGRAMMING_MISTAKE )
2014-05-16 15:08:05 -07:00
if ( PlainObjectType : : Options & RowMajor ) {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfRowMajor ( array < Index , NumIndices > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
} else {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfColMajor ( array < Index , NumIndices > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
}
}
# else
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( Index i0 , Index i1 ) const
{
if ( PlainObjectType : : Options & RowMajor ) {
2015-12-10 22:45:10 -08:00
const Index index = i1 + i0 * m_dimensions [ 1 ] ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
} else {
const Index index = i0 + i1 * m_dimensions [ 0 ] ;
return m_data [ index ] ;
}
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( Index i0 , Index i1 , Index i2 ) const
{
if ( PlainObjectType : : Options & RowMajor ) {
2015-12-10 22:45:10 -08:00
const Index index = i2 + m_dimensions [ 2 ] * ( i1 + m_dimensions [ 1 ] * i0 ) ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
} else {
const Index index = i0 + m_dimensions [ 0 ] * ( i1 + m_dimensions [ 1 ] * i2 ) ;
return m_data [ index ] ;
}
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( Index i0 , Index i1 , Index i2 , Index i3 ) const
{
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = i3 + m_dimensions [ 3 ] * ( i2 + m_dimensions [ 2 ] * ( i1 + m_dimensions [ 1 ] * i0 ) ) ;
return m_data [ index ] ;
} else {
const Index index = i0 + m_dimensions [ 0 ] * ( i1 + m_dimensions [ 1 ] * ( i2 + m_dimensions [ 2 ] * i3 ) ) ;
return m_data [ index ] ;
}
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar & operator ( ) ( Index i0 , Index i1 , Index i2 , Index i3 , Index i4 ) const
{
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = i4 + m_dimensions [ 4 ] * ( i3 + m_dimensions [ 3 ] * ( i2 + m_dimensions [ 2 ] * ( i1 + m_dimensions [ 1 ] * i0 ) ) ) ;
return m_data [ index ] ;
} else {
const Index index = i0 + m_dimensions [ 0 ] * ( i1 + m_dimensions [ 1 ] * ( i2 + m_dimensions [ 2 ] * ( i3 + m_dimensions [ 3 ] * i4 ) ) ) ;
return m_data [ index ] ;
}
}
# endif
EIGEN_DEVICE_FUNC
2014-05-22 16:22:35 -07:00
EIGEN_STRONG_INLINE Scalar & operator ( ) ( const array < Index , NumIndices > & indices )
2014-05-16 15:08:05 -07:00
{
// eigen_assert(checkIndexRange(indices));
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = m_dimensions . IndexOfRowMajor ( indices ) ;
return m_data [ index ] ;
} else {
const Index index = m_dimensions . IndexOfColMajor ( indices ) ;
return m_data [ index ] ;
}
}
2014-04-28 10:32:27 -07:00
2015-10-29 17:49:04 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Scalar & operator ( ) ( )
{
EIGEN_STATIC_ASSERT ( NumIndices = = 0 , YOU_MADE_A_PROGRAMMING_MISTAKE )
return m_data [ 0 ] ;
}
2016-02-10 08:02:04 -08:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Scalar & operator ( ) ( Index index )
{
eigen_internal_assert ( index > = 0 & & index < size ( ) ) ;
return m_data [ index ] ;
}
2016-05-20 15:05:38 +02:00
# if EIGEN_HAS_VARIADIC_TEMPLATES
2014-04-28 10:32:27 -07:00
template < typename . . . IndexTypes > EIGEN_DEVICE_FUNC
2016-02-10 08:02:04 -08:00
EIGEN_STRONG_INLINE Scalar & operator ( ) ( Index firstIndex , Index secondIndex , IndexTypes . . . otherIndices )
2014-04-28 10:32:27 -07:00
{
2016-02-10 08:02:04 -08:00
static_assert ( sizeof . . . ( otherIndices ) + 2 = = NumIndices | | NumIndices = = Dynamic , " Number of indices used to access a tensor coefficient must be equal to the rank of the tensor. " ) ;
const std : : size_t NumDims = sizeof . . . ( otherIndices ) + 2 ;
2014-05-06 11:18:37 -07:00
if ( PlainObjectType : : Options & RowMajor ) {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfRowMajor ( array < Index , NumDims > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-06 11:18:37 -07:00
return m_data [ index ] ;
} else {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfColMajor ( array < Index , NumDims > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-06 11:18:37 -07:00
return m_data [ index ] ;
}
2014-04-28 10:32:27 -07:00
}
2014-05-16 15:08:05 -07:00
# else
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Scalar & operator ( ) ( Index i0 , Index i1 )
{
if ( PlainObjectType : : Options & RowMajor ) {
2015-12-10 22:45:10 -08:00
const Index index = i1 + i0 * m_dimensions [ 1 ] ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
} else {
const Index index = i0 + i1 * m_dimensions [ 0 ] ;
return m_data [ index ] ;
}
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Scalar & operator ( ) ( Index i0 , Index i1 , Index i2 )
{
if ( PlainObjectType : : Options & RowMajor ) {
2015-12-10 22:45:10 -08:00
const Index index = i2 + m_dimensions [ 2 ] * ( i1 + m_dimensions [ 1 ] * i0 ) ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
} else {
const Index index = i0 + m_dimensions [ 0 ] * ( i1 + m_dimensions [ 1 ] * i2 ) ;
return m_data [ index ] ;
}
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Scalar & operator ( ) ( Index i0 , Index i1 , Index i2 , Index i3 )
{
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = i3 + m_dimensions [ 3 ] * ( i2 + m_dimensions [ 2 ] * ( i1 + m_dimensions [ 1 ] * i0 ) ) ;
return m_data [ index ] ;
} else {
const Index index = i0 + m_dimensions [ 0 ] * ( i1 + m_dimensions [ 1 ] * ( i2 + m_dimensions [ 2 ] * i3 ) ) ;
return m_data [ index ] ;
}
}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Scalar & operator ( ) ( Index i0 , Index i1 , Index i2 , Index i3 , Index i4 )
{
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = i4 + m_dimensions [ 4 ] * ( i3 + m_dimensions [ 3 ] * ( i2 + m_dimensions [ 2 ] * ( i1 + m_dimensions [ 1 ] * i0 ) ) ) ;
return m_data [ index ] ;
} else {
const Index index = i0 + m_dimensions [ 0 ] * ( i1 + m_dimensions [ 1 ] * ( i2 + m_dimensions [ 2 ] * ( i3 + m_dimensions [ 3 ] * i4 ) ) ) ;
return m_data [ index ] ;
}
}
2014-04-28 10:32:27 -07:00
# endif
2014-07-22 10:31:21 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Self & operator = ( const Self & other )
{
typedef TensorAssignOp < Self , const Self > Assign ;
Assign assign ( * this , other ) ;
internal : : TensorExecutor < const Assign , DefaultDevice > : : run ( assign , DefaultDevice ( ) ) ;
return * this ;
}
2014-05-16 15:08:05 -07:00
2014-04-28 10:32:27 -07:00
template < typename OtherDerived >
2014-07-22 10:31:21 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
2014-04-28 10:32:27 -07:00
Self & operator = ( const OtherDerived & other )
{
2014-06-13 09:56:51 -07:00
typedef TensorAssignOp < Self , const OtherDerived > Assign ;
Assign assign ( * this , other ) ;
internal : : TensorExecutor < const Assign , DefaultDevice > : : run ( assign , DefaultDevice ( ) ) ;
2014-04-28 10:32:27 -07:00
return * this ;
}
private :
2014-05-22 16:22:35 -07:00
Scalar * m_data ;
Dimensions m_dimensions ;
2014-04-28 10:32:27 -07:00
} ;
} // end namespace Eigen
# endif // EIGEN_CXX11_TENSOR_TENSOR_MAP_H