cMHN 1.1
C++ library for learning MHNs with pRC
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();
134 ++dimension)
135 {
136 if(mSubscripts[dimension] < rhs[dimension])
137 {
138 return true;
139 }
140 if(mSubscripts[dimension] > rhs[dimension])
141 {
142 return false;
143 }
144 }*/
145 return false;
146 }
147
148 constexpr auto isOutOfRange() const
149 {
150 return expand(makeSeries<Index, Dimension{}>(),
151 [this](auto const... seq)
152 {
153 return !((this->operator[](seq) < size(seq)) && ...);
154 });
155 }
156
157 constexpr decltype(auto) periodize() &
158 {
159 return *this %= Sizes();
160 }
161
162 template<class X, If<IsInvocable<Add, Subscripts &, X>> = 0>
163 constexpr auto &operator+=(X &&rhs) &
164 {
165 return *this = *this + forward<X>(rhs);
166 }
167
168 template<class X, If<IsInvocable<Sub, Subscripts &, X>> = 0>
169 constexpr auto &operator-=(X &&rhs) &
170 {
171 return *this = *this - forward<X>(rhs);
172 }
173
174 template<class X, If<IsInvocable<Mul, Subscripts &, X>> = 0>
175 constexpr auto &operator*=(X &&rhs) &
176 {
177 return *this = *this * forward<X>(rhs);
178 }
179
180 template<class X, If<IsInvocable<Div, Subscripts &, X>> = 0>
181 constexpr auto &operator/=(X &&rhs) &
182 {
183 return *this = *this / forward<X>(rhs);
184 }
185
186 template<class X, If<IsInvocable<Mod, Subscripts &, X>> = 0>
187 constexpr auto &operator%=(X &&rhs) &
188 {
189 return *this = *this % forward<X>(rhs);
190 }
191
192 private:
193 constexpr auto check([[maybe_unused]] Index const index)
194 {
195 if constexpr(cDebugLevel >= DebugLevel::Low)
196 {
197 if(!(index < size()))
198 {
199 Logging::error("Index out of range.");
200 }
201 }
202 }
203
204 private:
205 BEGIN_IGNORE_DIAGNOSTIC_GCC("-Wpedantic")
206 StackArray<Index, Dimension{}> mSubscripts;
208 };
209
210 template<Size... Ns>
211 static inline constexpr auto operator+(Subscripts<Ns...> const &lhs,
212 Subscripts<Ns...> const &rhs)
213 {
215 [&lhs, &rhs](auto const... seq)
216 {
217 return Subscripts<Ns...>((lhs[seq] + rhs[seq])...);
218 });
219 }
220
221 template<Size... Ns>
222 static inline constexpr auto operator-(Subscripts<Ns...> const &lhs,
223 Subscripts<Ns...> const &rhs)
224 {
226 [&lhs, &rhs](auto const... seq)
227 {
228 return Subscripts<Ns...>((lhs[seq] - rhs[seq])...);
229 });
230 }
231
232 template<Size... Ns, Size... Ss,
233 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
234 static inline constexpr auto operator*(Subscripts<Ns...> const &lhs,
235 Sizes<Ss...> const)
236 {
238 [&lhs](auto const... seq)
239 {
240 return Subscripts<(
242 (lhs[seq] * Sizes<Ss...>::size(seq))...);
243 });
244 }
245
246 template<Size... Ns, Size... Ss,
247 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
248 static inline constexpr auto operator*(Sizes<Ss...> const,
249 Subscripts<Ns...> const &rhs)
250 {
251 return rhs * Sizes<Ss...>();
252 }
253
254 template<Size... Ns, Size... Ss,
255 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
256 static inline constexpr auto operator/(Subscripts<Ns...> const &lhs,
257 Sizes<Ss...> const)
258 {
260 [&lhs](auto const... seq)
261 {
262 return Subscripts<(
264 (lhs[seq] / Sizes<Ss...>::size(seq))...);
265 });
266 }
267
268 template<Size... Ns, Size... Ss,
269 If<IsSatisfied<(sizeof...(Ns) == sizeof...(Ss))>> = 0>
270 static inline constexpr auto operator%(Subscripts<Ns...> const &lhs,
271 Sizes<Ss...> const)
272 {
274 [&lhs](auto const... seq)
275 {
276 return Subscripts<Ss...>(
277 (lhs[seq] % Sizes<Ss...>::size(seq))...);
278 });
279 }
280
281 template<Size... Ns>
282 static inline constexpr auto operator==(Subscripts<Ns...> const &lhs,
283 Subscripts<Ns...> const &rhs)
284 {
286 [&lhs, &rhs](auto const... seq)
287 {
288 return ((lhs[seq] == rhs[seq]) && ...);
289 });
290 }
291
292 template<Size... Ns>
293 static inline constexpr auto operator!=(Subscripts<Ns...> const &lhs,
294 Subscripts<Ns...> const &rhs)
295 {
296 return !(lhs == rhs);
297 }
298
299 template<Index... Ps, Size... Ns,
300 If<IsSatisfied<(sizeof...(Ps) == sizeof...(Ns))>> = 0,
301 If<IsSatisfied<(max(Ps...) < sizeof...(Ns))>> = 0,
303 static inline constexpr auto permute(Subscripts<Ns...> const &arg)
304 {
306 [&arg](auto const... seq)
307 {
308 return Subscripts<Sizes<Ns...>::size(seq)...>(arg[seq]...);
309 });
310 }
311
312 template<Size... Ns>
313 static inline constexpr auto reverse(Subscripts<Ns...> const &arg)
314 {
316 [&arg](auto const... seq)
317 {
318 return permute<seq...>(arg);
319 });
320 }
321
322 template<Direction D, Size Step, Size... Ns,
324 static inline constexpr auto rotate(Subscripts<Ns...> const &arg)
325 {
327 [&arg](auto const... seq)
328 {
329 return permute<seq...>(arg);
330 });
331 }
332
333 template<Index... Ds, Size... Ns,
334 If<True<decltype(chip<Ds...>(Sequence<Index, Ns...>()))>> = 0>
335 static inline constexpr auto chip(Subscripts<Ns...> const &arg)
336 {
338 [&arg](auto const... seq)
339 {
340 return Subscripts<Sizes<Ns...>::size(seq)...>(arg[seq]...);
341 });
342 }
343}
344#endif // pRC_CORE_CONTAINER_SUBSCRIPTS_H
pRC::Size const D
Definition CalculatePThetaTests.cpp:9
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:181
constexpr auto isOutOfRange() const
Definition subscripts.hpp:148
constexpr auto & operator+=(X &&rhs) &
Definition subscripts.hpp:163
constexpr auto & operator-=(X &&rhs) &
Definition subscripts.hpp:169
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:157
constexpr Subscripts(Index const index)
Definition subscripts.hpp:52
constexpr auto & operator%=(X &&rhs) &
Definition subscripts.hpp:187
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:175
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
static constexpr auto rotate(Sequence< T, First, Is... > const)
Definition sequence.hpp:460
static constexpr auto makeConstantSequence()
Definition sequence.hpp:402
Size Index
Definition type_traits.hpp:21
std::size_t Size
Definition type_traits.hpp:20
static constexpr auto reverse(Direction const D)
Definition direction.hpp:24
std::enable_if_t< B{}, int > If
Definition type_traits.hpp:68
Constant< Bool, B > IsSatisfied
Definition type_traits.hpp:71
static constexpr auto operator-(Sequence< T, As... > const, Sequence< T, Bs... > const)
Definition sequence.hpp:132
static constexpr auto makeSeries()
Definition sequence.hpp:351
CommonArray< Allocation::Stack, T, Ns... > StackArray
Definition type_traits.hpp:52
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:440
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
Sequence(std::integer_sequence< T, Seq... > const) -> Sequence< T, Seq... >
Direction
Definition direction.hpp:9
static constexpr auto chip(Sequence< T, Is... > const)
Definition sequence.hpp:551
static constexpr decltype(auto) expand(Sequence< T, Seq... > const, F &&f, Xs &&...args)
Definition sequence.hpp:344
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