FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
MultiIndex.hpp
1#ifndef __Fiber_MultiIndex_HPP
2#define __Fiber_MultiIndex_HPP
3
4#include <eagle/vecmath.hpp>
5#include <eagle/Assignment.hpp>
6#include <eagle/Operator.hpp>
7#include <eagle/FixedArray.hpp>
8#include <eagle/DomainVector.hpp>
9
10#include "Index.hpp"
11
12#include <array>
13#include <initializer_list>
14
15namespace Fiber
16{
17
19
20using Eagle::Mult;
21using Eagle::Div;
22using Eagle::Add;
23using Eagle::Sub;
24
55
57
58using Dims_t = int;
59
71template <Dims_t Dims>
72 class MultiIndex;
73
74
75template <Dims_t Dims>
77{
79 bool Iteratable;
80
82 : Size(MaxIndex)
83 {
84 Iteratable = MaxIndex.size()>0;
85 }
86
89 , Size(MaxIndex)
90 {}
91
92 void operator++()
93 {
94 Iteratable = this->inc(Size);
95 }
96
97 MultiIndex<Dims>&operator*()
98 {
99 return *this;
100 }
101
102 bool operator!=(const MultiIndexIterator&)
103 {
104 return Iteratable;
105 }
106};
107
108
112template <>
113 class MultiIndex<1>
114{
115 index_t idx;
116
117protected:
118 typedef index_t Index;
119 typedef Index value_type;
120
121 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Add&) noexcept
122 : idx(M.idx + D.maxidx() )
123 {}
124
125 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Sub&) noexcept
126 : idx(M.idx - D.maxidx() )
127 {}
128
129 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Mult&) noexcept
130 : idx(M.idx * D.maxidx() )
131 {}
132
133 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Div&) noexcept
134 : idx(M.idx / D.maxidx() )
135 {}
136
137 constexpr MultiIndex(unsigned int bits, const ::Eagle::BinaryAnd&) noexcept
138 : idx( (bits & 1) ? 1 : 0 )
139 {}
140
141 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const ::Eagle::BinaryAnd&) noexcept
142 : idx( M.idx > D.maxidx() ? M.idx - D.maxidx() : D.maxidx() - M.idx )
143 {}
144
145 constexpr MultiIndex(const MultiIndex&M, const Power2Alignment&) noexcept
146 : idx( RoundUpToNextHighestPowerOf2( M.idx) )
147 {}
148
149 constexpr MultiIndex(const std::array<index_t, 1>&A)
150 : idx( A[0] )
151 {}
152
153
154public:
157 : idx(0)
158 {}
159
161 constexpr MultiIndex(const Index&I) noexcept
162 : idx(I)
163 {}
164
166 constexpr MultiIndex(const MultiIndex&Midx, const Index&I) noexcept
167 : idx(I)
168 {}
169
174 : idx(lin_idx % Dimens.maxidx() )
175 {}
176
179 {
180 return MultiIndexIterator<1>(*this);
181 }
182
185 {
186 return MultiIndexIterator<1>(*this, *this);
187 }
188
189
190
191static int log2(index_t N) noexcept
192 {
193 if (N&1) return 0;
194 else return -1;
195 }
196
197 constexpr int getSignedOrientation(const MultiIndex&B) const
198 {
199 if (idx<B.idx) return +1;
200 if (idx>B.idx) return -1;
201 return 0;
202 }
203
204 constexpr const Index&operator[](int) const noexcept
205 { return idx; }
206
207 constexpr Index&operator[](int) noexcept
208 { return idx; }
209
210
211 constexpr const Index&maxidx() const noexcept
212 { return idx; }
213
214 constexpr Index&maxidx() noexcept
215 { return idx; }
216
217 constexpr Index size() const noexcept
218 { return idx; }
219
220
221 constexpr MultiIndex&operator+=(const MultiIndex&D) noexcept
222 {
223 idx += D.idx;
224 return *this;
225 }
226
227 constexpr MultiIndex&operator-=(const MultiIndex&D) noexcept
228 {
229 idx -= D.idx;
230 return *this;
231 }
232
233 constexpr MultiIndex operator+(const MultiIndex&D) noexcept
234 {
235 return MultiIndex(idx + D.idx);
236 }
237
238
239
240 friend constexpr MultiIndex clamp(const MultiIndex&M, const MultiIndex&D) noexcept
241 {
242 MultiIndex retval;
243 retval.idx = clamp(M.idx, D.idx);
244 return retval;
245 }
246
247 friend constexpr MultiIndex clamp_m1(const MultiIndex&M, const MultiIndex&D) noexcept
248 {
249 MultiIndex retval;
250 retval.idx = clamp(M.idx, D.idx-1);
251 return retval;
252 }
253
254
255 bool operator==(const MultiIndex&D) const noexcept
256 { return idx == D.idx; }
257
259 bool operator!=(const MultiIndex&D) const noexcept
260 {
261 return idx != D.maxidx();
262 }
263
264 bool inc(const MultiIndex&Dimens, const MultiIndex&Increment) noexcept
265 {
266 idx += Increment.maxidx();
267 if (idx >= Dimens.maxidx() )
268 {
269 idx = Index(0);
270 return false;
271 }
272 return true;
273 }
274
275 bool inc(const MultiIndex&Dimens) noexcept
276 {
277 idx++;
278 if (idx >= Dimens.maxidx() )
279 {
280 idx = Index(0);
281 return false;
282 }
283 return true;
284 }
285
286 Index linear(const MultiIndex&/*Dimens*/) const
287 { return idx; }
288
289 bool isWithin(const MultiIndex&Range) const noexcept
290 {
291// return maxidx()>=0 && maxidx() < Range.maxidx();
292 return maxidx() < Range.maxidx();
293 }
294
295// MSVC GCC G++ SGI C++
296#if defined(_IOSTREAM_) || defined(_GLIBCXX_OSTREAM) || _CPP_IOSTREAM || defined(__SGI_STL_IOSTREAM) || defined(__clang__)
297
298 std::ostream&print(std::ostream&os, char sep) const
299 //{ return os << IntValueTrait<Index>::getValue(idx); }
300 { return os << idx; }
301
303 friend std::ostream&operator<<(std::ostream&os, const MultiIndex&MI)
304 {
305 return MI.print(os, 'x');
306 }
307#endif
308
309
310template <class Functor, Dims_t SuperDims>
311static bool ForEachRecursion(Functor&F, const MultiIndex<SuperDims>&SuperIndex,
312 const MultiIndex&Start, const MultiIndex&End, const MultiIndex&Increment)
313 {
314 for(index_t idx = Start.idx; idx < End.idx; idx += Increment.idx)
315 {
316 MultiIndex<SuperDims+1> SupraIndex(SuperIndex, idx);
317 if (!F(SupraIndex) )
318 return false;
319 }
320 return true;
321 }
322};
323
324
329template <Dims_t Dims>
330 class MultiIndex : public MultiIndex<Dims-1>
331{
332 typedef MultiIndex<Dims-1> base_t;
333
334 index_t idx;
335
336public:
337 typedef index_t value_type;
338
340 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Add&) noexcept
341 : base_t(M,D, Add() )
342 , idx(M.idx + D.maxidx())
343 {}
344
346 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Sub&) noexcept
347 : base_t(M,D, Sub() )
348 , idx(M.idx - D.maxidx())
349 {}
350
352 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Mult&) noexcept
353 : base_t(M,D, Mult() )
354 , idx(M.idx * D.maxidx())
355 {}
356
358 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const Div&)
359 : base_t(M,D, Div() )
360 , idx(M.idx / D.maxidx())
361 {}
362
363 constexpr MultiIndex(unsigned int bits, const ::Eagle::BinaryAnd&) noexcept
364 : base_t(bits, ::Eagle::BinaryAnd() )
365 , idx( bits & (1<<(Dims-1)) ? 1 : 0 )
366 {}
367
368 constexpr MultiIndex(const MultiIndex&M, const MultiIndex&D, const ::Eagle::BinaryAnd&) noexcept
369 : base_t(M,D, ::Eagle::BinaryAnd() )
370 , idx( M.idx > D.maxidx() ? M.idx - D.maxidx() : D.maxidx() - M.idx )
371 {}
372
373 constexpr MultiIndex(const MultiIndex&M, const Power2Alignment&) noexcept
374 : base_t(M, Power2Alignment() )
375 , idx( RoundUpToNextHighestPowerOf2( M.idx) )
376 {}
377
378public:
383 {
384 for(int i=0; i<Dims; i++)
385 (*this)[i] = A[i];
386 }
387
395 {
396 Dims_t i = 0;
397 for(auto I : A)
398 {
399 (*this)[i] = I;
400 i++;
401 if (i>=Dims)
402 break;
403 }
404 }
405
408 {
409 return MultiIndexIterator<Dims>(*this);
410 }
411
414 {
415 return MultiIndexIterator<Dims>(*this, *this);
416 }
417
418
419
420public:
426 {
428 }
429
430 friend MultiIndex bitalign(const MultiIndex&M) noexcept
431 {
432 return MultiIndex(M, Power2Alignment() );
433 }
434
454static MultiIndex BitIndex(unsigned int bits) noexcept
455 {
456 return MultiIndex(bits, ::Eagle::BinaryAnd() );
457 }
458
469static MultiIndex Axis(unsigned int orientation) noexcept
470 {
471 return BitIndex( 1 << orientation );
472 }
473
490 {
491 return linear( MultiIndex(2) );
492 }
493
498static int log2(index_t N) noexcept
499 {
500 if (N & (1<<(Dims-1) ) )
501 return Dims-1;
502
503 return base_t::log2(N);
504 }
505
526 {
527 return log2( BitIndex() );
528 }
529
530 enum
531 {
533 dims = Dims,
534
536 SIZE = Dims
537 };
538
548 constexpr int getSignedOrientation(const MultiIndex&B) const
549 {
550 if (idx<B.idx) return +Dims;
551 if (idx>B.idx) return -int(Dims);
552 return subidx().getSignedOrientation(B.subidx() );
553 }
554
557 : idx(0)
558 {}
559
561 explicit constexpr MultiIndex(const index_t&I) noexcept
562 : base_t(I), idx(I)
563 {}
564
567 : base_t(Midx), idx(I)
568 {}
569
576 {
577 for(int i=0, k=0; i<Dims; i++)
578 {
579 if (i==SliceDirection)
580 (*this)[i] = Slice;
581 else
582 {
583 (*this)[i] = m[k];
584 k++;
585 }
586 }
587 }
588
611 , idx( (lin_idx / Dimens.subidx().size()) % Dimens.maxidx() )
612 {}
613
615 constexpr const MultiIndex<Dims-1>&subidx() const noexcept
616 { return *this; }
617
619 constexpr MultiIndex<Dims-1>&subidx() noexcept
620 { return *this; }
621
627 constexpr const index_t&operator[](std::size_t i) const
628 { return (i>=Dims-1) ? idx : subidx()[i]; }
629
633 constexpr index_t&operator[](std::size_t i) noexcept
634 { return (i>=Dims-1) ? idx : subidx()[i]; }
635
636
642
643 constexpr const index_t&maxidx() const noexcept
644 { return idx; }
645
646 constexpr index_t&maxidx() noexcept
647 { return idx; }
648
651 {
652 return idx*subidx().size();
653 }
654
656 constexpr bool operator!=(const MultiIndex&D) const noexcept
657 {
658 return idx != D.maxidx() || subidx() != D.subidx() ;
659 }
660
662 constexpr bool operator==(const MultiIndex&M) const noexcept
663 {
664 return idx == M.maxidx() && subidx() == M.subidx() ;
665 }
666
669 {
670 idx += D.maxidx();
671 subidx() += D.subidx();
672 return *this;
673 }
674
677 {
678 idx -= D.maxidx();
679 subidx() -= D.subidx();
680 return *this;
681 }
682
683/*
684 friend MultiIndex clamp(const MultiIndex&M, const MultiIndex&D)
685 {
686 MultiIndex retval;
687 retval.idx = clamp(M.idx , D.idx);
688 retval.subidx() = clamp(M.subidx(), D.subidx());
689 return retval;
690 }
691
692 friend MultiIndex clamp_m1(const MultiIndex&M, const MultiIndex&D)
693 {
694 MultiIndex retval;
695 retval.idx = clamp_m1(M.idx , D.idx-1);
696 retval.subidx() = clamp_m1(M.subidx(), D.subidx());
697 return retval;
698 }
699*/
700
706 bool inc(const MultiIndex&Dimens) noexcept
707 {
708 if ( subidx().inc(Dimens) )
709 return true;
710
711 idx ++;
712 if ( idx >= Dimens.maxidx() )
713 {
714 idx = index_t(0);
715 return false;
716 }
717 return true;
718 }
719
726 bool inc(const MultiIndex&Dimens, const MultiIndex&Increment) noexcept
727 {
728 if (subidx().inc( Dimens, Increment ) )
729 return true;
730
731 idx += Increment.maxidx();
732 if ( idx >= Dimens.maxidx() )
733 {
734 idx = index_t(0);
735 return false;
736 }
737 return true;
738 }
739
743inline index_t linear(const MultiIndex&Dimens) const
744#if 1
745 ;
746#else
747 {
748#ifndef NDEBUG
749 if (!(idx >= 0 && idx < Dimens.maxidx() ))
750 {
752 assert(idx >= 0 && idx < Dimens.maxidx() );
753 }
754#endif
755 /*
756 Pretty sure, this formula can be optimized.
757 The size() call on the subdimension recursively multiplies
758 its elements, but this could be moved into the summation/
759 multiplication recursive call.
760 */
761 index_t L = Dimens.subidx().size();
762 return idx * L + subidx().linear( Dimens.subidx() );
763 }
764#endif
765
766
767// MSVC GCC G++ SGI C++
768#if defined(_IOSTREAM_) || defined(_GLIBCXX_OSTREAM) || _CPP_IOSTREAM || defined(__SGI_STL_IOSTREAM) || defined(__clang__)
769
770 std::ostream&print(std::ostream&os, char sep) const
771 {
772 base_t::print(os, sep);
773 return os << sep << idx;
774 }
775
777 friend std::ostream&operator<<(std::ostream&os, const MultiIndex&MI)
778 {
779 return MI.print(os, 'x');
780 }
781#endif
782
784 bool isWithin(const MultiIndex&Range) const noexcept
785 {
786 // return maxidx()>=0 && maxidx() < Range.maxidx() &&
787 return maxidx() < Range.maxidx() &&
788 subidx().isWithin( Range );
789 }
790
792 bool operator<(const MultiIndex&Range) const noexcept
793 {
794 return isWithin( Range );
795 }
796
798 bool operator>(const MultiIndex&Range) const noexcept
799 {
800 return !isWithin( Range );
801 }
802
804 MultiIndex operator+(const MultiIndex&D) const noexcept
805 { return MultiIndex(*this, D, Add() ); }
806
808 MultiIndex operator-(const MultiIndex&D) const noexcept
809 { return MultiIndex(*this, D, Sub() ); }
810
812 MultiIndex operator*(const MultiIndex&D) const noexcept
813 { return MultiIndex(*this, D, Mult() ); }
814
816 MultiIndex operator/(const MultiIndex&D) const noexcept
817 { return MultiIndex(*this, D, Div() ); }
818
819
830 {
831 const MultiIndex&M = *this;
832 if (i==0) return M;
833
834 if (i<0)
835 {
836 if (M[-i-1] == 0)
837 return M;
838
839 return M - MultiIndex::Axis(-i-1);
840 }
841 else
842 return M + MultiIndex::Axis( i-1);
843 }
844
850 friend MultiIndex operator|(const MultiIndex&M, int i)
851 {
852 if (i==0) return M;
853
854 if (i<0)
855 return M + MultiIndex::Axis(-i-1);
856 else
857 {
858 if (M[-i-1] == 0)
859 return M;
860
861 return M - MultiIndex::Axis( i-1);
862 }
863 }
864
865protected:
866
867template <class Functor, Dims_t SuperDims>
868static bool ForEachRecursion(Functor&F, const MultiIndex<SuperDims>&SuperIndex,
870 {
871 for(index_t idx = Start.idx; idx < End.idx; idx += Increment.idx)
872 {
875 return false;
876 }
877 return true;
878 }
879
880public:
881
882template <class Functor>
883static bool ForEach(Functor&F, const MultiIndex&Start, const MultiIndex&End, const MultiIndex&Increment = MultiIndex(1) )
884 {
885 for(index_t idx = Start.idx; idx < End.idx; idx += Increment.idx)
886 {
887 MultiIndex<1> SupraIndex(idx);
888 if (!MultiIndex<Dims-1>::ForEachRecursion(F, SupraIndex, Start, End, Increment) )
889 return false;
890 }
891 return true;
892 }
893};
894
895
896inline constexpr MultiIndex<1> MIndex(index_t i0)
897{
898 return {i0};
899//MultiIndex<1> m = i0;
900// return m;
901}
902
903inline constexpr MultiIndex<2> MIndex(index_t i0, index_t i1)
904{
905 return {i0, i1};
906
907//MultiIndex<2> m; m = i0, i1;
908// return m;
909}
910
911inline constexpr MultiIndex<3> MIndex(index_t i0, index_t i1, index_t i2)
912{
913 return {i0, i1, i2};
914//MultiIndex<3> m; m = i0, i1, i2;
915// return m;
916}
917
918inline constexpr MultiIndex<4> MIndex(index_t i0, index_t i1, index_t i2, index_t i3)
919{
920 return {i0, i1, i2, i3};
921//MultiIndex<4> m; m = i0, i1, i2, i3;
922// return m;
923}
924
925// MSVC GCC G++ SGI C++
926#if defined(_IOSTREAM_) || defined(_GLIBCXX_OSTREAM) || _CPP_IOSTREAM || defined(__SGI_STL_IOSTREAM) || defined(__clang__)
927template <Dims_t Dims>
928 inline std::ostream&operator<<(std::ostream&os, const MultiIndex<Dims>&M)
929{
930 return M.print( os<<'[', ',') << ']' ;
931}
932#endif
933
934
939template <Dims_t Dims>
941{
943
944 for(Dims_t i=0; i<Dims; i++)
945 result[i] = double(Divisor[i])/Dividend[i];
946
947 return result;
948}
949
950
969template <class VectorType, class Domain, class scalar_t>
974{
976 result = V;
977
978constexpr Dims_t DIMS = VectorType::SIZE;
979
980 for(Dims_t i=0; i<DIMS; i++)
981 {
983
984 if (divisor > Stride[i])
985 result[i] /= divisor - Stride[i];
986
987 }
988
989 return result;
990}
991
1006template <class VectorType, class Domain, class scalar_t>
1011{
1013 result = V;
1014
1015constexpr Dims_t DIMS = VectorType::SIZE;
1016
1017 for(Dims_t i=0; i<DIMS; i++)
1018 {
1020
1021 if (divisor > Stride[i])
1022 result[i] /= divisor - Stride[i];
1023 else
1024 result[i] = 0;
1025
1026 }
1027
1028 return result;
1029}
1030
1031template <Dims_t Dims>
1035{
1037 for(Dims_t i=0; i<Dims; i++)
1038 {
1039 if (I[i]>CompareValue[i])
1040 retval[i] = Yes[i];
1041 }
1042 return retval;
1043}
1044
1045
1046
1051template <Dims_t Dims>
1053{
1054 return MultiIndex<Dims>(C) + I;
1055}
1056
1057
1062template <Dims_t Dims>
1064{
1065 return I + MultiIndex<Dims>(C);
1066}
1067
1069template <Dims_t Dims, class Int>
1071{
1073
1074 for(Dims_t i=0; i<Dims; i++)
1075 M[i] *= Factor;
1076
1077 return M;
1078}
1079
1081template <Dims_t Dims, class Int>
1082inline MultiIndex<Dims>&operator*=(MultiIndex<Dims>&M, Int Factor)
1083{
1084 for(Dims_t i=0; i<Dims; i++)
1085 M[i] *= Factor;
1086
1087 return M;
1088}
1089
1091template <Dims_t Dims, class Int>
1092inline MultiIndex<Dims> operator/(const MultiIndex<Dims>&MIn, Int Factor)
1093{
1094MultiIndex<Dims> M = MIn;
1095
1096 for(Dims_t i=0; i<Dims; i++)
1097 M[i] /= Factor;
1098
1099 return M;
1100}
1101
1103template <Dims_t Dims, class Int>
1104inline MultiIndex<Dims>&operator/=(MultiIndex<Dims>&M, Int Factor)
1105{
1106 for(Dims_t i=0; i<Dims; i++)
1107 M[i] /= Factor;
1108
1109 return M;
1110}
1111
1112
1117template <Dims_t Dims>
1119{
1121 for(Dims_t i=0; i<Dims; i++)
1122 m[i] = a[i]*I[i];
1123
1124 return m;
1125}
1126
1131template <Dims_t Dims>
1133{
1135 for(Dims_t i=0; i<Dims; i++)
1136 m[i] = I[i]*a[i];
1137
1138 return m;
1139}
1140
1145template <Dims_t Dims>
1147{
1149 for(Dims_t i=0; i<Dims; i++)
1150 m[i] = a[i]/I[i];
1151
1152 return m;
1153}
1154
1159template <Dims_t Dims>
1161{
1162 for(Dims_t i=0; i<Dims; i++)
1163 a[i] /= I[i];
1164
1165 return a;
1166}
1167
1172template <Dims_t Dims>
1174{
1175 for(Dims_t i=0; i<Dims; i++)
1176 a[i] *= I[i];
1177
1178 return a;
1179}
1180
1181
1182
1186template <Dims_t Dims>
1187inline FixedArray<int, Dims> MultiIndexToFixedArray(const MultiIndex<Dims>&Value)
1188{
1190
1191 for(Dims_t i=0; i<Dims; i++)
1192 result[i] = Value[i];
1193
1194 return result;
1195}
1196
1201template <Dims_t Dims>
1202inline MultiIndex<Dims> FixedArrayToMultiIndex(const FixedArray<int, Dims>&Value)
1203{
1204MultiIndex<Dims> result;
1205
1206 for(Dims_t i=0; i<Dims; i++)
1207 result[i] = Value[i];
1208
1209 return result;
1210}
1211
1215template <Dims_t Dims>
1216inline MultiIndex<Dims> minMultiIndex(const MultiIndex<Dims>&A, const MultiIndex<Dims>&B)
1217{
1218MultiIndex<Dims> result;
1219
1220 for(Dims_t i=0; i<Dims; i++)
1221 {
1222 result[i] = A[i]<B[i] ? A[i] : B[i];
1223 }
1224 return result;
1225}
1226
1227
1231template <Dims_t Dims>
1232inline MultiIndex<Dims> maxMultiIndex(const MultiIndex<Dims>&A, const MultiIndex<Dims>&B)
1233{
1234MultiIndex<Dims> result;
1235
1236 for(Dims_t i=0; i<Dims; i++)
1237 {
1238 result[i] = A[i]>B[i] ? A[i] : B[i];
1239 }
1240 return result;
1241}
1242
1243
1244
1245#if 0
1250template <Dims_t Dims>
1251 inline FixedArray<double, Dims> Modulo(double*a, double range=1.0)
1252 {
1253 FixedArray<double, Dims> m;
1254 for(Dims_t i=0; i<Dims; i++)
1255 m[i] = fmod(a[i] , range);
1256 return m;
1257 }
1258
1259
1264template <Dims_t Dims>
1265 inline FixedArray<double, Dims> Modulo(double*a, double range=1.0)
1266 {
1267 FixedArray<double, Dims> m;
1268 for(Dims_t i=0; i<Dims; i++)
1269 m[i] = fmod(a[i] , range);
1270 return m;
1271 }
1272
1277template <Dims_t Dims>
1278 inline FixedArray<double, Dims> Modulo(const FixedArray<double, Dims>&a, const FixedArray<double, Dims>&range)
1279 {
1280 MultiIndex<Dims, double> m;
1281 for(Dims_t i=0; i<Dims; i++)
1282 m[i] = fmod(a[i] , range[i]);
1283 return m;
1284 }
1285#endif
1286
1287} // namespace Fiber
1288
1289namespace std
1290{
1291
1292template <Fiber::Dims_t Dims>
1293inline string to_string(const Fiber::MultiIndex<Dims>&M)
1294{
1295Fiber::Dims_t i = 0;
1296
1297string retval = "[";
1298
1299 for(; i<Dims-1; i++)
1300 retval += std::to_string(M[i]) + "x";
1301
1302 retval += std::to_string(M[i]) + "]";
1303
1304 return retval;
1305}
1306
1307} // namespace std
1308
1309
1310#ifdef ENABLE_MEMCORE_ASSERT
1311#include <memcore/Verbose.hpp>
1312#endif
1313
1314namespace Fiber
1315{
1316
1317template <Dims_t Dims>
1319{
1320#ifndef NDEBUG
1321 if (!(idx >= 0 && idx < Dimens.maxidx() ))
1322 {
1323#ifdef ENABLE_MEMCORE_ASSERT
1324 Verbose(0) << "Index " << idx << " beyond allowed maximum " << Dimens.maxidx() << " out of " << Dimens;
1325 Assert(idx >= 0 && idx < Dimens.maxidx() );
1326#endif
1327 assert(idx >= 0 && idx < Dimens.maxidx() );
1328 }
1329#endif
1330 /*
1331 Pretty sure, this formula can be optimized.
1332 The size() call on the subdimension recursively multiplies
1333 its elements, but this could be moved into the summation/
1334 multiplication recursive call.
1335 */
1336index_t L = Dimens.subidx().size();
1337return idx * L + subidx().linear( Dimens.subidx() );
1338}
1339
1340
1341}
1342
1343
1344#endif // __Fiber_MultiIndex_HPP
constexpr complex< _Tp > & operator*=(const _Tp &)
constexpr complex< _Tp > operator/(const complex< _Tp > &__x, const complex< _Tp > &__y)
constexpr complex< _Tp > & operator/=(const _Tp &)
basic_ostream< char > ostream
constexpr const _Tp & clamp(const _Tp &__val, const _Tp &__lo, const _Tp &__hi)
An iterator with an optional DataCreator, which is just a class to intercept creation of data along a...
Definition CreativeIterator.hpp:34
MultiIndexIterator< 1 > end() const
End a ranged loop.
Definition MultiIndex.hpp:184
constexpr MultiIndex(const Index &I) noexcept
Initialize highest index.
Definition MultiIndex.hpp:161
bool operator!=(const MultiIndex &D) const noexcept
inequality comparision operator
Definition MultiIndex.hpp:259
constexpr MultiIndex(const Index &lin_idx, const MultiIndex &Dimens, const CreateFromLinear &)
Multidimensional Index - a linear Index with Dimensions.
Definition MultiIndex.hpp:173
constexpr MultiIndex(const MultiIndex &Midx, const Index &I) noexcept
Multidimensional index as product of subdimension and index.
Definition MultiIndex.hpp:166
MultiIndexIterator< 1 > begin() const
Begin a ranged loop.
Definition MultiIndex.hpp:178
constexpr MultiIndex() noexcept
Default constructor.
Definition MultiIndex.hpp:156
A recursively defined multidimensional index.
Definition MultiIndex.hpp:331
constexpr index_t & operator[](std::size_t i) noexcept
Indexing operator to access values for each dimension.
Definition MultiIndex.hpp:633
MultiIndex operator+(const MultiIndex &D) const noexcept
Add two multidimensional indices.
Definition MultiIndex.hpp:804
friend MultiIndex distance(const MultiIndex &M0, const MultiIndex &M1)
Compute the distance between two multiindices, which is always positive in each index (in contrast to...
Definition MultiIndex.hpp:425
index_t BitIndex() const
From this given multiindex which is supposed to have index values of either 0 or 1 in each direction,...
Definition MultiIndex.hpp:489
constexpr const MultiIndex< Dims-1 > & subidx() const noexcept
Return associated constant dimensionator of one dimension less.
Definition MultiIndex.hpp:615
index_t linear(const MultiIndex &Dimens) const
Compute the linear index from the given dimensionator.
Definition MultiIndex.hpp:1318
constexpr MultiIndex(const index_t &I) noexcept
Initialize all indices with same value.
Definition MultiIndex.hpp:561
constexpr MultiIndex(const MultiIndex< Dims-1 > &Midx, const index_t &I) noexcept
Multidimensional index as tensor product of subdimension and index.
Definition MultiIndex.hpp:566
constexpr MultiIndex(const std::array< index_t, Dims > &A)
Construct from std::array of same size.
Definition MultiIndex.hpp:382
bool inc(const MultiIndex &Dimens) noexcept
Increment the current index, if it is larger than the extent a given in the Dimensions parameter,...
Definition MultiIndex.hpp:706
MultiIndex operator&(int i) const
Shortcut operator to compute the MultiIndex that is just one step aside in the direction as specified...
Definition MultiIndex.hpp:829
MultiIndexIterator< Dims > begin() const
Begin a ranged loop.
Definition MultiIndex.hpp:407
constexpr MultiIndex< Dims-1 > & subidx() noexcept
Return associated dimensionator of one dimension less.
Definition MultiIndex.hpp:619
constexpr MultiIndex(const index_t &lin_idx, const MultiIndex &Dimens, const CreateFromLinear &)
Create multidimensional index from one-dimensional index, given the multidimensional dimension on whe...
Definition MultiIndex.hpp:609
friend MultiIndex operator|(const MultiIndex &M, int i)
Axis index subtraction operator, similar to adding an integer to a multidimensional index,...
Definition MultiIndex.hpp:850
constexpr MultiIndex(const std::initializer_list< index_t > &A)
Construct from set of indices.
Definition MultiIndex.hpp:394
MultiIndex & operator-=(const MultiIndex &D) noexcept
component-wise self-subtraction
Definition MultiIndex.hpp:676
constexpr int getSignedOrientation(const MultiIndex &B) const
Returns the dimension, starting with 1, in which this multidimensional index is non-zero.
Definition MultiIndex.hpp:548
bool isWithin(const MultiIndex &Range) const noexcept
Check whether this multidimensional index is within the specified domain.
Definition MultiIndex.hpp:784
Eagle::Assignment< MultiIndex, 0 > operator=(const index_t &i)
Assignment via comma operator.
Definition MultiIndex.hpp:638
MultiIndexIterator< Dims > end() const
End a ranged loop.
Definition MultiIndex.hpp:413
MultiIndex operator-(const MultiIndex &D) const noexcept
Subtract multidimensional indices.
Definition MultiIndex.hpp:808
constexpr MultiIndex() noexcept
Default constructor (initialization by zero)
Definition MultiIndex.hpp:556
bool operator<(const MultiIndex &Range) const noexcept
Check if the current multiindex is smaller than the range.
Definition MultiIndex.hpp:792
static int log2(index_t N) noexcept
Logarithm of basis 2 where we expect a maximum value of 1<<(Dims-1) here.
Definition MultiIndex.hpp:498
constexpr const index_t & operator[](std::size_t i) const
Indexing operator to access values for each dimension.
Definition MultiIndex.hpp:627
MultiIndex & operator+=(const MultiIndex &D) noexcept
component-wise self-addition
Definition MultiIndex.hpp:668
MultiIndex operator/(const MultiIndex &D) const noexcept
Divide multidimensional indices component-wise.
Definition MultiIndex.hpp:816
constexpr bool operator!=(const MultiIndex &D) const noexcept
inequality comparision operator
Definition MultiIndex.hpp:656
MultiIndex operator*(const MultiIndex &D) const noexcept
Multiply multidimensional indices component-wise.
Definition MultiIndex.hpp:812
constexpr MultiIndex(const MultiIndex< Dims-1 > &m, const index_t &Slice, int SliceDirection)
Multidimensional index as product of subdimension and index for a given slice dimension (create globa...
Definition MultiIndex.hpp:575
@ SIZE
Export an SIZE enum for treatment like an FixedArray.
Definition MultiIndex.hpp:536
@ dims
The dimension of this multidimensional index.
Definition MultiIndex.hpp:533
static MultiIndex BitIndex(unsigned int bits) noexcept
Multidimensional bit indices, that are zero or one in each of the directions as specified by the bits...
Definition MultiIndex.hpp:454
index_t size() const noexcept
Recursive function to compute the entire number of elements.
Definition MultiIndex.hpp:650
bool operator>(const MultiIndex &Range) const noexcept
Check if the current multiindex is larger than the range.
Definition MultiIndex.hpp:798
constexpr MultiIndex(const MultiIndex &M, const MultiIndex &D, const Sub &) noexcept
Computational constructor for subtracting two multidimensional indices.
Definition MultiIndex.hpp:346
constexpr bool operator==(const MultiIndex &M) const noexcept
comparison operator
Definition MultiIndex.hpp:662
constexpr MultiIndex(const MultiIndex &M, const MultiIndex &D, const Add &) noexcept
Computational constructor for adding two multidimensional indices.
Definition MultiIndex.hpp:340
index_t Orientation() const noexcept
Given a MultiIndex that only contains one element of value 1, all others being zero (such as one crea...
Definition MultiIndex.hpp:525
bool inc(const MultiIndex &Dimens, const MultiIndex &Increment) noexcept
Increment the current index by a certain increment.
Definition MultiIndex.hpp:726
constexpr MultiIndex(const MultiIndex &M, const MultiIndex &D, const Div &)
Computational constructor for component-wise division of two multidimensional indices.
Definition MultiIndex.hpp:358
constexpr MultiIndex(const MultiIndex &M, const MultiIndex &D, const Mult &) noexcept
Computational constructor for component-wise multiplication of two multidimensional indices.
Definition MultiIndex.hpp:352
static MultiIndex Axis(unsigned int orientation) noexcept
Return a MultiIndex that points just in the given orientation.
Definition MultiIndex.hpp:469
Information per time slice, mainly a set of Grid objects that are accessed via GridID objects.
Definition Slice.hpp:36
Anemone_Context_t operator<<(Anemone &A, VRenderContext &VC)
constexpr FixedArray< double, Dims > div(const MultiIndex< Dims > &Divisor, const MultiIndex< Dims > &Dividend)
Compute the rational division of two MultiIndex es.
Definition MultiIndex.hpp:940
MultiIndex< Dims > operator+(index_t C, const MultiIndex< Dims > &I)
Add constant plus multi-index.
Definition MultiIndex.hpp:1052
FixedArray< double, Dims > operator*(const FixedArray< double, Dims > &a, const MultiIndex< Dims > &I)
Component-wise multiplication.
Definition MultiIndex.hpp:1118
Eagle::DomainVector< VectorType, Domain, scalar_t > CellSize0(const Eagle::DomainVector< VectorType, Domain, scalar_t > &V, const MultiIndex< VectorType::SIZE > &Dividend, const MultiIndex< VectorType::SIZE > &Stride=MultiIndex< VectorType::SIZE >(1))
Compute the size of a "cell" given a distance between a set of points.
Definition MultiIndex.hpp:1008
FixedArray< double, Dims > & operator*=(FixedArray< double, Dims > &a, const MultiIndex< Dims > &I)
Component-wise multiplication.
Definition MultiIndex.hpp:1173
FixedArray< double, Dims > operator*(const MultiIndex< Dims > &I, const FixedArray< double, Dims > &a)
Component-wise multiplication.
Definition MultiIndex.hpp:1132
MultiIndex< Dims > operator+(const MultiIndex< Dims > &I, index_t C)
Add multi-index plus constant.
Definition MultiIndex.hpp:1063
FixedArray< double, Dims > operator/(const FixedArray< double, Dims > &a, const MultiIndex< Dims > &I)
Component-wise division.
Definition MultiIndex.hpp:1146
FixedArray< double, Dims > & operator/=(FixedArray< double, Dims > &a, const MultiIndex< Dims > &I)
Component-wise division.
Definition MultiIndex.hpp:1160
Eagle::DomainVector< VectorType, Domain, scalar_t > CellSize(const Eagle::DomainVector< VectorType, Domain, scalar_t > &V, const MultiIndex< VectorType::SIZE > &Dividend, const MultiIndex< VectorType::SIZE > &Stride=MultiIndex< VectorType::SIZE >(1))
Compute the size of a "cell" given a distance between a set of points.
Definition MultiIndex.hpp:971
Column< C, Value > operator*(const Column< C, Value > &A, double V)
Operator<'-'> Sub
Operator<'+'> Add
Operator<' *'> Mult
Operator<'/'> Div
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2
constexpr index_t RoundUpToNextHighestPowerOf2(index_t v)
Align a value to the next fitting power of 2.
Definition Index.hpp:43
IndexTypeConfig< sizeof(void *)>::index_t index_t
Define the index type as according to the size of a pointer, i.e.
Definition Index.hpp:22
void breakpoint(const char *Description)
std::string to_string(const span< char > &s)
STL namespace.
string to_string(const Eagle::FixedArray< ElementType, N > &A, const char *OpenBrace="{", const char *CloseBrace="}", const char *Separator=",")
A helper class to be used for multilinear index construction.
Definition MultiIndex.hpp:54
Definition MultiIndex.hpp:77
Definition MultiIndex.hpp:56