pRC
multi-purpose Tensor Train library for C++
Loading...
Searching...
No Matches
subscripts.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-2-Clause
2
3#ifndef pRC_CORE_CONTAINER_SUBSCRIPTS_H
4#define pRC_CORE_CONTAINER_SUBSCRIPTS_H
5
13#include <prc/core/log/log.hpp>
14#include <prc/pragma.hpp>
15
16namespace pRC
17{
18 template<Size... Ns>
20 {
21 public:
22 using Sizes = pRC::Sizes<Ns...>;
23 using Dimension = typename Sizes::Dimension;
24
25 template<class E = typename Sizes::IsLinearizable, If<E> = 0>
26 static constexpr auto size()
27 {
28 return Sizes::size();
29 }
30
31 static constexpr auto size(Index const dimension)
32 {
33 return Sizes::size(dimension);
34 }
35
36 public:
37 ~Subscripts() = default;
38 constexpr Subscripts() = default;
39 constexpr Subscripts(Subscripts const &) = default;
40 constexpr Subscripts(Subscripts &&) = default;
41 constexpr Subscripts &operator=(Subscripts const &) & = default;
42 constexpr Subscripts &operator=(Subscripts &&) & = default;
43
44 template<class... Ss, If<All<IsConvertible<Ss, Index>...>> = 0,
45 If<IsSatisfied<(sizeof...(Ss) == Dimension())>> = 0>
46 explicit constexpr Subscripts(Ss const... subscripts)
47 : mSubscripts(subscripts...)
48 {
49 }
50
51 template<Index D = Dimension(), If<IsSatisfied<(D == 0)>> = 0>
52 explicit constexpr Subscripts(Index const index)
53 {
54 check(index);
55 }
56
57 template<Index D = Dimension(), If<IsSatisfied<(D > 1)>> = 0,
58 class E = typename Sizes::IsLinearizable, If<E> = 0>
59 explicit constexpr Subscripts(Index const index)
60 {
61 check(index);
62
63 expand(
64 makeSeries<Index, Dimension{} - 1>(),
65 [this](auto index, auto const... seq)
66 {
67 operator[](0) = index % size(0);
68 ((operator[](seq + 1) =
69 (index /= size(seq)) % size(seq + 1)),
70 ...);
71 },
72 index);
73 }
74
75 template<class E = typename Sizes::IsLinearizable, If<E> = 0>
76 explicit constexpr operator Index() const
77 {
78 if constexpr(cDebugLevel >= DebugLevel::Low)
79 {
80 if(isOutOfRange())
81 {
82 Logging::error("Subscripts out of range.");
83 }
84 }
85
86 return expand(
88 [](auto subscripts, auto const... seq)
89 {
90 [[maybe_unused]] Index scale = 1;
91 ((subscripts[seq] *= scale, scale *= size(seq)), ...);
92 return (subscripts[seq] + ... + 0);
93 },
94 mSubscripts);
95 }
96
97 constexpr decltype(auto) operator[](Index const dimension) &&
98 {
99 return move(mSubscripts)[dimension];
100 }
101
102 constexpr decltype(auto) operator[](Index const dimension) const &&
103 {
104 return move(mSubscripts)[dimension];
105 }
106
107 constexpr decltype(auto) operator[](Index const dimension) &
108 {
109 return mSubscripts[dimension];
110 }
111
112 constexpr decltype(auto) operator[](Index const dimension) const &
113 {
114 return mSubscripts[dimension];
115 }
116
117 constexpr bool operator<(const Subscripts &rhs) const
118 {
119 for(std::size_t i = Dimension(); i > 0; --i)
120 {
121
122 auto lhsE = mSubscripts[i - 1];
123 auto rhsE = rhs[i - 1];
124 if(lhsE < rhsE)
125 {
126 return true;
127 }
128 if(lhsE > rhsE)
129 {
130 return false;
131 }
132 }
133 /*for(std::size_t dimension = 0; dimension < Dimension(); ++dimension)
134 {
135 if(mSubscripts[dimension] < rhs[dimension])
136 {
137 return true;
138 }
139 if(mSubscripts[dimension] > rhs[dimension])
140 {
141 return false;
142 }
143 }*/
144 return false;
145 }
146
147 constexpr auto isOutOfRange() const
148 {
149 return expand(makeSeries<Index, Dimension{}>(),
150 [this](auto const... seq)
151 {
152 return !((this->operator[](seq) < size(seq)) && ...);
153 });
154 }
155
156 constexpr decltype(auto) periodize() &
157 {
158 return *this %= Sizes();
159 }
160
161 template<class X, If<IsInvocable<Add, Subscripts &, X>> = 0>
162 constexpr auto &operator+=(X &&rhs) &
163 {
164 return *this = *this + forward<X>(rhs);
165 }
166
167 template<class X, If<IsInvocable<Sub, Subscripts &, X>> = 0>
168 constexpr auto &operator-=(X &&rhs) &
169 {
170 return *this = *this - forward<X>(rhs);
171 }
172
173 template<class X, If<IsInvocable<Mul, Subscripts &, X>> = 0>
174 constexpr auto &operator*=(X &&rhs) &
175 {
176 return *this = *this * forward<X>(rhs);
177 }
178
179 template<class X, If<IsInvocable<Div, Subscripts &, X>> = 0>
180 constexpr auto &operator/=(X &&rhs) &
181 {
182 return *this = *this / forward<X>(rhs);
183 }
184
185 template<class X, If<IsInvocable<Mod, Subscripts &, X>> = 0>
186 constexpr auto &operator%=(X &&rhs) &
187 {
188 return *this = *this % forward<X>(rhs);
189 }
190
191 private:
192 constexpr auto check([[maybe_unused]] Index const index)
193 {
194 if constexpr(cDebugLevel >= DebugLevel::Low)
195 {
196 if(!(index < size()))
197 {
198 Logging::error("Index out of range.");
199 }
200 }
201 }
202
203 private:
204 BEGIN_IGNORE_DIAGNOSTIC_GCC("-Wpedantic")
205 StackArray<Index, Dimension{}> mSubscripts;
207 };
208
209 template<Size... Ns>
210 static inline constexpr auto operator+(Subscripts<Ns...> const &lhs,
211 Subscripts<Ns...> const &rhs)
212 {
214 [&lhs, &rhs](auto const... seq)
215 {
216 return Subscripts<Ns...>((lhs[seq] + rhs[seq])...);
217 });
218 }
219
220 template<Size... Ns>
221 static inline constexpr auto operator-(Subscripts<Ns...> const &lhs,
222 Subscripts<Ns...> const &rhs)
223 {
225 [&lhs, &rhs](auto const... seq)
226 {
227 return Subscripts<Ns...>((lhs[seq] - rhs[seq])...);
228 });
229 }
230
231 template<Size... Ns, Size... Ss,
232 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
233 static inline constexpr auto operator*(Subscripts<Ns...> const &lhs,
234 Sizes<Ss...> const)
235 {
237 [&lhs](auto const... seq)
238 {
239 return Subscripts<(
241 (lhs[seq] * Sizes<Ss...>::size(seq))...);
242 });
243 }
244
245 template<Size... Ns, Size... Ss,
246 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
247 static inline constexpr auto operator*(Sizes<Ss...> const,
248 Subscripts<Ns...> const &rhs)
249 {
250 return rhs * Sizes<Ss...>();
251 }
252
253 template<Size... Ns, Size... Ss,
254 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
255 static inline constexpr auto operator/(Subscripts<Ns...> const &lhs,
256 Sizes<Ss...> const)
257 {
259 [&lhs](auto const... seq)
260 {
261 return Subscripts<(
263 (lhs[seq] / Sizes<Ss...>::size(seq))...);
264 });
265 }
266
267 template<Size... Ns, Size... Ss,
268 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
269 static inline constexpr auto operator%(Subscripts<Ns...> const &lhs,
270 Sizes<Ss...> const)
271 {
273 [&lhs](auto const... seq)
274 {
275 return Subscripts<Ss...>(
276 (lhs[seq] % Sizes<Ss...>::size(seq))...);
277 });
278 }
279
280 template<Size... Ns>
281 static inline constexpr auto operator==(Subscripts<Ns...> const &lhs,
282 Subscripts<Ns...> const &rhs)
283 {
285 [&lhs, &rhs](auto const... seq)
286 {
287 return ((lhs[seq] == rhs[seq]) && ...);
288 });
289 }
290
291 template<Size... Ns>
292 static inline constexpr auto operator!=(Subscripts<Ns...> const &lhs,
293 Subscripts<Ns...> const &rhs)
294 {
295 return !(lhs == rhs);
296 }
297
298 template<Index... Ps, Size... Ns,
299 If<IsSatisfied<(sizeof...(Ps) == sizeof...(Ns))>> = 0,
300 If<IsSatisfied<(max(Ps...) < sizeof...(Ns))>> = 0,
302 static inline constexpr auto permute(Subscripts<Ns...> const &arg)
303 {
305 [&arg](auto const... seq)
306 {
307 return Subscripts<Sizes<Ns...>::size(seq)...>(arg[seq]...);
308 });
309 }
310
311 template<Size... Ns>
312 static inline constexpr auto reverse(Subscripts<Ns...> const &arg)
313 {
315 [&arg](auto const... seq)
316 {
317 return permute<seq...>(arg);
318 });
319 }
320
321 template<Direction D, Size Step, Size... Ns,
323 static inline constexpr auto rotate(Subscripts<Ns...> const &arg)
324 {
326 [&arg](auto const... seq)
327 {
328 return permute<seq...>(arg);
329 });
330 }
331
332 template<Index... Ds, Size... Ns,
333 If<True<decltype(chip<Ds...>(Sequence<Index, Ns...>()))>> = 0>
334 static inline constexpr auto chip(Subscripts<Ns...> const &arg)
335 {
337 [&arg](auto const... seq)
338 {
339 return Subscripts<Sizes<Ns...>::size(seq)...>(arg[seq]...);
340 });
341 }
342}
343#endif // pRC_CORE_CONTAINER_SUBSCRIPTS_H
Definition sequence.hpp:56
static constexpr auto size()
Definition sequence.hpp:88
Constant< Size, sizeof...(Ns)> Dimension
Definition sequence.hpp:74
Constant< Bool, linearizable()> IsLinearizable
Definition sequence.hpp:75
Definition subscripts.hpp:20
constexpr Subscripts & operator=(Subscripts const &) &=default
static constexpr auto size()
Definition subscripts.hpp:26
constexpr decltype(auto) operator[](Index const dimension) &&
Definition subscripts.hpp:97
constexpr auto & operator/=(X &&rhs) &
Definition subscripts.hpp:180
constexpr auto isOutOfRange() const
Definition subscripts.hpp:147
constexpr auto & operator+=(X &&rhs) &
Definition subscripts.hpp:162
constexpr auto & operator-=(X &&rhs) &
Definition subscripts.hpp:168
constexpr Subscripts(Index const index)
Definition subscripts.hpp:59
typename Sizes::Dimension Dimension
Definition subscripts.hpp:23
constexpr Subscripts()=default
constexpr Subscripts & operator=(Subscripts &&) &=default
constexpr Subscripts(Ss const ... subscripts)
Definition subscripts.hpp:46
~Subscripts()=default
constexpr decltype(auto) periodize() &
Definition subscripts.hpp:156
constexpr Subscripts(Index const index)
Definition subscripts.hpp:52
constexpr auto & operator%=(X &&rhs) &
Definition subscripts.hpp:186
static constexpr auto size(Index const dimension)
Definition subscripts.hpp:31
constexpr Subscripts(Subscripts &&)=default
constexpr Subscripts(Subscripts const &)=default
pRC::Sizes< Ns... > Sizes
Definition subscripts.hpp:22
constexpr bool operator<(const Subscripts &rhs) const
Definition subscripts.hpp:117
constexpr auto & operator*=(X &&rhs) &
Definition subscripts.hpp:174
static void error(Xs &&...args)
Definition log.hpp:14
Definition cholesky.hpp:18
static constexpr auto arg(Complex< T > const &a)
Definition arg.hpp:12
CommonArray< Allocation::Stack, T, Ns... > StackArray
Definition type_traits.hpp:52
static constexpr auto rotate(Sequence< T, First, Is... > const)
Definition sequence.hpp:470
static constexpr auto reverse(Direction const D)
Definition direction.hpp:24
std::enable_if_t< B{}, int > If
Definition type_traits.hpp:68
std::size_t Size
Definition type_traits.hpp:20
static constexpr auto operator-(Sequence< T, As... > const, Sequence< T, Bs... > const)
Definition sequence.hpp:132
static constexpr auto makeSeries()
Definition sequence.hpp:361
Constant< Bool, B > IsSatisfied
Definition type_traits.hpp:71
static constexpr Conditional< IsSatisfied< C >, RemoveConstReference< X >, X > copy(X &&a)
Definition copy.hpp:13
static constexpr auto operator!=(JacobiRotation< TA > const &a, JacobiRotation< TB > const &b)
Definition jacobi_rotation.hpp:304
constexpr auto cDebugLevel
Definition config.hpp:46
static constexpr auto permute(Sequence< T, Is... > const)
Definition sequence.hpp:450
static constexpr auto operator==(JacobiRotation< TA > const &a, JacobiRotation< TB > const &b)
Definition jacobi_rotation.hpp:297
static constexpr auto operator+(Sequence< T, As... > const, Sequence< T, Bs... > const)
Definition sequence.hpp:110
Direction
Definition direction.hpp:9
static constexpr auto chip(Sequence< T, Is... > const)
Definition sequence.hpp:561
static constexpr decltype(auto) expand(Sequence< T, Seq... > const, F &&f, Xs &&...args)
forwards the values in a pRC::Sequence to a function as parameters
Definition sequence.hpp:354
Size Index
Definition type_traits.hpp:21
static constexpr X max(X &&a)
Definition max.hpp:13
#define BEGIN_IGNORE_DIAGNOSTIC_GCC(warning)
Definition pragma.hpp:42
#define END_IGNORE_DIAGNOSTIC_GCC
Definition pragma.hpp:43