15 #ifndef LARDATA_UTILITIES_TENSORINDICES_H 16 #define LARDATA_UTILITIES_TENSORINDICES_H 23 #include <type_traits> 46 template <
unsigned int RANK>
51 template <
unsigned int RANK,
unsigned int DIM>
73 static constexpr
unsigned int rank() {
return 1U; }
80 typename = std::enable_if_t
88 template <
typename ITER>
90 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
91 operator() (ITER indexIter)
const {
return *indexIter; }
95 template <
typename ITER>
97 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
98 at(ITER indexIter)
const 99 {
return checkOuterIndex(*indexIter); }
102 {
return (index >= 0) && ((
DimSize_t) index < size()); }
104 template <
typename ITER>
106 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
bool>
108 {
return (*indexIter >= 0) && ((
DimSize_t) *indexIter < size()); }
111 template <
unsigned int DIM = 0>
114 template <
unsigned int DIM>
117 static_assert(DIM == 0,
"Invalid dimension requested");
121 template <
unsigned int DIM>
124 static_assert(DIM == 0,
"Invalid dimension requested");
129 {
return has((
Index_t) linIndex); }
132 {
return t.
size() == size(); }
134 {
return t.
size() != size(); }
139 if (has(index))
return index;
140 throw std::out_of_range(
"Requested index " +
std::to_string(index)
149 template <
unsigned int R,
unsigned int D>
174 template <
unsigned int RANK>
176 static_assert(RANK > 1,
"TensorIndices must have rank 1 or higher");
193 static constexpr
unsigned int rank() {
return RANK; }
211 template <
typename... OTHERDIMS>
213 :
Base_t(first), m(others...), totSize(dim0() * m.size()) {}
238 typename = std::enable_if_t
242 :
Base_t(dimIter), m(++dimIter), totSize(dim0() * m.size()) {}
265 template <
typename... OTHERINDICES>
267 {
return first * minor().
size() + minor()(others...); }
289 template <
typename ITER>
291 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
292 operator() (ITER indexIter)
const 294 auto const baseSize = (*indexIter) * minor().size();
295 return baseSize + minor()(++indexIter);
321 template <
typename... OTHERINDICES>
324 return Base_t::checkOuterIndex(first) * minor().size()
325 + minor().at(others...);
349 template <
typename ITER>
351 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
352 at(ITER indexIter)
const 355 = Base_t::checkOuterIndex(*indexIter) * minor().size();
356 return baseSize + minor()(++indexIter);
384 template <
typename... OTHERINDICES>
386 {
return Base_t::has(first) && minor().has(others...); }
410 template <
typename ITER>
412 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
bool>
414 {
return Base_t::has(*indexIter)? minor().has(++indexIter):
false; }
424 template <
unsigned int DIM>
453 template <
unsigned int DIM>
455 {
return (index >= 0U) && ((
DimSize_t) index < dim<DIM>()); }
471 template <
unsigned int DIM = 0>
474 return (DIM == 0)? totalSize():
480 {
return (linIndex >= 0U) && ((
DimSize_t) linIndex < size()); }
498 template <
unsigned int R,
unsigned int D>
513 unsigned int RANK1,
unsigned int RANK2,
514 typename = std::enable_if_t<(RANK1 != RANK2), bool>
521 unsigned int RANK1,
unsigned int RANK2,
522 typename = std::enable_if_t<(RANK1 != RANK2), bool>
541 template <
typename... DIMS>
578 template <
unsigned int RANK,
unsigned int DIM>
579 struct ExtractTensorDimension {
580 static_assert(RANK > DIM,
"Invalid dimension requested");
591 template <
unsigned int RANK>
593 static_assert(RANK > 0,
"Invalid rank 0 for TensorIndices");
609 #endif // LARDATA_UTILITIES_TENSORINDICES_H bool has(Index_t index) const
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_t > at(ITER indexIter) const
Base_t::LinIndex_t LinIndex_t
Type of the linear index.
Namespace for general, non-LArSoft-specific utilities.
std::ptrdiff_t Index_t
Type of a single index in the tensor.
bool operator==(TensorIndices< RANK1 > const &a, TensorIndices< RANK2 > const &b)
Comparison operator with tensors of different rank.
bool hasIndex(Index_t index) const
Types for TensorIndices class.
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_t > at(ITER indexIter) const
Returns the linear index corresponding to the tensor indices.
bool has(Index_t first, OTHERINDICES...others) const
Returns whether the specified set of indices is valid.
DimSize_t dimSize
size of the largest dimension
DimSize_t dim0() const
Returns the size of the outer dimension.
TensorIndices(ITER dimIter)
Base_t::Index_t Index_t
Type of a single index in the tensor.
DimSize_t totalSize() const
Returns the total size of this tensor.
TensorIndices(DimSize_t first, OTHERDIMS...others)
Constructor: initialises the dimension of the tensor.
bool hasLinIndex(LinIndex_t linIndex) const
unsigned int Index_t
Type to denote the index of the flag.
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, bool > has(ITER indexIter) const
DimSize_t dim() const
Returns the size of the specified dimension.
bool hasIndex(Index_t index) const
Returns whether a index is valid within a specified dimension.
DimSize_t totalSize() const
Returns the total size of this tensor (the same as size())
Index_t checkOuterIndex(Index_t index) const
Converts a tensor element specification into a linear index.
TensorIndicesBasicTypes::LinIndex_t LinIndex_t
std::size_t DimSize_t
Type of size of a dimension in the tensor.
DimSize_t totSize
size of this tensor
TensorIndices(ITER dimIter)
Constructor: initialises the dimension of the tensor.
bool hasLinIndex(LinIndex_t linIndex) const
Returns whether the specified linear index is valid in this tensor.
TensorIndices(DimSize_t dim)
TensorIndicesBasicTypes::Index_t Index_t
MinorTensor_t m
the rest of the tensor indices
TensorIndicesBasicTypes::DimSize_t DimSize_t
std::string value(boost::any const &)
static constexpr unsigned int rank()
Rank of this tensor.
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
MinorTensor_t const & minor() const
Returns the tensor of rank Rank-1 from stripping the first dimension.
static constexpr unsigned int rank()
DimSize_t size() const
Returns the size of the minor tensor.
auto makeTensorIndices(DIMS...dims)
Instantiates a TensorIndices class with the specified dimensions.
bool operator!=(TensorIndices< RANK1 > const &a, TensorIndices< RANK2 > const &b)
Comparison operator with tensors of different rank.
std::size_t LinIndex_t
Type of the linear index.
LinIndex_t at(Index_t first, OTHERINDICES...others) const
Returns the linear index corresponding to the tensor indices.
LinIndex_t at(Index_t index) const
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.
Base_t::DimSize_t DimSize_t
Type for the specification of a dimension size.