QUGaR 0.0.9
Loading...
Searching...
No Matches
tensor_index_tp.hpp
Go to the documentation of this file.
1// --------------------------------------------------------------------------
2//
3// Copyright (C) 2025-present by Pablo Antolin
4//
5// This file is part of the QUGaR library.
6//
7// SPDX-License-Identifier: MIT
8//
9// --------------------------------------------------------------------------
10
11#ifndef QUGAR_LIBRARY_TENSOR_INDEX_TP_HPP
12#define QUGAR_LIBRARY_TENSOR_INDEX_TP_HPP
13
20
21#include <limits>
22#include <qugar/vector.hpp>
23
24
25#include <array>
26#include <cassert>
27#include <cstddef>
28#include <cstdint>
29#include <functional>
30#include <type_traits>
31
32namespace qugar {
33
34template<int dim> class TensorIndexTP;
35
39template<int dim> class TensorSizeTP : public Vector<int, dim>
40{
41public:
43
45
48
51 explicit TensorSizeTP(const int size);
52
55 explicit TensorSizeTP(const Vector<int, dim> &sizes);
56
59 explicit TensorSizeTP(const TensorIndexTP<dim> &sizes);
60
62
68
74
77 [[nodiscard]] std::size_t size() const;
78
82 [[nodiscard]] bool operator==(const TensorSizeTP<dim> &rhs) const;
83
90 [[nodiscard]] TensorSizeTP<dim> operator+(const TensorSizeTP<dim> &rhs) const;
91};
92
96template<int dim> class TensorIndexTP : public Vector<int, dim>
97{
98public:
100
101
103 template<int aux_dim = dim>
104 requires(aux_dim == dim && dim > 0)
107
108 template<int aux_dim = dim>
109 requires(aux_dim == dim && dim == 0)
112
116 template<int aux_dim = dim>
117 requires(aux_dim == dim && dim > 0)
118 explicit TensorIndexTP(int ind) : Vector<int, dim>(ind)
119 {}
120
123 explicit TensorIndexTP(const Vector<int, dim> &indices);
124
127 explicit TensorIndexTP(const TensorSizeTP<dim> &indices);
128
136 template<int aux_dim = dim>
137 requires(aux_dim == dim && dim > 0)
138 TensorIndexTP(std::int64_t flat_index, const TensorIndexTP<dim> &size)
139 {
140 auto total_size = static_cast<std::int64_t>(prod(size.as_Vector()));
141
142 // NOLINTNEXTLINE (readability-simplify-boolean-expr)
143 assert(0 <= flat_index && flat_index < total_size);
144
145 for (int dir = dim - 1; dir >= 0; --dir) {
146 total_size /= size(dir);
147 const std::int64_t ind = flat_index / total_size;
148 assert(ind < std::numeric_limits<int>::max());
149 this->operator()(dir) = static_cast<int>(ind);
150 flat_index -= ind * total_size;
151 }
152 }
153
161 template<int aux_dim = dim>
162 requires(aux_dim == dim && dim > 0)
163 TensorIndexTP(std::int64_t flat_index, const TensorSizeTP<dim> &size) : TensorIndexTP(flat_index, TensorIndexTP(size))
164 {}
165
168 template<typename... T>
169 requires(dim > 1 && sizeof...(T) == dim && std::conjunction_v<std::is_same<int, T>...>)
170 explicit TensorIndexTP(T... indices) : TensorIndexTP(Vector<int, dim>{ indices... })
171 {}
172
174
180 {
181 // For an unknown reason, the linker (llvm 17) doesn't find the symbol if the implementation is moved to the .cpp
182 // file
183 return dynamic_cast<const Vector<int, dim> &>(*this);
184 }
185
191
197 template<typename S> [[nodiscard]] std::int64_t flat(const S &size) const;
198
202 [[nodiscard]] bool operator==(const TensorIndexTP<dim> &rhs) const;
203
207 [[nodiscard]] bool operator!=(const TensorIndexTP<dim> &rhs) const;
208
213 [[nodiscard]] bool operator<(const TensorIndexTP<dim> &rhs) const;
214
218 template<int aux_dim = dim>
219 requires(aux_dim == dim && dim > 1)
221
228 [[nodiscard]] std::size_t hash() const;
229};
230
231}// namespace qugar
232
233namespace std {
234template<int dim> struct hash<qugar::TensorIndexTP<dim>>
235{
236 size_t operator()(const qugar::TensorIndexTP<dim> &tid) const noexcept { return tid.hash(); }
237};
238}// namespace std
239
240namespace qugar {
241
245template<int dim> class TensorIndexRangeTP
246{
247public:
251 TensorIndexRangeTP(const TensorIndexTP<dim> &lower_bound, const TensorIndexTP<dim> &upper_bound);
252
256 explicit TensorIndexRangeTP(const TensorIndexTP<dim> &upper_bound);
257
261 explicit TensorIndexRangeTP(const TensorSizeTP<dim> &upper_bound);
262
266 explicit TensorIndexRangeTP(int upper_bound);
267
270 [[nodiscard]] TensorSizeTP<dim> get_sizes() const;
271
274 [[nodiscard]] std::size_t size() const;
275
280 [[nodiscard]] std::array<TensorIndexRangeTP<dim>, 2> split() const;
281
282
285 {
286 public:
292 const TensorIndexTP<dim> &lower_bound,
293 const TensorIndexTP<dim> &upper_bound);
294
297 [[nodiscard]] const TensorIndexTP<dim> &operator*() const;
298
301 [[nodiscard]] const TensorIndexTP<dim> *operator->() const;
302
306 [[nodiscard]] std::int64_t flat() const;
307
311
314 // NOLINTNEXTLINE (cert-dcl21-cpp) // Check deprecated.
316
321 [[nodiscard]] bool operator==(const Iterator &rhs) const;
322
327 [[nodiscard]] bool operator!=(const Iterator &rhs) const;
328
329 private:
336 };
337
342
346
350 Iterator cend() const;
351
354 Iterator end() const;
355
358 [[nodiscard]] const TensorIndexTP<dim> &get_lower_bound() const;
359
362 [[nodiscard]] const TensorIndexTP<dim> &get_upper_bound() const;
363
367 [[nodiscard]] bool is_in_range(const TensorIndexTP<dim> &index) const;
368
373 [[nodiscard]] bool is_in_range(std::int64_t index, const TensorSizeTP<dim> &total_size) const;
374
375private:
380};
381
382
383}// namespace qugar
384
385#endif// QUGAR_LIBRARY_TENSOR_INDEX_TP_HPP
Iterator class for tensor index ranges.
Definition tensor_index_tp.hpp:285
TensorIndexTP< dim > index_
Iterator index.
Definition tensor_index_tp.hpp:331
bool operator!=(const Iterator &rhs) const
Compares if two iterators are different. They are considered to be different if at least one of the c...
const TensorIndexTP< dim > & operator*() const
Dereference operator.
Iterator & operator++()
Pre increments the iterator.
bool operator==(const Iterator &rhs) const
Compares if two iterators are equal. They are considered to be equal if their indices and bounds are ...
const TensorIndexTP< dim > * operator->() const
Indirection operator.
std::int64_t flat() const
Transforms the current tensor index into a flat one by considering the upper bound as associated size...
TensorIndexTP< dim > lower_bound_
Lower bound.
Definition tensor_index_tp.hpp:333
Iterator operator++(int)
Post increments the iterator.
Iterator(const TensorIndexTP< dim > &index, const TensorIndexTP< dim > &lower_bound, const TensorIndexTP< dim > &upper_bound)
Constructs a new iterator object given and index and its lower and upper bounds.
TensorIndexTP< dim > upper_bound_
Upper bound.
Definition tensor_index_tp.hpp:335
Class representing a dim-dimensional range defined by lower and upper tensor bounds.
Definition tensor_index_tp.hpp:246
std::array< TensorIndexRangeTP< dim >, 2 > split() const
Splits the current range along the direction with a largest number of indices.
TensorIndexRangeTP(int upper_bound)
Constructs a new TensorIndexRangeTP object from its upper bound. The lower bound is assumed to be zer...
TensorIndexRangeTP(const TensorIndexTP< dim > &upper_bound)
Constructs a new TensorIndexRangeTP object from its upper bound. The lower bound is assumed to be zer...
Iterator cbegin() const
Creates a begin iterator.
TensorSizeTP< dim > get_sizes() const
Gets the sizes along all the directions.
const TensorIndexTP< dim > & get_upper_bound() const
Gets the upper bound.
std::size_t size() const
returns the number of entries in the range.
TensorIndexRangeTP(const TensorIndexTP< dim > &lower_bound, const TensorIndexTP< dim > &upper_bound)
Constructs a new TensorIndexRangeTP object from its lower and upper bounds.
TensorIndexTP< dim > upper_bound_
Upper bounds.
Definition tensor_index_tp.hpp:379
bool is_in_range(const TensorIndexTP< dim > &index) const
Checks that the given index is contained in the range.
Iterator end() const
Creates an end iterator.
Iterator begin() const
Creates a begin iterator.
const TensorIndexTP< dim > & get_lower_bound() const
Gets the lower bound.
TensorIndexTP< dim > lower_bound_
Lower bounds.
Definition tensor_index_tp.hpp:377
TensorIndexRangeTP(const TensorSizeTP< dim > &upper_bound)
Constructs a new TensorIndexRangeTP object from its upper bound. The lower bound is assumed to be zer...
Iterator cend() const
Creates an end iterator.
bool is_in_range(std::int64_t index, const TensorSizeTP< dim > &total_size) const
Checks that the given index is contained in the range.
Class representing a dim-dimensional tensor-product indices.
Definition tensor_index_tp.hpp:97
TensorIndexTP(int ind)
Constructs a new TensorIndexTP object from an index.
Definition tensor_index_tp.hpp:118
TensorIndexTP(std::int64_t flat_index, const TensorSizeTP< dim > &size)
Constructs a new TensorIndexTP object from a flat index and an associated tensor size following the l...
Definition tensor_index_tp.hpp:163
bool operator<(const TensorIndexTP< dim > &rhs) const
Checks if the current tensor index is smaller than rhs. To determine if one is smaller than the other...
TensorIndexTP()
Definition tensor_index_tp.hpp:110
const Vector< int, dim > & as_Vector() const
Returns the tensor index casted as a Vector.
Definition tensor_index_tp.hpp:179
TensorIndexTP()
Default constructor. Initializes indices to zero.
Definition tensor_index_tp.hpp:105
Vector< int, dim > & as_Vector()
Returns the tensor index casted as a Vector.
TensorIndexTP< dim - 1 > remove_component(int comp) const
Creates a new index by removing one of its component.
TensorIndexTP(T... indices)
Constructs the tensor index from an argument list.
Definition tensor_index_tp.hpp:170
TensorIndexTP(std::int64_t flat_index, const TensorIndexTP< dim > &size)
Constructs a new TensorIndexTP object from a flat index and an associated tensor size following the l...
Definition tensor_index_tp.hpp:138
TensorIndexTP(const TensorSizeTP< dim > &indices)
Constructs a new TensorIndexTP object from its indices.
std::int64_t flat(const S &size) const
Gets the flat index associated to the current tensor index for a given tensor size.
bool operator!=(const TensorIndexTP< dim > &rhs) const
Checks if two tensor indices are different by comparing all its components. They are different if at ...
std::size_t hash() const
Computes a hash value for the tensor index.
TensorIndexTP(const Vector< int, dim > &indices)
Constructs a new TensorIndexTP object from its indices.
bool operator==(const TensorIndexTP< dim > &rhs) const
Checks if two tensor indices are equal by comparing all its components. They are equal if all the com...
Class representing a dim-dimensional tensor-product sizes container.
Definition tensor_index_tp.hpp:40
TensorSizeTP< dim > operator+(const TensorSizeTP< dim > &rhs) const
Adds two TensorSizeTP objects.
TensorSizeTP(const TensorIndexTP< dim > &sizes)
Construct a new TensorSizeTP object from sizes along directions.
std::size_t size() const
Gets the total number of entries (product of sizes along all directions).
const Vector< int, dim > & as_Vector() const
Returns the tensor size casted as a Vector.
Vector< int, dim > & as_Vector()
Returns the tensor size casted as a Vector.
TensorSizeTP()
Default constructor. Initializes indices to zero.
bool operator==(const TensorSizeTP< dim > &rhs) const
Checks if two tensor sizes are equal by comparing all its components. They are equal if all the compo...
TensorSizeTP(const Vector< int, dim > &sizes)
Construct a new TensorSizeTP object from sizes along directions.
TensorSizeTP(const int size)
Construct a new TensorSizeTP object from size along directions.
QUGaR's main namespace.
Definition affine_transf.hpp:28
::algoim::uvector< T, dim > Vector
Class representing a vector.
Definition vector.hpp:31
std::ptrdiff_t index
Definition types.hpp:19
Definition tensor_index_tp.hpp:233
size_t operator()(const qugar::TensorIndexTP< dim > &tid) const noexcept
Definition tensor_index_tp.hpp:236