14namespace Experimental {
30 if (shape.size() == 0)
49 const auto size = shape.size();
52 for (std::size_t i = 0; i < size; i++) {
54 strides[size - 1 - i] = 1;
56 strides[size - 1 - i] = strides[size - 1 - i + 1] * shape[size - 1 - i + 1];
60 for (std::size_t i = 0; i < size; i++) {
64 strides[i] = strides[i - 1] * shape[i - 1];
69 ss <<
"Memory layout type is not valid for calculating strides.";
70 throw std::runtime_error(ss.str());
83 const auto size = shape.size();
87 for (std::size_t i = 0; i < size; i++) {
88 indices[i] = int(
r / strides[i]);
98template <
typename U,
typename V>
101 std::size_t globalIndex = 0;
102 const auto size = idx.size();
103 for (std::size_t i = 0; i < size; i++) {
104 globalIndex += strides[size - 1 - i] * idx[size - 1 - i];
110template <
class... Ts>
114template <
class T0,
class... Ts>
115struct and_types<T0, Ts...> : std::integral_constant<bool, T0{} && and_types<Ts...>{}> {
130 const std::vector<std::size_t> &mins,
const std::vector<std::size_t> &maxs,
131 std::vector<std::size_t> idx, std::size_t active)
133 const auto size = idx.size();
134 for (std::size_t i = mins[active]; i < maxs[active]; i++) {
136 if (active == size - 1) {
138 for (std::size_t j = 0; j < size; j++) {
139 idxThere[j] -= mins[j];
141 there(idxThere) = here(idx);
161template <
typename V,
typename C = std::vector<V>>
217 fData = &(*container->begin());
263 class Iterator :
public std::iterator<std::random_access_iterator_tag, Value_t> {
268 using difference_type =
typename std::iterator<std::random_access_iterator_tag, Value_t>::difference_type;
311template <
typename Value_t,
typename Container_t>
316 std::stringstream ss;
317 ss <<
"Cannot reshape tensor with size " << fSize <<
" into shape { ";
318 for (std::size_t i = 0; i < shape.size(); i++) {
319 if (i != shape.size() - 1) {
320 ss << shape[i] <<
", ";
322 ss << shape[i] <<
" }.";
325 throw std::runtime_error(ss.str());
338template <
typename Value_t,
typename Container_t>
342 return fData[globalIndex];
348template <
typename Value_t,
typename Container_t>
352 return fData[globalIndex];
358template <
typename Value_t,
typename Container_t>
359template <
typename... Idx>
363 "Indices are not convertible to std::size_t.");
364 return operator()({
static_cast<std::size_t
>(idx)...});
370template <
typename Value_t,
typename Container_t>
371template <
typename... Idx>
375 "Indices are not convertible to std::size_t.");
376 return operator()({
static_cast<std::size_t
>(idx)...});
384template <
typename Value_t,
typename Container_t>
388 if (fLayout == MemoryLayout::RowMajor) {
389 fLayout = MemoryLayout::ColumnMajor;
390 }
else if (fLayout == MemoryLayout::ColumnMajor) {
391 fLayout = MemoryLayout::RowMajor;
393 throw std::runtime_error(
"Memory layout is not known.");
400 std::reverse(
x.fShape.begin(),
x.fShape.end());
403 std::reverse(
x.fStrides.begin(),
x.fStrides.end());
411template <
typename Value_t,
typename Container_t>
417 for (std::size_t i = 0; i < fShape.size(); i++) {
418 if (fShape[i] != 1) {
419 shape.emplace_back(fShape[i]);
420 strides.emplace_back(fStrides[i]);
427 if (shape.size() == 0 && fShape.size() != 0) {
428 shape.emplace_back(1);
429 strides.emplace_back(1);
435 x.fStrides = strides;
443template <
typename Value_t,
typename Container_t>
447 const int len = fShape.size();
449 auto strides = fStrides;
451 if (len + idx + 1 < 0) {
452 throw std::runtime_error(
"Given negative index is invalid.");
454 shape.insert(shape.end() + 1 + idx, 1);
455 strides.insert(strides.begin() + 1 + idx, 1);
458 throw std::runtime_error(
"Given index is invalid.");
460 shape.insert(shape.begin() + idx, 1);
461 strides.insert(strides.begin() + idx, 1);
467 x.fStrides = strides;
475template <
typename Value_t,
typename Container_t>
480 x.ReshapeInplace(shape);
488template <
typename Value_t,
typename Container_t>
492 const auto sliceSize = slice.size();
493 const auto shapeSize = fShape.size();
494 if (sliceSize != shapeSize) {
495 std::stringstream ss;
496 ss <<
"Size of slice (" << sliceSize <<
") is unequal number of dimensions (" << shapeSize <<
").";
497 throw std::runtime_error(ss.str());
512 for (std::size_t i = 0; i < sliceSize; i++) {
513 shape[i] = slice[i][1] - slice[i][0];
520 for (std::size_t i = 0; i < sliceSize; i++) {
521 idx[i] = slice[i][0];
541template <
typename Value_t,
typename Container_t>
548 const auto mins =
Shape_t(fShape.size());
549 const auto maxs = fShape;
563 const auto shapeSize =
x.GetShape().size();
564 if (shapeSize == 1) {
566 const auto size =
x.GetSize();
567 for (std::size_t i = 0; i < size; i++) {
573 }
else if (shapeSize == 2) {
575 const auto shape =
x.GetShape();
576 for (std::size_t i = 0; i < shape[0]; i++) {
578 for (std::size_t j = 0; j < shape[1]; j++) {
580 if (j < shape[1] - 1) {
590 os <<
"{ printing not yet implemented for this rank }";
602 std::stringstream ss;
TRObject operator()(const T1 &t1) const
bool operator>=(const Iterator &rhs) const
bool operator==(const Iterator &rhs) const
Iterator(RTensor< Value_t, Container_t > &x, typename Index_t::value_type idx)
bool operator!=(const Iterator &rhs) const
difference_type operator-(const Iterator &rhs)
Iterator operator+(difference_type rhs) const
bool operator<(const Iterator &rhs) const
Index_t::value_type fGlobalIndex
Iterator & operator+=(difference_type rhs)
Iterator & operator-=(difference_type rhs)
typename std::iterator< std::random_access_iterator_tag, Value_t >::difference_type difference_type
RTensor< Value_t, Container_t > & fTensor
bool operator>(const Iterator &rhs) const
Iterator operator-(difference_type rhs) const
Index_t::value_type GetGlobalIndex() const
bool operator<=(const Iterator &rhs) const
RTensor is a container with contiguous memory and shape information.
void ReshapeInplace(const Shape_t &shape)
Reshape tensor in place.
const std::shared_ptr< Container_t > GetContainer() const
Value_t & operator()(const Index_t &idx)
Access elements.
RTensor< Value_t, Container_t > Transpose()
Transpose.
RTensor(Shape_t shape, MemoryLayout layout=MemoryLayout::RowMajor)
Construct a tensor owning data initialized with new container.
MemoryLayout GetMemoryLayout() const
std::vector< Shape_t > Slice_t
RTensor(Value_t *data, Shape_t shape, Shape_t strides, MemoryLayout layout=MemoryLayout::RowMajor)
Construct a tensor as view on data.
RTensor< Value_t, Container_t > Reshape(const Shape_t &shape)
Reshape tensor.
std::shared_ptr< Container_t > GetContainer()
Value_t & operator()(Idx... idx)
Access elements.
std::shared_ptr< Container_t > fContainer
RTensor(std::shared_ptr< Container_t > container, Shape_t shape, MemoryLayout layout=MemoryLayout::RowMajor)
Construct a tensor owning externally provided data.
RTensor< Value_t, Container_t > ExpandDims(int idx)
Expand dimensions.
const Shape_t & GetStrides() const
std::size_t GetSize() const
RTensor(Value_t *data, Shape_t shape, MemoryLayout layout=MemoryLayout::RowMajor)
Construct a tensor as view on data.
RTensor< Value_t, Container_t > Slice(const Slice_t &slice)
Create a slice of the tensor.
const Value_t * GetData() const
Iterator begin() noexcept
const Shape_t & GetShape() const
RTensor< Value_t, Container_t > Squeeze()
Squeeze dimensions.
RTensor< Value_t, Container_t > Copy(MemoryLayout layout=MemoryLayout::RowMajor)
Copy RTensor to new object.
std::vector< std::size_t > Shape_t
Expr< TransposeOp< SMatrix< T, D1, D2, R >, T, D1, D2 >, T, D2, D1, typename TranspPolicy< T, D1, D2, R >::RepType > Transpose(const SMatrix< T, D1, D2, R > &rhs)
Matrix Transpose B(i,j) = A(j,i) returning a matrix expression.
void Copy(void *source, void *dest)
RooCmdArg Slice(const RooArgSet &sliceSet)
static constexpr double s
std::vector< std::size_t > ComputeStridesFromShape(const T &shape, MemoryLayout layout)
Compute strides from shape vector.
void RecursiveCopy(T &here, T &there, const std::vector< std::size_t > &mins, const std::vector< std::size_t > &maxs, std::vector< std::size_t > idx, std::size_t active)
Copy slice of a tensor recursively from here to there.
T ComputeIndicesFromGlobalIndex(const T &shape, MemoryLayout layout, const typename T::value_type idx)
Compute indices from global index.
std::size_t GetSizeFromShape(const T &shape)
Get size of tensor from shape vector.
std::size_t ComputeGlobalIndex(const U &strides, const V &idx)
Compute global index from indices.
MemoryLayout
Memory layout type (copy from RTensor.hxx)
std::ostream & operator<<(std::ostream &os, RTensor< T > &x)
Pretty printing.
create variable transformations
Type checking for all types of a parameter pack, e.g., used in combination with std::is_convertible.