LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
util::TensorIndices< RANK > Class Template Reference

Converts a tensor element specification into a linear index. More...

#include "TensorIndices.h"

Public Types

using Index_t = Base_t::Index_t
 Type of a single index in the tensor. More...
 
using DimSize_t = Base_t::DimSize_t
 Type for the specification of a dimension size. More...
 
using LinIndex_t = Base_t::LinIndex_t
 Type of the linear index. More...
 
using MinorTensor_t = TensorIndices< rank()-1 >
 Type of the tensor indices with rank smaller by one. More...
 

Public Member Functions

template<typename... OTHERDIMS>
 TensorIndices (DimSize_t first, OTHERDIMS...others)
 Constructor: initialises the dimension of the tensor. More...
 
template<typename ITER , typename = std::enable_if_t<std::is_convertible<decltype(*(ITER())), DimSize_t>::value, void>>
 TensorIndices (ITER dimIter)
 Constructor: initialises the dimension of the tensor. More...
 
template<typename... OTHERINDICES>
LinIndex_t operator() (Index_t first, OTHERINDICES...others) const
 Returns the linear index corresponding to the tensor indices. More...
 
template<typename ITER >
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_toperator() (ITER indexIter) const
 Returns the linear index corresponding to the tensor indices. More...
 
template<typename... OTHERINDICES>
LinIndex_t at (Index_t first, OTHERINDICES...others) const
 Returns the linear index corresponding to the tensor indices. More...
 
template<typename ITER >
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_tat (ITER indexIter) const
 Returns the linear index corresponding to the tensor indices. More...
 
template<typename... OTHERINDICES>
bool has (Index_t first, OTHERINDICES...others) const
 Returns whether the specified set of indices is valid. More...
 
template<typename ITER >
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, bool > has (ITER indexIter) const
 Returns whether the specified set of indices is valid. More...
 
template<unsigned int DIM>
DimSize_t dim () const
 Returns the size of the specified dimension. More...
 
template<unsigned int DIM>
bool hasIndex (Index_t index) const
 Returns whether a index is valid within a specified dimension. More...
 
template<unsigned int DIM = 0>
DimSize_t size () const
 Returns the size of the minor tensor. More...
 
bool hasLinIndex (LinIndex_t linIndex) const
 Returns whether the specified linear index is valid in this tensor. More...
 
MinorTensor_t const & minorTensor () const
 
bool operator== (TensorIndices< RANK > const &t) const
 Returns whether all sizes of the tensor t are the same as this one. More...
 
bool operator!= (TensorIndices< RANK > const &t) const
 Returns whether any size of the tensor t is different from this one. More...
 

Static Public Member Functions

static constexpr unsigned int rank ()
 Rank of this tensor. More...
 

Protected Member Functions

DimSize_t totalSize () const
 Returns the total size of this tensor (the same as size()) More...
 

Protected Attributes

MinorTensor_t m
 the rest of the tensor indices More...
 
DimSize_t totSize
 size of this tensor More...
 

Private Types

using Base_t = TensorIndices< 1U >
 type of base class More...
 

Friends

template<unsigned int R, unsigned int D>
struct details::ExtractTensorDimension
 

Detailed Description

template<unsigned int RANK>
class util::TensorIndices< RANK >

Converts a tensor element specification into a linear index.

Example to use a 6 x 3 x 2 x 4 tensor of rank 4:

TensorIndices<4> indices(6, 3, 2, 4);
std::vector<double> v(indices.size(), 0.);
std::cout << v[indices(4, 1, 1, 0)] << std::endl;

This will map the content of the vector v as a tensor of rank 4.

Definition at line 43 of file TensorIndices.h.

Member Typedef Documentation

template<unsigned int RANK>
using util::TensorIndices< RANK >::Base_t = TensorIndices<1U>
private

type of base class

Definition at line 169 of file TensorIndices.h.

template<unsigned int RANK>
using util::TensorIndices< RANK >::DimSize_t = Base_t::DimSize_t

Type for the specification of a dimension size.

Definition at line 176 of file TensorIndices.h.

template<unsigned int RANK>
using util::TensorIndices< RANK >::Index_t = Base_t::Index_t

Type of a single index in the tensor.

Definition at line 173 of file TensorIndices.h.

template<unsigned int RANK>
using util::TensorIndices< RANK >::LinIndex_t = Base_t::LinIndex_t

Type of the linear index.

Definition at line 179 of file TensorIndices.h.

template<unsigned int RANK>
using util::TensorIndices< RANK >::MinorTensor_t = TensorIndices<rank() - 1>

Type of the tensor indices with rank smaller by one.

Definition at line 185 of file TensorIndices.h.

Constructor & Destructor Documentation

template<unsigned int RANK>
template<typename... OTHERDIMS>
util::TensorIndices< RANK >::TensorIndices ( DimSize_t  first,
OTHERDIMS...  others 
)
inline

Constructor: initialises the dimension of the tensor.

Template Parameters
OTHERINDICEStypes of the other index values
Parameters
firstthe size of the first dimension
otherssize of each of the other dimensions

Example to initialise indices for a 6 x 3 x 2 x 4 tensor of rank 4:

TensorIndices<4> indices(6, 3, 2, 4);

Definition at line 200 of file TensorIndices.h.

201  : Base_t(first), m(others...), totSize(dim0() * m.size())
202  {}
TensorIndices< 1U > Base_t
type of base class
DimSize_t totSize
size of this tensor
MinorTensor_t m
the rest of the tensor indices
DimSize_t size() const
Returns the size of the minor tensor.
template<unsigned int RANK>
template<typename ITER , typename = std::enable_if_t<std::is_convertible<decltype(*(ITER())), DimSize_t>::value, void>>
util::TensorIndices< RANK >::TensorIndices ( ITER  dimIter)
inline

Constructor: initialises the dimension of the tensor.

Template Parameters
ITERtype of iterator to dimension sizes
Parameters
dimIteriterator pointing to the first dimension size

Dimensions are initialised from the values pointed by the specified iterator. The iterator is required to be a forward iterator pointing to a type convertible to a DimSize_t type. The iterator must be valid when increased up to rank() - 1 times, so that all the rank() dimensions can be extracted.

Example to initialise indices for a 6 x 3 x 2 x 4 tensor of rank 4:

std::array<size_t, 4> dims { 6, 3, 2, 4 };
TensorIndices<4> indices(dims.begin());

Note that no end iterator is required.

Definition at line 227 of file TensorIndices.h.

227  : Base_t(dimIter), m(++dimIter), totSize(dim0() * m.size())
228  {}
TensorIndices< 1U > Base_t
type of base class
DimSize_t totSize
size of this tensor
MinorTensor_t m
the rest of the tensor indices
DimSize_t size() const
Returns the size of the minor tensor.

Member Function Documentation

template<unsigned int RANK>
template<typename... OTHERINDICES>
LinIndex_t util::TensorIndices< RANK >::at ( Index_t  first,
OTHERINDICES...  others 
) const
inline

Returns the linear index corresponding to the tensor indices.

Template Parameters
OTHERINDICEStypes of the other index values
Parameters
firstthe index of the first dimension
othersthe indices of the other dimensions
Exceptions
std::out_of_rangeif any of the indices is not valid
Returns
the offset of the specified element with respect to the first one
See also
operator()(), has()

If any of the index values is not in the valid index range, an exception is thrown.

Use it as:

TensorIndices<4> indices(6, 3, 2, 4);
auto validIndex = indices.at(4, 2, 0, 1);
auto invalidIndex = indices.at(4, 3, 2, 1); // throws std::out_of_range

(in the example, note that the last line has two indices out of range and an exception will be thrown).

Definition at line 306 of file TensorIndices.h.

307  {
308  return Base_t::checkOuterIndex(first) * minorTensor().size() + minorTensor().at(others...);
309  }
Index_t checkOuterIndex(Index_t index) const
DimSize_t size() const
Returns the size of the minor tensor.
MinorTensor_t const & minorTensor() const
LinIndex_t at(Index_t first, OTHERINDICES...others) const
Returns the linear index corresponding to the tensor indices.
template<unsigned int RANK>
template<typename ITER >
std::enable_if_t<std::is_convertible<decltype(*(ITER())), DimSize_t>::value, LinIndex_t> util::TensorIndices< RANK >::at ( ITER  indexIter) const
inline

Returns the linear index corresponding to the tensor indices.

Template Parameters
ITERtype of iterator to dimension sizes
Parameters
indexIteriterator pointing to the first dimension size
Exceptions
std::out_of_rangeif any of the indices is not valid
Returns
the offset of the specified element with respect to the first one
See also
operator()(), has()

If any of the index values is not in the valid index range, an exception is thrown.

Use it as:

TensorIndices<4> indices(6, 3, 2, 4);
std::array<int, 4> ix { 4, 2, 0, 1 };
auto validIndex = indices.at(ix.begin());

The behaviour is the same as in at()(Index_t first, OTHERINDICES... others).

Definition at line 333 of file TensorIndices.h.

335  {
336  auto const baseSize = Base_t::checkOuterIndex(*indexIter) * minorTensor().size();
337  return baseSize + minorTensor()(++indexIter);
338  }
Index_t checkOuterIndex(Index_t index) const
DimSize_t size() const
Returns the size of the minor tensor.
MinorTensor_t const & minorTensor() const
template<unsigned int RANK>
template<unsigned int DIM>
DimSize_t util::TensorIndices< RANK >::dim ( ) const
inline

Returns the size of the specified dimension.

Template Parameters
DIMthe dimension (0 is the first one)
Returns
the size of the specified dimension

Code won't compile for DIM larger than the tensor rank.

Definition at line 407 of file TensorIndices.h.

408  {
410  }
static TensorIndicesBasicTypes::DimSize_t dim(TensorIndices< RANK > const &t)
template<unsigned int RANK>
template<typename... OTHERINDICES>
bool util::TensorIndices< RANK >::has ( Index_t  first,
OTHERINDICES...  others 
) const
inline

Returns whether the specified set of indices is valid.

Template Parameters
OTHERINDICEStypes of the other index values
Parameters
firstthe index of the first dimension
othersthe indices of the other dimensions
Returns
whether the specified set of indices is valid
See also
operator(), at()

If any of the index values is not in the valid index range, an exception is thrown.

Use it as:

TensorIndices<4> indices(6, 3, 2, 4);
if (indices.has(4, 2, 0, 1)) {
// ...
}
if (indices.has(4, 3, 2, 1)) {
// ... (won't be executed)
}

(in the example, note that the last line has two indices out of range and an exception will be thrown).

Definition at line 365 of file TensorIndices.h.

366  {
367  return Base_t::has(first) && minorTensor().has(others...);
368  }
bool has(Index_t index) const
Definition: TensorIndices.h:94
bool has(Index_t first, OTHERINDICES...others) const
Returns whether the specified set of indices is valid.
MinorTensor_t const & minorTensor() const
template<unsigned int RANK>
template<typename ITER >
std::enable_if_t<std::is_convertible<decltype(*(ITER())), DimSize_t>::value, bool> util::TensorIndices< RANK >::has ( ITER  indexIter) const
inline

Returns whether the specified set of indices is valid.

Template Parameters
ITERtype of iterator to dimension sizes
Parameters
indexIteriterator pointing to the first dimension size
Returns
whether the specified set of indices is valid
See also
operator(), at()

If any of the index values is not in the valid index range, an exception is thrown.

Use it as:

TensorIndices<4> indices(6, 3, 2, 4);
std::array<int, 4> ix { 4, 2, 0, 1 };
if (indices.has(ix.begin())) {
// ...
}

The behaviour is the same as in has()(Index_t first, OTHERINDICES... others).

Definition at line 393 of file TensorIndices.h.

395  {
396  return Base_t::has(*indexIter) ? minorTensor().has(++indexIter) : false;
397  }
bool has(Index_t index) const
Definition: TensorIndices.h:94
bool has(Index_t first, OTHERINDICES...others) const
Returns whether the specified set of indices is valid.
MinorTensor_t const & minorTensor() const
template<unsigned int RANK>
template<unsigned int DIM>
bool util::TensorIndices< RANK >::hasIndex ( Index_t  index) const
inline

Returns whether a index is valid within a specified dimension.

Template Parameters
DIMthe dimension (0 is the first one)
Parameters
indexthe value of the index to be tested
Returns
whether a index is valid within a specified dimension

Use it as:

TensorIndices<4> indices(6, 3, 2, 4);
if (indices.hasIndex<0>(2)) { // dimension #0 has 6 indices, [ 0 ; 5 ]
// ... (will be executed)
}
if (indices.hasIndex<0>(6)) {
// ... (will not be executed)
}
if (indices.hasIndex<2>(0)) { // dimension #2 has 2 indices, { 0 , 1 }
// ... (will be executed)
}
if (indices.hasIndex<3>(6)) {// dimension #3 has 4 indices, [ 0 ; 3 ]
// ... (will not be executed)
}

Definition at line 437 of file TensorIndices.h.

438  {
439  return (index >= 0U) && ((DimSize_t)index < dim<DIM>());
440  }
Base_t::DimSize_t DimSize_t
Type for the specification of a dimension size.
template<unsigned int RANK>
bool util::TensorIndices< RANK >::hasLinIndex ( LinIndex_t  linIndex) const
inline

Returns whether the specified linear index is valid in this tensor.

Definition at line 462 of file TensorIndices.h.

Referenced by util::details::GridContainerIndicesBase< DIMS >::has().

463  {
464  return (linIndex >= 0U) && ((DimSize_t)linIndex < size());
465  }
DimSize_t size() const
Returns the size of the minor tensor.
Base_t::DimSize_t DimSize_t
Type for the specification of a dimension size.
template<unsigned int RANK>
MinorTensor_t const& util::TensorIndices< RANK >::minorTensor ( ) const
inline

Returns the tensor of rank Rank-1 from stripping the first dimension Note that the minorTensor variable was previously named "minor". However, minor is also defined in sys/types.h to mean something completely different.

Definition at line 470 of file TensorIndices.h.

Referenced by util::details::ExtractTensorDimension< RANK, DIM >::dim(), util::TensorIndices< DIMS >::operator!=(), util::TensorIndices< DIMS >::operator==(), and util::details::ExtractTensorDimension< RANK, DIM >::size().

470 { return m; }
MinorTensor_t m
the rest of the tensor indices
template<unsigned int RANK>
bool util::TensorIndices< RANK >::operator!= ( TensorIndices< RANK > const &  t) const
inline

Returns whether any size of the tensor t is different from this one.

Definition at line 479 of file TensorIndices.h.

480  {
481  return Base_t::operator!=(t) || (minorTensor() != t.minorTensor());
482  }
bool operator!=(TensorIndices< 1U > const &t) const
MinorTensor_t const & minorTensor() const
template<unsigned int RANK>
template<typename... OTHERINDICES>
LinIndex_t util::TensorIndices< RANK >::operator() ( Index_t  first,
OTHERINDICES...  others 
) const
inline

Returns the linear index corresponding to the tensor indices.

Template Parameters
OTHERINDICEStypes of the other index values
Parameters
firstthe index of the first dimension
othersthe indices of the other dimensions
Returns
the offset of the specified element with respect to the first one
See also
at(), has()

No check is performed on the validity of the indices (that is, whether they fall within the dimension range).

Use it as:

TensorIndices<4> indices(6, 3, 2, 4);
auto validIndex = indices(4, 2, 0, 1);
auto invalidIndex = indices(4, 3, 2, 1); // invalid index is returned!

(in the example, note that the last line has two indices out of range and the return value will not be valid!).

Definition at line 251 of file TensorIndices.h.

252  {
253  return first * minorTensor().size() + minorTensor()(others...);
254  }
DimSize_t size() const
Returns the size of the minor tensor.
MinorTensor_t const & minorTensor() const
template<unsigned int RANK>
template<typename ITER >
std::enable_if_t<std::is_convertible<decltype(*(ITER())), DimSize_t>::value, LinIndex_t> util::TensorIndices< RANK >::operator() ( ITER  indexIter) const
inline

Returns the linear index corresponding to the tensor indices.

Template Parameters
ITERtype of iterator to dimension sizes
Parameters
indexIteriterator pointing to the first dimension size
Returns
the offset of the specified element with respect to the first one
See also
at(), has()

No check is performed on the validity of the indices (that is, whether they fall within the dimension range).

Use it as:

TensorIndices<4> indices(6, 3, 2, 4);
std::array<int, 4> ix { 4, 2, 0, 1 };
auto validIndex = indices(ix.begin());

The behaviour is the same as in operator()(Index_t first, OTHERINDICES... others).

Definition at line 277 of file TensorIndices.h.

278  {
279  auto const baseSize = (*indexIter) * minorTensor().size();
280  return baseSize + minorTensor()(++indexIter);
281  }
DimSize_t size() const
Returns the size of the minor tensor.
MinorTensor_t const & minorTensor() const
template<unsigned int RANK>
bool util::TensorIndices< RANK >::operator== ( TensorIndices< RANK > const &  t) const
inline

Returns whether all sizes of the tensor t are the same as this one.

Definition at line 473 of file TensorIndices.h.

474  {
475  return Base_t::operator==(t) && (minorTensor() == t.minorTensor());
476  }
bool operator==(TensorIndices< 1U > const &t) const
MinorTensor_t const & minorTensor() const
template<unsigned int RANK>
static constexpr unsigned int util::TensorIndices< RANK >::rank ( )
inlinestatic

Rank of this tensor.

Definition at line 182 of file TensorIndices.h.

182 { return RANK; }
template<unsigned int RANK>
template<unsigned int DIM = 0>
DimSize_t util::TensorIndices< RANK >::size ( ) const
inline

Returns the size of the minor tensor.

Template Parameters
DIMthe index of the outer dimension of the minor tensor
Returns
the size of the specified tensor

The total size of the tensor obtained after stripping the DIM most outer dimensions if returned. Therefore, size<0>() is the size of the full tensor, while size<1>() is the size of the tensor obtained by stripping the first dimension (that is, the tensor returned by minor()), and so on.

Code won't compile for DIM larger than the tensor rank.

Definition at line 456 of file TensorIndices.h.

Referenced by util::details::GridContainerIndicesBase< DIMS >::size(), and util::details::ExtractTensorDimension< RANK, 0U >::size().

457  {
458  return (DIM == 0) ? totalSize() : details::ExtractTensorDimension<rank(), DIM>::size(*this);
459  }
DimSize_t totalSize() const
Returns the total size of this tensor (the same as size())
static constexpr unsigned int rank()
Rank of this tensor.
DimSize_t size() const
Returns the size of the minor tensor.
template<unsigned int RANK>
DimSize_t util::TensorIndices< RANK >::totalSize ( ) const
inlineprotected

Returns the total size of this tensor (the same as size())

Definition at line 493 of file TensorIndices.h.

493 { return totSize; }
DimSize_t totSize
size of this tensor

Friends And Related Function Documentation

template<unsigned int RANK>
template<unsigned int R, unsigned int D>
friend struct details::ExtractTensorDimension
friend

Definition at line 487 of file TensorIndices.h.

Member Data Documentation

template<unsigned int RANK>
MinorTensor_t util::TensorIndices< RANK >::m
protected

the rest of the tensor indices

Definition at line 489 of file TensorIndices.h.

template<unsigned int RANK>
DimSize_t util::TensorIndices< RANK >::totSize
protected

size of this tensor

Definition at line 490 of file TensorIndices.h.


The documentation for this class was generated from the following file: