CNORXZ
Container with Native Operation Routines and Expressions
Loading...
Searching...
No Matches
yrange.cc
Go to the documentation of this file.
1// -*- C++ -*-
12#include "ranges/ranges.h"
13#include "array/array.h"
14
15namespace CNORXZ
16{
17 /*=======================+
18 | YIndex (private) |
19 +=======================*/
20
21 inline DPack YIndex::mkIndices() const
22 {
23 Vector<XIndexPtr> o(mRange->dim(), nullptr);
24 for(SizeT i = 0; i != mRange->dim(); ++i){
25 auto rp = mRange->sub(i);
26 CXZ_ASSERT(rp != nullptr, "subranges not available");
27 o[i] = rp->begin().xptr();
28 }
29 return DPack(std::move(o));
30 }
31
32 inline Vector<SizeT> YIndex::mkFormat() const
33 {
34 Vector<SizeT> o(mIs.size());
35 SizeT b = 1;
36 for(SizeT i = o.size(); i != 0; --i){
37 const SizeT j = i-1;
38 o[j] = b;
39 b *= mIs[j]->pmax().val();
40 }
41 return o;
42 }
43
44 inline Vector<SizeT> YIndex::mkLexFormat() const
45 {
46 Vector<SizeT> o(mIs.size());
47 SizeT b = 1;
48 for(SizeT i = o.size(); i != 0; --i){
49 const SizeT j = i-1;
50 o[j] = b;
51 b *= mIs[j]->lmax().val();
52 }
53 return o;
54 }
55
56 inline Vector<RangePtr> YIndex::mkRangeVec(const Vector<XIndexPtr>& is) const
57 {
58 Vector<RangePtr> o(is.size());
59 std::transform(is.begin(), is.end(), o.begin(), [](const auto& e) { return e->range(); });
60 return o;
61 }
62
63 inline void YIndex::mkPos()
64 {
65 mLex = 0;
66 IB::mPos = 0;
67 for(SizeT i = 0; i != dim(); ++i){
68 mLex += mIs[i]->lex() * mLexFormat[i].val();
69 IB::mPos += mIs[i]->pos() * mFormat[i].val();
70 }
71 }
72
73 inline void YIndex::up(SizeT i)
74 {
75 auto& idx = mIs[i];
76 // it is guaranteed that the last accessible position
77 // is one less than the max position (=end)
78 if(i != 0 and idx->lex() == idx->lmax().val()-1){
79 IB::mPos -= mFormat[i].val() * idx->pos();
80 mLex -= mLexFormat[i].val() * idx->lex();
81 (*idx) = 0;
82 up(i-1);
83 return;
84 }
85 IB::mPos += mFormat[i].val();
86 mLex += mLexFormat[i].val();
87 ++(*idx);
88 }
89
90 inline void YIndex::down(SizeT i)
91 {
92 auto& idx = mIs[i];
93 if(i != 0 and idx->pos() == 0){
94 (*idx) = idx->lmax().val()-1;
95 IB::mPos += mFormat[i].val() * idx->pos();
96 mLex += mLexFormat[i].val() * idx->lex();
97 down(i-1);
98 return;
99 }
100 IB::mPos -= mFormat[i].val();
101 mLex -= mLexFormat[i].val();
102 --(*idx);
103 }
104
105 inline decltype(auto) YIndex::mkIFor(SizeT i, const DXpr<None>& xpr, NoF&& f) const
106 {
107 if(i == mIs.size()-1){
108 return mIs[i]->ifor( xpr, std::forward<NoF>(f) );
109 }
110 else {
111 auto f1 = f;
112 auto f2 = f1;
113 return mIs[i]->ifor( mkIFor(i+1, xpr, std::move(f1)), std::move(f2) );
114 }
115 }
116
117 inline SizeT YIndex::mkPMax() const
118 {
119 SizeT o = 0;
120 for(SizeT i = 0; i != mIs.size(); ++i){
121 o += (mIs[i]->pmax().val()-1) * mFormat[i].val();
122 }
123 return o+1;
124 }
125
126 inline SizeT YIndex::mkLMax() const
127 {
128 return std::accumulate(mIs.all().begin(), mIs.all().end(),1,
129 [](const auto& res, const auto& el) { return res * el->lmax().val(); } );
130 }
131
132
133 /*=============+
134 | YIndex |
135 +=============*/
136
139 mRange(rangeCast<YRange>(i.range())),
140 mIs(mkIndices()),
141 mFormat(i.mFormat),
142 mLexFormat(i.mLexFormat),
143 mPMax(mkPMax()),
144 mLMax(mkLMax())
145 {
146 *this = i.lex();
147 }
148
150 {
152 mRange = rangeCast<YRange>(i.range());
153 mIs = mkIndices();
154 mFormat = i.mFormat;
155 mLexFormat = i.mLexFormat;
156 mPMax = mkPMax();
157 mLMax = mkLMax();
158 return *this = i.lex();
159 }
160
163 mRange(std::dynamic_pointer_cast<YRange>(yrange(mkRangeVec(is)))),
164 mIs(is),
165 mFormat(mkFormat()),
166 mLexFormat(mkLexFormat()),
167 mPMax(mkPMax()),
168 mLMax(mkLMax())
169 {
170 mkPos();
171 }
172
175 mRange(std::dynamic_pointer_cast<YRange>(yrange(mkRangeVec(is)))),
176 mIs(is),
177 mFormat(bs),
178 mLexFormat(mkLexFormat()),
179 mPMax(mkPMax()),
180 mLMax(mkLMax())
181 {
182 mkPos();
183 }
184
187 mRange(rangeCast<YRange>(range)),
188 mIs(mkIndices()),
189 mFormat(mkFormat()),
190 mLexFormat(mkLexFormat()),
191 mPMax(mkPMax()),
192 mLMax(mkLMax())
193 {
194 *this = lexpos;
195 }
196
197 YIndex::YIndex(const RangePtr& range, const YFormat& bs, SizeT lexpos) :
199 mRange(rangeCast<YRange>(range)),
200 mIs(mkIndices()),
201 mFormat(bs),
202 mLexFormat(mkLexFormat()),
203 mPMax(mkPMax()),
204 mLMax(mkLMax())
205 {
206 *this = lexpos;
207 }
208
210 {
211 if(lexpos >= lmax().val()){
212 mLex = lmax().val();
213 IB::mPos = pmax().val();
214 return *this;
215 }
216 mLex = lexpos;
217 IB::mPos = 0;
218 for(SizeT i = 0; i != mIs.size(); ++i){
219 *mIs[i] = (lex() / mLexFormat[i].val()) % mIs[i]->lmax().val();
220 IB::mPos += mFormat[i].val() * mIs[i]->pos();
221 }
222 return *this;
223 }
224
226 {
227 if(lex() == lmax().val()-1){
228 return *this = lmax().val();
229 }
230 if(lex() != lmax().val()){
231 up(mIs.size()-1);
232 }
233 return *this;
234 }
235
237 {
238 if(lex() == lmax().val()){
239 return *this = lmax().val()-1;
240 }
241 if(lex() != 0){
242 down(mIs.size()-1);
243 }
244 return *this;
245 }
246
248 {
249 YIndex o(*this);
250 return o += n;
251 }
252
254 {
255 YIndex o(*this);
256 return o -= n;
257 }
258
260 {
261 return lex() - i.lex();
262 }
263
265 {
266 if(static_cast<Int>(lex()) + n < 0){
267 return *this = 0;
268 }
269 return *this = static_cast<Int>(lex()) + n;
270 }
271
273 {
274 if(static_cast<Int>(lex()) - n < 0){
275 return *this = 0;
276 }
277 return *this = static_cast<Int>(lex()) - n;
278 }
279
281 {
282 return mLex;
283 }
284
286 {
287 return mPMax;
288 }
289
291 {
292 return mLMax;
293 }
294
296 {
297 return IndexId<0>(this->ptrId());
298 }
299
301 {
302 return meta();
303 }
304
306 {
307 return mRange->dim();
308 }
309
311 {
312 return mRange;
313 }
314
316 {
317 SizeT o = 0;
318 for(SizeT i = 0; i != mIs.size(); ++i){
319 const auto u = mIs[i]->stepSize(id) * mFormat[i];
320 o += u.val();
321 }
322 return UPos(o);
323 }
324
326 {
327 const String blim = "[";
328 const String elim = "]";
329 const String dlim = ",";
330 return blim +
331 std::accumulate(std::next(mIs.all().begin()), mIs.all().end(), mIs[0]->stringMeta(),
332 [&](const auto& s, const auto& e)
333 { return s + dlim + e->stringMeta(); } ) +
334 elim;
335 }
336
338 {
339 Vector<DType> v(mIs.size());
340 std::transform(mIs.all().begin(), mIs.all().end(), v.begin(),
341 [](const auto& x) { return x->meta(); });
342 return v;
343 }
344
346 {
347 CXZ_ASSERT(meta.size() == mIs.size(), "input meta size ("
348 << meta.size() << ") different from expected size ("
349 << mIs.size() << ")");
350 for(SizeT i = 0; i != mIs.size(); ++i){
351 mIs[i]->at(meta[i]);
352 }
353 mkPos();
354 return *this;
355 }
356
358 {
359 return mkIFor(0, xpr, std::forward<NoF>(f));
360 }
361
363 {
364 mIs = i->pack();
365 mkPos();
366 return *this;
367 }
368
370 {
371 mkPos();
372 return *this;
373 }
374
375 const DPack& YIndex::pack() const
376 {
377 return mIs;
378 }
379
381 {
382 CXZ_ASSERT(dim() == last.dim(), "end index has different number of dimensions ("
383 << last.dim() << ") than begin index (" << dim() << ")");
385 for(SizeT i = 0; i != dim(); ++i){
386 v[i] = mIs[i]->prange( last.pack()[i] );
387 }
388 return YRangeFactory(v).create();
389 }
390
392 {
394 SizeT osize = 0;
395 for(SizeT j = 0; j != dfv.size(); ++j){
396 dfv[j] = mIs[j]->deepFormat();
397 std::for_each(dfv[j].begin(), dfv[j].end(),
398 [&](SizeT& x) { x *= mFormat[j].val(); } );
399 osize += dfv[j].size();
400 }
402 SizeT off = 0;
403 for(SizeT j = 0; j != dfv.size(); ++j){
404 std::copy(dfv[j].begin(), dfv[j].end(), o.begin()+off);
405 off += dfv[j].size();
406 }
407 return o;
408 }
409
411 {
413 SizeT osize = 0;
414 for(SizeT j = 0; j != dmv.size(); ++j){
415 dmv[j] = mIs[j]->deepMax();
416 osize += dmv[j].size();
417 }
419 SizeT off = 0;
420 for(SizeT j = 0; j != dmv.size(); ++j){
421 std::copy(dmv[j].begin(), dmv[j].end(), o.begin()+off);
422 off += dmv[j].size();
423 }
424 return o;
425 }
426
428 {
429 // f: input format
430 // s: input sizes
431 CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()");
432 if(f.size() == 1){
433 CXZ_ASSERT(s[0] == lmax().val(), "got inconsistent size; expeected "
434 << lmax().val() << ", got " << s[0]);
435 return *this;
436 }
437
438 SizeT j = 0;
439 SizeT j0 = 0;
440 SizeT xi = 1;
442 for(SizeT i = 0; i != dim(); ++i){
443 CXZ_ASSERT(j != s.size(), "incompatible index formats");
444 xi *= mIs[i]->lmax().val();
445 SizeT xj = s[j];
446 if(xi < xj) {
447 CXZ_ERROR("reformating with lower-dimensional formats is not possible; use sub-indices instead");
448 continue;
449 }
450 j0 = j;
451 while(xj < xi){
452 ++j;
453 CXZ_ASSERT(j != s.size(), "incompatible index formats");
454 xj *= s[j];
455 }
456 CXZ_ASSERT(xj == xi, "incompatible index formats");
457 xi = 1;
458 ++j;
459
462 std::copy(f.begin()+j0,f.begin()+j,nf.begin());
463 nformat[i] = *std::min_element(nf.begin(), nf.end());
464 std::for_each(nf.begin(), nf.end(), [&](SizeT& x)
465 { CXZ_ASSERT(x % nformat[i].val() == 0, "incompatible"); x /= nformat[i].val(); } );
466 std::copy(s.begin()+j0,s.begin()+j,ns.begin());
467 mIs[i]->reformat(nf,ns);
468 }
469 mFormat = YFormat(nformat);
470 return *this;
471 }
472
474 {
475 for(SizeT i = 0; i != mIs.size(); ++i){
476 if(not mIs[i]->formatIsTrivial()){
477 return false;
478 }
479 }
480 SizeT b = 1;
481 for(SizeT i = mFormat.size(); i != 0; --i){
482 const SizeT j = i-1;
483 if(mFormat[j].val() != b){
484 return false;
485 }
486 b *= mIs[j]->pmax().val();
487 }
488 return true;
489 }
490
491 const YFormat& YIndex::format() const
492 {
493 return mFormat;
494 }
495
497 {
498 return mLexFormat;
499 }
500
502 {
503 mFormat = bs;
504 return *this;
505 }
506
508 {
509 CXZ_ASSERT(ind < dim(), "got index number (" << ind << ") larger than dimension ("
510 << dim() << ")");
511 auto& idx = mIs[ind];
512 CXZ_ASSERT(lex < idx->lmax().val(), "tried to set sub-index position " << lex
513 << ", which is out of scope; maximum position in range is " << idx->lmax().val() );
514 (*idx) = lex;
515 (*this)();
516 return *this;
517 }
518
519
520 /*==========================+
521 | non-member functions |
522 +==========================*/
523
524 YIndex yindex(const DPack& pack)
525 {
526 return YIndex(pack.all());
527 }
528
530 {
531 return YIndex(is);
532 }
533
535 {
536 return std::make_shared<YIndex>(pack.all());
537 }
538
540 {
541 return std::make_shared<YIndex>(is);
542 }
543
544 /*====================+
545 | YRangeFactory |
546 +====================*/
547
548 YRangeFactory::YRangeFactory(const Vector<RangePtr>& rvec) :
549 mRVec(rvec) {}
550
551 YRangeFactory::YRangeFactory(Vector<RangePtr>&& rvec) :
552 mRVec(std::forward<Vector<RangePtr>>(rvec)) {}
553
554 YRangeFactory::YRangeFactory(const Vector<RangePtr>& rvec, const RangePtr& ref) :
555 mRVec(rvec), mRef(ref) {}
556
557 YRangeFactory::YRangeFactory(Vector<RangePtr>&& rvec, const RangePtr& ref) :
558 mRVec(std::forward<Vector<RangePtr>>(rvec)), mRef(ref) {}
559
560 void YRangeFactory::make()
561 {
562 Vector<Uuid> k(mRVec.size());
563 std::transform(mRVec.begin(), mRVec.end(), k.begin(),
564 [&](const RangePtr& r) { return r->id(); } );
565 mProd = this->fromCreated(typeid(YRange), k);
566 if(mProd == nullptr){
567 mProd = std::shared_ptr<YRange>
568 ( new YRange( std::move(mRVec) ) );
569 this->addToCreated(typeid(YRange), k, mProd);
570 }
571 }
572
573 /*=============+
574 | YRange |
575 +=============*/
576
578 {
579 return mRVec[i];
580 }
581
583 {
584 if(mRVec.size() == 0){
585 return MArray<RangePtr>();
586 }
587 return MArray<RangePtr>( CRangeFactory(mRVec.size()).create(), mRVec );
588 }
589
591 {
592 SizeT out = 1;
593 for(auto& r: mRVec){
594 out *= r->size();
595 }
596 return out;
597 }
598
600 {
601 return mRVec.size();
602 }
603
605 {
606 const String blim = "[";
607 const String elim = "]";
608 const String dlim = ",";
609 String out = elim;
610 for(auto rit = mRVec.end()-1;;--rit){
611 const SizeT cursize = (*rit)->size();
612 const SizeT curpos = pos % cursize;
613 out = (*rit)->stringMeta(curpos) + out;
614 pos /= cursize;
615 if(rit == mRVec.begin()){
616 out = blim + out;
617 break;
618 }
619 out = dlim + out;
620 }
621 return out;
622 }
623
624 const TypeInfo& YRange::type() const
625 {
626 return typeid(YRange);
627 }
628
630 {
631 return typeid(Vector<DType>);
632 }
633
635 {
636 CXZ_ASSERT(r->dim() == this->dim(), "cannot extend range of dimension "
637 << this->dim() << " by range of dimension " << r->dim());
638 Vector<RangePtr> rvec(this->dim());
639 if(this->dim() == 1 and r->sub(0) == nullptr){
640 rvec[0] = mRVec[0]->extend( r );
641 }
642 else {
643 for(SizeT i = 0; i != this->dim(); ++i){
644 rvec[i] = mRVec[i]->extend( r->sub(i) );
645 }
646 }
647 return YRangeFactory( rvec ).create();
648 }
649
650 Vector<Uuid> YRange::key() const
651 {
652 Vector<Uuid> k(mRVec.size());
653 std::transform(mRVec.begin(), mRVec.end(), k.begin(),
654 [&](const RangePtr& r) { return r->id(); } );
655 return k;
656 }
657
658 YRange::YRange(const Vector<RangePtr>& rvec) : mRVec(rvec) {}
659
660 YRange::YRange(Vector<RangePtr>&& rvec) : mRVec(std::forward<Vector<RangePtr>>(rvec)) {}
661
662 /*==========================+
663 | non-member functions |
664 +==========================*/
665
667 {
668 return YRangeFactory(rs).create();
669 }
670
671 /*=================+
672 | Range Casts |
673 +=================*/
674
676 {
677 return std::dynamic_pointer_cast<YRange>( YRangeFactory({r}).create() );
678 }
679
680}
Array main header.
#define CXZ_ERROR(errmsg)
Definition assert.h:26
#define CXZ_ASSERT(statement, errmsg)
Definition assert.h:40
SizeT size() const
Definition index_pack.cc:29
SizeT pos() const
Definition index_pack.cc:91
const Vector< XIndexPtr > & all() const
Definition index_pack.cc:24
SizeT lex() const
Definition index_pack.cc:77
RangePtr fromCreated(const TypeInfo &info, const Vector< Uuid > &rids) const
Definition range_base.cc:33
void addToCreated(const TypeInfo &info, const Vector< Uuid > &rids, const RangePtr &r)
Definition range_base.cc:44
constexpr const SizeT & val() const
SizeT size() const
YIndex operator-(Int n) const
Definition yrange.cc:253
Vector< SizeT > deepMax() const
Definition yrange.cc:410
YIndex operator+(Int n) const
Definition yrange.cc:247
const YFormat & format() const
Definition yrange.cc:491
RangePtr prange(const YIndex &last) const
Definition yrange.cc:380
const YFormat & lexFormat() const
Definition yrange.cc:496
YIndex & operator=(YIndex &&i)=default
const DPack & pack() const
Definition yrange.cc:375
bool formatIsTrivial() const
Definition yrange.cc:473
YIndex & at(const Vector< DType > &meta)
Definition yrange.cc:345
UPos stepSize(const IndexId< 0 > id) const
Definition yrange.cc:315
Vector< DType > operator*() const
Definition yrange.cc:300
UPos pmax() const
Definition yrange.cc:285
YIndex & operator()()
Definition yrange.cc:369
DXpr< None > ifor(const DXpr< None > &xpr, NoF &&f) const
Definition yrange.cc:357
YIndex & operator-=(Int n)
Definition yrange.cc:272
SizeT lex() const
Definition yrange.cc:280
YIndex & operator--()
Definition yrange.cc:236
YIndex & setSub(SizeT ind, SizeT lex)
Definition yrange.cc:507
String stringMeta() const
Definition yrange.cc:325
UPos lmax() const
Definition yrange.cc:290
YIndex & operator+=(Int n)
Definition yrange.cc:264
YIndex()=default
Sptr< YRange > range() const
Definition yrange.cc:310
YIndex & operator++()
Definition yrange.cc:225
Vector< DType > meta() const
Definition yrange.cc:337
IndexId< 0 > id() const
Definition yrange.cc:295
Vector< SizeT > deepFormat() const
Definition yrange.cc:391
YIndex & setFormat(const YFormat &bs)
Definition yrange.cc:501
SizeT dim() const
Definition yrange.cc:305
YIndex & reformat(const Vector< SizeT > &f, const Vector< SizeT > &s)
Definition yrange.cc:427
virtual MArray< RangePtr > sub() const override final
Definition yrange.cc:582
friend YRangeFactory
Definition yrange.h:315
virtual const TypeInfo & type() const override final
Definition yrange.cc:624
virtual RangePtr extend(const RangePtr &r) const override final
Definition yrange.cc:634
virtual SizeT size() const override final
Definition yrange.cc:590
virtual SizeT dim() const override final
Definition yrange.cc:599
virtual String stringMeta(SizeT pos) const override final
Definition yrange.cc:604
virtual const TypeInfo & metaType() const override final
Definition yrange.cc:629
std::string String
Definition types.h:42
std::type_info TypeInfo
Definition types.h:71
uint64_t SizeT
Definition types.h:38
RangePtr yrange(const Vector< RangePtr > &rs)
Definition yrange.cc:666
Sptr< RangeBase > RangePtr
Definition types.h:157
Sptr< YIndex > yindexPtr(const DPack &is)
Definition yrange.cc:534
std::vector< T, Allocator< T > > Vector
Definition types.h:310
int32_t Int
Definition types.h:36
decltype(auto) xpr(const Sptr< I > &i)
Sptr< Range > rangeCast(const RangePtr r)
YIndex yindex(const DPack &pack)
Definition yrange.cc:524
std::shared_ptr< T > Sptr
Definition types.h:48
Ranges main header.
static Sptr< Range > func(const RangePtr &r)