diff --git a/src/include/base/types.h b/src/include/base/types.h index 62053cb..57d9b4e 100644 --- a/src/include/base/types.h +++ b/src/include/base/types.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace CNORXZ { @@ -20,6 +21,7 @@ namespace CNORXZ typedef std::intptr_t PtrId; typedef int32_t Int; + typedef int64_t LInt; typedef uint64_t SizeT; typedef double Double; typedef Double Real; diff --git a/src/include/ranges/crange.cc.h b/src/include/ranges/crange.cc.h index 2c299ad..63b344e 100644 --- a/src/include/ranges/crange.cc.h +++ b/src/include/ranges/crange.cc.h @@ -9,7 +9,7 @@ namespace CNORXZ template decltype(auto) CIndex::ifor(const Xpr& xpr, F&& f) const { - return For<0,Xpr,F>(this->max(), this->id(), xpr, std::forward(f)); + return For<0,Xpr,F>(this->pmax(), this->id(), xpr, std::forward(f)); } } diff --git a/src/include/ranges/crange.h b/src/include/ranges/crange.h index 8daf6c4..eb49167 100644 --- a/src/include/ranges/crange.h +++ b/src/include/ranges/crange.h @@ -19,7 +19,7 @@ namespace CNORXZ CIndex(const RangePtr& range, SizeT pos = 0); - CIndex& operator=(SizeT pos); + CIndex& operator=(SizeT lexpos); CIndex& operator++(); CIndex& operator--(); CIndex operator+(Int n) const; @@ -27,7 +27,9 @@ namespace CNORXZ CIndex& operator+=(Int n); CIndex& operator-=(Int n); - SizeT max() const; + SizeT lex() const; + SizeT pmax() const; + SizeT lmax() const; IndexId<0> id() const; SizeT operator*() const; diff --git a/src/include/ranges/dindex.h b/src/include/ranges/dindex.h index e2a2504..16e42c3 100644 --- a/src/include/ranges/dindex.h +++ b/src/include/ranges/dindex.h @@ -24,7 +24,7 @@ namespace CNORXZ template DIndex(const IndexInterface& i); - DIndex& operator=(SizeT pos); + DIndex& operator=(SizeT lexpos); DIndex& operator++(); DIndex& operator--(); DIndex operator+(Int n) const; @@ -32,7 +32,9 @@ namespace CNORXZ DIndex& operator+=(Int n); DIndex& operator-=(Int n); - SizeT max() const; + SizeT lex() const; + SizeT pmax() const; + SizeT lmax() const; IndexId<0> id() const; DType operator*() const; @@ -48,6 +50,8 @@ namespace CNORXZ DXpr ifor(const DXpr& xpr, std::function&& f) const; + const XIndexPtr& xptr() const; + private: XIndexPtr mI; }; diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index 6d77c6a..6e2fe8c 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -20,17 +20,18 @@ namespace CNORXZ I& THIS() { return static_cast(*this); } const I& THIS() const { return static_cast(*this); } - I& operator=(SizeT pos) { return THIS() = pos; } I& operator++() { return ++THIS(); } I& operator--() { return --THIS();} I operator+(Int n) const { return THIS() + n; } I operator-(Int n) const { return THIS() - n; } I& operator+=(Int n) { return THIS() += n; } I& operator-=(Int n) { return THIS() -= n; } - Int operator-(const IndexInterface& i) const { return mPos - i.mPos; } + Int operator-(const IndexInterface& i) const { return lex() - i.lex(); } - SizeT pos() const; - SizeT max() const { return THIS().max(); } + SizeT pos() const; // 'memory' pos + SizeT lex() const { return THIS().lex(); } // lexicographic pos + SizeT pmax() const { return THIS().pmax(); } // memory pos max + SizeT lmax() const { return THIS().lmax(); } // lexicographic pos max PtrId ptrId() const; decltype(auto) id() const { return THIS().id(); } diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 447f25b..48fc971 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -12,12 +12,12 @@ namespace CNORXZ template template - constexpr decltype(auto) MIndex::mkIPack(SizeT pos, Isq is) const + constexpr decltype(auto) MIndex::mkIPack(Isq is) const { static_assert(sizeof...(Is) == NI, - "sequence size does not match number of indices"); + "sequence sioze does not match number of indices"); CXZ_ASSERT( ( (mRange->sub(Is) != nullptr) and ... ), - "no subranges available" ); + "subranges not available" ); return std::make_tuple( std::make_shared( mRange->sub(Is) )... ); } @@ -28,7 +28,7 @@ namespace CNORXZ return std::make_tuple ( iter // replace UPos by SPos where possible !!! - ( [&](auto i) { return UPos(std::get(ipack)->max()); }, + ( [&](auto i) { return UPos(std::get(ipack)->pmax()); }, [&](const auto&... as) { return (as * ...); } )..., SPos<1>() ); } @@ -39,7 +39,7 @@ namespace CNORXZ { auto& i = std::get(mIPack); if constexpr(I != 0){ - if(i->pos() == i->max()-1){ + if(i->lex() == i->lmax()-1){ IB::mPos -= std::get(mBlockSizes).val() * i->pos(); (*i) = 0; up(); @@ -56,8 +56,8 @@ namespace CNORXZ { auto& i = std::get(mIPack); if constexpr(I != 0){ - if(i->pos() == 0){ - (*i) = i->max()-1; + if(i->lex() == 0){ + (*i) = i->lmax()-1; IB::mPos += std::get(mBlockSizes).val() * i->pos(); down(); return; @@ -85,37 +85,46 @@ namespace CNORXZ template MIndex::MIndex(const MIndex& i) : - IndexInterface,Tuple>(i.pos()), + IndexInterface,Tuple>(0), mRange(rangeCast(i.range())), - mIPack(mkIPack(IB::mPos, Isqr<0,NI>{})), + mIPack(mkIPack(Isqr<0,NI>{})), mBlockSizes(mkBlockSizes(mIPack,Isqr<0,NI-1>{})) - {} + { + mPMax = iter<0,NI>( [&](auto i) { return std::get(mIPack)->pmax(); }, + [](auto... e) { return (e * ...); }); + *this = i.pos(); + } template MIndex& MIndex::operator=(const MIndex& i) { - IndexInterface,Tuple>::operator=(i); + IndexInterface,Tuple>::operator=(0); mRange = rangeCast(i.range()); - mIPack = mkIPack(IB::mPos, Isqr<0,NI>{}); + mIPack = mkIPack(Isqr<0,NI>{}); mBlockSizes = mkBlockSizes(mIPack,Isqr<0,NI-1>{}); - return *this; + mPMax = iter<0,NI>( [&](auto i) { return std::get(mIPack)->pmax(); }, + [](auto... e) { return (e * ...); }); + return *this = i.pos(); } template - MIndex::MIndex(const RangePtr& range, SizeT pos) : + MIndex::MIndex(const RangePtr& range, SizeT lexpos) : IndexInterface,Tuple>(0), mRange(rangeCast(range)), - mIPack(mkIPack(IB::mPos, Isqr<0,NI>{})), + mIPack(mkIPack(Isqr<0,NI>{})), mBlockSizes(mkBlockSizes(mIPack,Isqr<0,NI-1>{})) { - (*this) = pos; + mPMax = iter<0,NI>( [&](auto i) { return std::get(mIPack)->pmax(); }, + [](auto... e) { return (e * ...); }); + *this = lexpos; } template - MIndex& MIndex::operator=(SizeT pos) + MIndex& MIndex::operator=(SizeT lexpos) { - IB::mPos = pos; - iter<0,NI>( [&](auto i) { *std::get(mIPack) = (IB::mPos / std::get(mBlockSizes).val()) % std::get(mIPack)->max(); }, NoF{} ); + // Adapt in GMIndex + IB::mPos = lexpos; + iter<0,NI>( [&](auto i) { *std::get(mIPack) = (IB::mPos / std::get(mBlockSizes).val()) % std::get(mIPack)->pmax(); }, NoF{} ); return *this; } @@ -123,8 +132,7 @@ namespace CNORXZ MIndex& MIndex::operator++() { // End state is defined by high-index being end while all other indices are zero - auto& i0 = std::get<0>(mIPack); - if(i0->pos() != i0->max()){ + if(lex() != lmax()){ up(); } return *this; @@ -133,7 +141,7 @@ namespace CNORXZ template MIndex& MIndex::operator--() { - if(IB::mPos != 0){ + if(lex() != 0){ down(); } return *this; @@ -156,12 +164,12 @@ namespace CNORXZ template MIndex& MIndex::operator+=(Int n) { - if(-n > static_cast(IB::mPos)){ + if(-n > static_cast(lex())){ (*this) = 0; } - const SizeT p = IB::mPos + n; - if(p > max()){ - (*this) = max(); + const SizeT p = lex() + n; + if(p > lmax()){ + (*this) = lmax(); } (*this) = p; return *this; @@ -170,21 +178,33 @@ namespace CNORXZ template MIndex& MIndex::operator-=(Int n) { - if(n > static_cast(IB::mPos)){ + if(n > static_cast(lex())){ (*this) = 0; } - const SizeT p = IB::mPos + n; - if(p > max()){ - (*this) = max(); + const SizeT p = lex() + n; + if(p > lmax()){ + (*this) = lmax(); } (*this) = p; return *this; } template - SizeT MIndex::max() const + SizeT MIndex::lex() const { - return mRange->size(); + return IB::mPos; + } + + template + SizeT MIndex::pmax() const + { + return mPMax; + } + + template + SizeT MIndex::lmax() const + { + return mPMax; } template diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index e8e0c6a..5ad50cd 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -27,12 +27,13 @@ namespace CNORXZ // NO DEFAULT HERE !!! // ( have to assign sub-indices (ptr!) correctly ) MIndex() = default; - MIndex(const MIndex& i); - MIndex& operator=(const MIndex& i); MIndex(MIndex&& i) = default; MIndex& operator=(MIndex&& i) = default; - MIndex(const RangePtr& range, SizeT pos = 0); + MIndex(const MIndex& i); + MIndex& operator=(const MIndex& i); + + MIndex(const RangePtr& range, SizeT lexpos = 0); MIndex& operator=(SizeT pos); MIndex& operator++(); @@ -42,7 +43,9 @@ namespace CNORXZ MIndex& operator+=(Int n); MIndex& operator-=(Int n); - SizeT max() const; + SizeT lex() const; + SizeT pmax() const; + SizeT lmax() const; IndexId<0> id() const; MetaType operator*() const; @@ -71,7 +74,7 @@ namespace CNORXZ static constexpr decltype(auto) mkBlockSizes(const IndexPack& ipack, Isq is); template - constexpr decltype(auto) mkIPack(SizeT pos, Isq is) const; + constexpr decltype(auto) mkIPack(Isq is) const; template inline void up(); @@ -86,6 +89,7 @@ namespace CNORXZ IndexPack mIPack; typedef RemoveRef{}))> BlockTuple; BlockTuple mBlockSizes; + SizeT mPMax = 0; // = LMax here, add new variable in GMIndex! }; // modified blockSizes; to be used for Slices; can be created from MIndices @@ -101,7 +105,7 @@ namespace CNORXZ constexpr decltype(auto) ifor(const Xpr& xpr, F&& f) const; private: - BlockType mBlockSizes; + BlockType mLexBlockSizes; template constexpr decltype(auto) mkPos(Isq is) const; diff --git a/src/include/ranges/range_helper.h b/src/include/ranges/range_helper.h deleted file mode 100644 index d60f78a..0000000 --- a/src/include/ranges/range_helper.h +++ /dev/null @@ -1,285 +0,0 @@ - -#ifndef __cxz_range_helper_h__ -#define __cxz_range_helper_h__ - -namespace CNORXZ -{ - namespace RangeHelper - { - - template - int ppx(std::tuple...>& ip, - std::array& bs, - std::intptr_t idxPtrNum) - { - auto& siPtr = std::get(ip); - if(reinterpret_cast(siPtr.get()) == idxPtrNum){ - if constexpr(I != 0){ - return ppx(ip, bs, idxPtrNum); - } - else { - return std::get<0>(bs); - } - } - else { - const int tmp = siPtr->pp(idxPtrNum); - if constexpr(I != 0){ - if(siPtr->pos() == siPtr->max()){ - (*siPtr) = 0; - return ppx(ip, bs, idxPtrNum) - siPtr->max() + 1; - } - } - return tmp * std::get(bs); - } - } - - template - int mmx(std::tuple...>& ip, - std::array& bs, - std::intptr_t idxPtrNum) - { - auto& siPtr = std::get(ip); - if(reinterpret_cast(siPtr.get()) == idxPtrNum){ - if constexpr(I != 0){ - return mmx(ip, bs, idxPtrNum); - } - else { - return std::get<0>(bs); - } - } - else { - const int tmp = siPtr->mm(idxPtrNum); - if constexpr(I != 0){ - if(siPtr->pos() == siPtr->max()){ - (*siPtr) = siPtr->max() - 1; - return mmx(ip, bs, idxPtrNum) - siPtr->max() + 1; - } - } - return tmp * std::get(bs); - } - } - - template - inline size_t makePos(const std::tuple...>& iPtrTup, - const std::array& blockSize) - { - if constexpr(N != 0){ - return makePos(iPtrTup, blockSize) + - std::get(iPtrTup)->pos() * std::get(blockSize); - } - else { - return std::get<0>(iPtrTup)->pos() * std::get<1>(blockSize); - } - } - - template - inline void resolveSetRange(std::shared_ptr& rp, const vector >& orig, - size_t origpos, size_t size) - { - assert(size == 1); - rp = std::dynamic_pointer_cast( orig[origpos] ); // catch bad cast here!! - } - - template - inline void setRangeToVec(vector >& v, - std::shared_ptr r) - { - v.insert(v.begin(), r); - } - - template - void setIndexPack(IndexPack& iPack, size_t pos) - { - auto& i = *std::get(iPack).get(); - const size_t ownPos = pos % i.max(); - i = ownPos; - if constexpr(N != 0){ - setIndexPack(iPack, (pos - ownPos) / i.max() ); - } - } - - template - inline size_t getMeta(const std::tuple...>& space, - const std::tuple& meta) - { - if constexpr(N != 0){ - return getMeta(space,meta) * std::get(space)->size() + - std::get(space)->getMeta(std::get(meta)); - } - else { - return std::get<0>(space)->getMeta(std::get<0>(meta)); - } - } - - template - inline void getTypeNum(vector& res, const std::tuple...>& stp) - { - auto& r = *std::get(stp); - auto tn = r.typeNum(); - res.insert(res.begin(), tn.begin(), tn.end()); - if constexpr(N != 0){ - getTypeNum(res, stp); - } - } - - template - auto mkFor(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) - { - constexpr size_t S = std::tuple_size::value; - if constexpr(N < S-1){ - return std::get(ipack) - ->ifor( step*std::get(ba), mkFor(step, ipack, ba, exs) ); - } - else { - return std::get(ipack)->ifor( step*std::get(ba), exs); - } - } - - template - auto mkForh(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) - { - constexpr size_t S = std::tuple_size::value; - if constexpr(N < S-1){ - return std::get(ipack) - ->iforh( step*std::get(ba), mkForh(step, ipack, ba, exs) ); - } - else { - return std::get(ipack)->iforh( step*std::get(ba), exs); - } - } - - template - auto mkPFor(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) - { - constexpr size_t S = std::tuple_size::value; - if constexpr(N < S-1){ - return std::get(ipack) - ->pifor( step*std::get(ba), mkFor(step, ipack, ba, exs) ); - // mkFor is correct here, because we want to multithread only the FIRST index!! - } - else { - return std::get(ipack)->pifor( step*std::get(ba), exs); - } - } - - template - inline void resolveRangeType(const vector >& orig, - RangeTuple& rtp, size_t off, size_t size, SIZET... sizes) - { - constexpr size_t tps = std::tuple_size::value; - ::CNORXZ::RangeHelper::resolveSetRange(std::get(rtp), orig, off, size); - if constexpr(N < tps-1){ - resolveRangeType(orig, rtp, off+size, sizes...); - } - } - - template - inline void resolveRangeType(const vector >& orig, - RangeTuple& rtp, size_t off, size_t size) - { - constexpr size_t tps = std::tuple_size::value; - ::CNORXZ::RangeHelper::resolveSetRange(std::get(rtp), orig, off, size); - } - - template - inline size_t getCMeta(MetaType* xtarget, size_t pos, - const std::tuple...>& stp, size_t off) - { - //constexpr size_t NN = sizeof...(Ranges); - auto& r = *std::get(stp); - const size_t ownPos = pos % r.size(); - const size_t s = r.cmetaSize(); - off -= s; - r.cmeta(reinterpret_cast(&std::get(*xtarget)), ownPos); - if constexpr(N != 0){ - return s + getCMeta(xtarget, (pos - ownPos) / r.size(), stp, off); - } - else { - assert(off == 0); - return s; - } - } - - template - inline size_t getCMetaSize(const std::tuple...>& stp) - { - auto& r = *std::get(stp); - if constexpr(N < sizeof...(Ranges)-1){ - return r.cmetaSize() + getCMetaSize(stp); - } - else { - return r.cmetaSize(); - } - } - - template - inline std::string getStringMeta(const MIndex& mi) - { - if constexpr(N < MIndex::sDim()-1){ - return mi.template getPtr()->stringMeta() + "," + getStringMeta(mi); - } - else { - return mi.template getPtr()->stringMeta(); - } - } - - template - inline size_t getStepSize(const Index& ii, std::intptr_t j); - - template - inline void getStepSizeX(const Index& ii, std::intptr_t j, size_t& ss, size_t& sx) - { - const auto& ni = ii.template get(); - const size_t max = ni.max(); - const size_t tmp = getStepSize(ni, j); - ss += tmp * ii.template getBlockSize(); - sx *= max; - if constexpr(N != 0){ - getStepSizeX(ii, j, ss, sx); - } - } - - template - inline size_t getStepSize(const Index& ii, std::intptr_t j) - { - constexpr IndexType IT = Index::sType(); - if constexpr(IT == IndexType::SINGLE){ - const std::intptr_t ip = reinterpret_cast(&ii); - return ip == j ? 1 : 0; - } - else { - size_t ss = 0; - size_t sx = 1; - constexpr size_t DIM = Index::sDim(); - getStepSizeX(ii, j, ss, sx); - return ss; - } - } - - - template - inline bool compareSpaceTypes(const vector >& rbvec) - { - if constexpr(N != 0){ - return rbvec[SIZE-N-1]->spaceType() == Range::STYPE and compareSpaceTypes(rbvec); - } - else { - return rbvec[SIZE-N-1]->spaceType() == Range::STYPE; - } - } - - template - inline void setSpace(const vector >& rbvec, - std::tuple...>& stp) - { - typedef typename std::remove_reference( stp ))>::type RType; - std::get( stp ) = std::dynamic_pointer_cast( rbvec[N] ); - if constexpr(N != 0){ - setSpace(rbvec, stp); - } - } - - } // namespace RangeHelper -} // namespace CNORXZ - -#endif diff --git a/src/include/ranges/urange.cc.h b/src/include/ranges/urange.cc.h index 91e3926..5243d17 100644 --- a/src/include/ranges/urange.cc.h +++ b/src/include/ranges/urange.cc.h @@ -22,9 +22,9 @@ namespace CNORXZ {} template - UIndex& UIndex::operator=(size_t pos) + UIndex& UIndex::operator=(size_t lexpos) { - IB::mPos = pos; + IB::mPos = lexpos; return *this; } @@ -69,7 +69,19 @@ namespace CNORXZ } template - SizeT UIndex::max() const + SizeT UIndex::lex() const + { + return IB::mPos; + } + + template + SizeT UIndex::pmax() const + { + return mRangePtr->size(); + } + + template + SizeT UIndex::lmax() const { return mRangePtr->size(); } @@ -128,7 +140,7 @@ namespace CNORXZ template decltype(auto) UIndex::ifor(const Xpr& xpr, F&& f) const { - return For<0,Xpr,F>(this->max(), this->id(), xpr, std::forward(f)); + return For<0,Xpr,F>(this->pmax(), this->id(), xpr, std::forward(f)); } /********************** diff --git a/src/include/ranges/urange.h b/src/include/ranges/urange.h index 35fb4da..44c0245 100644 --- a/src/include/ranges/urange.h +++ b/src/include/ranges/urange.h @@ -22,7 +22,7 @@ namespace CNORXZ UIndex(const RangePtr& range, SizeT pos = 0); - UIndex& operator=(SizeT pos); + UIndex& operator=(SizeT lexpos); UIndex& operator++(); UIndex& operator--(); UIndex operator+(Int n) const; @@ -30,7 +30,9 @@ namespace CNORXZ UIndex& operator+=(Int n); UIndex& operator-=(Int n); - SizeT max() const; + SizeT lex() const; + SizeT pmax() const; + SizeT lmax() const; IndexId<0> id() const; const MetaT& operator*() const; diff --git a/src/include/ranges/xindex.cc.h b/src/include/ranges/xindex.cc.h index 50e0109..07c2c4c 100644 --- a/src/include/ranges/xindex.cc.h +++ b/src/include/ranges/xindex.cc.h @@ -32,9 +32,10 @@ namespace CNORXZ } template - XIndex& XIndex::operator=(SizeT pos) + XIndex& XIndex::operator=(SizeT lexpos) { - *mI = pos; + mI->THIS() = lexpos; + assert(mI->lex() == lexpos); return *this; } @@ -79,9 +80,21 @@ namespace CNORXZ } template - SizeT XIndex::max() const + SizeT XIndex::lex() const { - return mI->max(); + return mI->lex(); + } + + template + SizeT XIndex::pmax() const + { + return mI->pmax(); + } + + template + SizeT XIndex::lmax() const + { + return mI->lmax(); } template @@ -136,9 +149,9 @@ namespace CNORXZ template DXpr XIndex::ifor(const DXpr& xpr, - std::function&& f) const + const std::function& f) const { - return DXpr(mI->ifor(xpr, std::forward>(f))); + return DXpr(mI->ifor(xpr, f)); } } diff --git a/src/include/ranges/xindex.h b/src/include/ranges/xindex.h index 434c64c..e615754 100644 --- a/src/include/ranges/xindex.h +++ b/src/include/ranges/xindex.h @@ -17,7 +17,7 @@ namespace CNORXZ virtual XIndexPtr copy() const = 0; virtual SizeT pos() const = 0; - virtual XIndexBase& operator=(SizeT pos) = 0; + virtual XIndexBase& operator=(SizeT lexpos) = 0; virtual XIndexBase& operator++() = 0; virtual XIndexBase& operator--() = 0; virtual XIndexPtr operator+(Int n) const = 0; @@ -25,7 +25,9 @@ namespace CNORXZ virtual XIndexBase& operator+=(Int n) = 0; virtual XIndexBase& operator-=(Int n) = 0; - virtual SizeT max() const = 0; + virtual SizeT lex() const = 0; + virtual SizeT pmax() const = 0; + virtual SizeT lmax() const = 0; virtual IndexId<0> id() const = 0; virtual DType operator*() const = 0; @@ -39,7 +41,7 @@ namespace CNORXZ virtual XIndexBase& at(const DType& meta) = 0; virtual DXpr ifor(const DXpr& xpr, - std::function&& f) const = 0; + const std::function& f) const = 0; }; //Sptr& operator++(Sptr& i); @@ -63,7 +65,7 @@ namespace CNORXZ virtual XIndexPtr copy() const override final; virtual SizeT pos() const override final; - virtual XIndex& operator=(SizeT pos) override final; + virtual XIndex& operator=(SizeT lexpos) override final; virtual XIndex& operator++() override final; virtual XIndex& operator--() override final; virtual XIndexPtr operator+(Int n) const override final; @@ -71,7 +73,9 @@ namespace CNORXZ virtual XIndex& operator+=(Int n) override final; virtual XIndex& operator-=(Int n) override final; - virtual SizeT max() const override final; + virtual SizeT lex() const override final; + virtual SizeT pmax() const override final; + virtual SizeT lmax() const override final; virtual IndexId<0> id() const override final; virtual DType operator*() const override final; @@ -85,7 +89,7 @@ namespace CNORXZ virtual XIndexBase& at(const DType& meta) override final; virtual DXpr ifor(const DXpr& xpr, - std::function&& f) const override final; + const std::function& f) const override final; private: IndexPtr mI; diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index 94097fb..a5551a3 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -10,10 +10,6 @@ namespace CNORXZ { - // YRange!!!! - - // Future DynamicIndex - //class YIndex : public XIndexBase class YIndex : public IndexInterface { public: @@ -21,21 +17,26 @@ namespace CNORXZ typedef YRange RangeType; typedef DType MetaType; - DEFAULT_MEMBERS(YIndex); - YIndex(const RangePtr& range, SizeT pos = 0); - YIndex(const RangePtr& range, const Vector& is, SizeT pos = 0); + YIndex() = default; + YIndex(YIndex&& i) = default; + YIndex& operator=(YIndex&& i) = default; - YIndex& sync(); // remove!!! + YIndex(const YIndex& i); + YIndex& operator=(const YIndex& i); - YIndex& operator=(SizeT pos); + YIndex(const RangePtr& range, SizeT lexpos); + + YIndex& operator=(SizeT lexpos); YIndex& operator++(); YIndex& operator--(); - YIndex operator+(Int n) const; + YIndex operator+(Int n) const; // equivalent to applying n times ++ YIndex operator-(Int n) const; YIndex& operator+=(Int n); YIndex& operator-=(Int n); - SizeT max() const; + SizeT lex() const; + SizeT pmax() const; + SizeT lmax() const; IndexId<0> id() const; DType operator*() const; @@ -48,14 +49,28 @@ namespace CNORXZ DType meta() const; YIndex& at(const DType& meta); - DXpr ifor(const DXpr& xpr, std::function&& f) const; + DXpr ifor(const DXpr& xpr, const std::function& f) const; private: + inline Vector mkBlockSizes() const; + inline Vector mkLexBlockSizes() const; + inline Vector mkIndices() const; + inline void up(SizeT i); + inline void down(SizeT i); + inline decltype(auto) mkIFor(SizeT i, const DXpr& xpr, + const std::function& f) const; - Sptr mRangePtr; + inline SizeT mkPMax() const; + inline SizeT mkLMax() const; + + SizeT mLPos = 0; + Sptr mRange; Vector mIs; Vector mBlockSizes; // dim() elements only!!! - + Vector mLexBlockSizes; // dim() elements only!!! + SizeT mLex = 0; + SizeT mPMax = 0; + SizeT mLMax = 0; }; class YRangeFactory : public RangeFactoryBase @@ -82,6 +97,7 @@ namespace CNORXZ friend YRangeFactory; + virtual RangePtr sub(SizeT i) const override final; virtual SizeT size() const override final; virtual SizeT dim() const override final; virtual String stringMeta(SizeT pos) const override final; diff --git a/src/lib/ranges/crange.cc b/src/lib/ranges/crange.cc index 93495f1..6be9932 100644 --- a/src/lib/ranges/crange.cc +++ b/src/lib/ranges/crange.cc @@ -11,9 +11,9 @@ namespace CNORXZ IndexInterface(pos), mRangePtr(rangeCast(range)) {} - CIndex& CIndex::operator=(SizeT pos) + CIndex& CIndex::operator=(SizeT lexpos) { - IB::mPos = pos; + IB::mPos = lexpos; return *this; } @@ -51,11 +51,21 @@ namespace CNORXZ return *this; } - SizeT CIndex::max() const + SizeT CIndex::lex() const + { + return IB::mPos; + } + + SizeT CIndex::lmax() const { return mRangePtr->size(); } - + + SizeT CIndex::pmax() const + { + return mRangePtr->size(); + } + IndexId<0> CIndex::id() const { return IndexId<0>(this->ptrId()); diff --git a/src/lib/ranges/dindex.cc b/src/lib/ranges/dindex.cc index 00e541a..cb83a12 100644 --- a/src/lib/ranges/dindex.cc +++ b/src/lib/ranges/dindex.cc @@ -37,9 +37,9 @@ namespace CNORXZ mI(i) {} - DIndex& DIndex::operator=(SizeT pos) + DIndex& DIndex::operator=(SizeT lexpos) { - *mI = pos; + *mI = lexpos; IB::mPos = mI->pos(); return *this; } @@ -82,6 +82,26 @@ namespace CNORXZ return *this; } + SizeT DIndex::lex() const + { + return mI->lex(); + } + + SizeT DIndex::pmax() const + { + return mI->pmax(); + } + + SizeT DIndex::lmax() const + { + return mI->lmax(); + } + + IndexId<0> DIndex::id() const + { + return mI->id(); + } + DType DIndex::operator*() const { return *(*mI); @@ -124,4 +144,8 @@ namespace CNORXZ return DXpr(mI->ifor(xpr, std::forward>(f)) ); } + const XIndexPtr& DIndex::xptr() const + { + return mI; + } } diff --git a/src/lib/ranges/range_base.cc b/src/lib/ranges/range_base.cc index b64d7b1..6401637 100644 --- a/src/lib/ranges/range_base.cc +++ b/src/lib/ranges/range_base.cc @@ -83,7 +83,7 @@ namespace CNORXZ RangePtr operator*(const RangePtr& a, const RangePtr& b) { - assert(0); // check segfault + "flatten" yrange (no yrange of yranges etc) + //assert(0); // check segfault + "flatten" yrange (no yrange of yranges etc) return YRangeFactory({a,b}).create(); } diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index e0ca97c..3f7137a 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -3,96 +3,216 @@ namespace CNORXZ { + /************************* + * YIndex (private) * + *************************/ + + inline Vector YIndex::mkIndices() const + { + Vector o(mRange->dim(), nullptr); + for(SizeT i = 0; i != mRange->dim(); ++i){ + auto rp = mRange->sub(i); + CXZ_ASSERT(rp != nullptr, "subranges not available"); + o[i] = rp->begin().xptr(); + } + return o; + } + + inline Vector YIndex::mkBlockSizes() const + { + Vector o(mIs.size()); + SizeT b = 1; + for(SizeT i = o.size(); i != 0; --i){ + const SizeT j = i-1; + o[j] = b; + b *= mIs[j]->pmax(); + } + return o; + } + + inline Vector YIndex::mkLexBlockSizes() const + { + Vector o(mIs.size()); + SizeT b = 1; + for(SizeT i = o.size(); i != 0; --i){ + const SizeT j = i-1; + o[j] = b; + b *= mIs[j]->lmax(); + } + return o; + } + + inline void YIndex::up(SizeT i) + { + auto& idx = mIs[i]; + // it is guaranteed that the last accessible position + // is one less than the max position (=end) + if(i != 0 and idx->lex() == idx->lmax()-1){ + IB::mPos -= mBlockSizes[i] * idx->pos(); + (*idx) = 0; + up(i-1); + return; + } + IB::mPos += mBlockSizes[i]; + ++(*idx); + } + + inline void YIndex::down(SizeT i) + { + auto& idx = mIs[i]; + if(i != 0 and idx->pos() == 0){ + (*idx) = idx->lmax()-1; + IB::mPos += mBlockSizes[i] * idx->pos(); + down(i-1); + return; + } + IB::mPos += mBlockSizes[i]; + --(*idx); + } + + inline decltype(auto) YIndex::mkIFor(SizeT i, const DXpr& xpr, + const std::function& f) const + { + if(i == mIs.size()-1){ + return mIs[i]->ifor( xpr, f ); + } + else { + return mIs[i]->ifor( mkIFor(i+1, xpr, f), f ); + } + } + + inline SizeT YIndex::mkPMax() const + { + SizeT o = 0; + for(SizeT i = 0; i != mIs.size(); ++i){ + o += (mIs[i]->pmax()-1) * mBlockSizes[i]; + } + return o+1; + } + + inline SizeT YIndex::mkLMax() const + { + return std::accumulate(mIs.begin(), mIs.end(),1, + [](const auto& res, const auto& el) { return res * el->lmax(); } ); + } + + /*************** * YIndex * ***************/ - YIndex::YIndex(const RangePtr& range, SizeT pos) : - IndexInterface(pos), - mRangePtr(rangeCast(range)), mIs(mRangePtr->dim()), - mBlockSizes(mRangePtr->dim()) + YIndex::YIndex(const YIndex& i) : + IndexInterface(i), + mRange(rangeCast(i.range())), + mIs(mkIndices()), + mBlockSizes(mkBlockSizes()), + mLexBlockSizes(mkLexBlockSizes()), + mPMax(mkPMax()), + mLMax(mkLMax()) { - assert(0); - // init ...!!! - } - - YIndex::YIndex(const RangePtr& range, const Vector& is, SizeT pos) : - IndexInterface(pos), - mRangePtr(rangeCast(range)), mIs(is), - mBlockSizes(mRangePtr->dim()) - { - CXZ_ASSERT(mIs.size() == mRangePtr->dim(), "obtained wrong number of indices"); - assert(0); - // init ...!!! - } - - YIndex& YIndex::sync() - { - assert(0); - return *this; + *this = i.lex(); } - YIndex& YIndex::operator=(SizeT pos) + YIndex& YIndex::operator=(const YIndex& i) { - IB::mPos = pos; - assert(0); - // sub inds... (LAZY!!!) !!! + IndexInterface::operator=(i); + mRange = rangeCast(i.range()); + mIs = mkIndices(); + mBlockSizes = mkBlockSizes(); + mLexBlockSizes = mkLexBlockSizes(); + mPMax = mkPMax(); + mLMax = mkLMax(); + return *this = i.lex(); + } + + YIndex::YIndex(const RangePtr& range, SizeT lexpos) : + IndexInterface(0), + mRange(rangeCast(range)), + mIs(mkIndices()), + mBlockSizes(mkBlockSizes()), + mLexBlockSizes(mkLexBlockSizes()), + mPMax(mkPMax()), + mLMax(mkLMax()) + { + *this = lexpos; + } + + YIndex& YIndex::operator=(SizeT lexpos) + { + mLex = lexpos; + if(lexpos == lmax()){ + IB::mPos = pmax(); + return *this; + } + IB::mPos = 0; + for(SizeT i = 0; i != mIs.size(); ++i){ + *mIs[i] = (lex() / mLexBlockSizes[i]) % mIs[i]->lmax(); + IB::mPos += mBlockSizes[i] * mIs[i]->pos(); + } return *this; } YIndex& YIndex::operator++() { - assert(0); - // increment sub inds (LAZY!!!) !!! - ++mPos; + auto& i0 = mIs[0]; + if(i0->lex() != i0->lmax()){ + up(mIs.size()-1); + } + // no else! up() changes i0! + if(i0->lex() == i0->lmax()){ + IB::mPos = pmax(); + } return *this; } YIndex& YIndex::operator--() { - assert(0); - // decrement sub inds (LAZY!!!) !!! - --mPos; + auto& i0 = mIs[0]; + if(i0->lex() == i0->lmax()){ + IB::mPos = mBlockSizes[0] * i0->pmax(); + } + if(lex() != 0){ + down(mIs.size()-1); + } return *this; } YIndex YIndex::operator+(Int n) const { - assert(0); - // sub inds !!! - return YIndex(mRangePtr, IB::mPos + n); + YIndex o(*this); + return o += n; } YIndex YIndex::operator-(Int n) const { - assert(0); - // sub inds !!! - return YIndex(mRangePtr, IB::mPos - n); + YIndex o(*this); + return o -= n; } YIndex& YIndex::operator+=(Int n) { - assert(0); - // sub inds !!! - IB::mPos += n; - return *this; + return *this = lex() + n; } YIndex& YIndex::operator-=(Int n) { - assert(0); - // sub inds !!! - IB::mPos -= n; - return *this; + + return *this = lex() - n; } - SizeT YIndex::max() const + SizeT YIndex::lex() const { - SizeT o = 1; - for(auto& i: mIs){ - o *= i->max(); - } - return o; + return mLex; + } + + SizeT YIndex::pmax() const + { + return mPMax; + } + + SizeT YIndex::lmax() const + { + return mLMax; } IndexId<0> YIndex::id() const @@ -102,42 +222,45 @@ namespace CNORXZ DType YIndex::operator*() const { - assert(0); - return DType(); + return meta(); } SizeT YIndex::dim() const { - return mRangePtr->dim(); + return mRange->dim(); } Sptr YIndex::range() const { - return mRangePtr; + return mRange; } UPos YIndex::stepSize(const IndexId<0> id) const { - assert(0); - // sub inds !!! - return UPos(0); + SizeT o = 0; + for(SizeT i = 0; i != mIs.size(); ++i){ + const auto u = mIs[i]->stepSize(id) * UPos(mBlockSizes[i]); + o += u.val(); + } + return UPos(o); } String YIndex::stringMeta() const { - String out = "["; - auto it = mIs.begin(); - for(; it != mIs.end()-1; ++it){ - out += (*it)->stringMeta() + ","; - } - out += (*it)->stringMeta() + "]"; - return out; + const String blim = "["; + const String elim = "]"; + const String dlim = ","; + return blim + + std::accumulate(std::next(mIs.begin()), mIs.end(), mIs[0]->stringMeta(), + [&](const auto& s, const auto& e) + { return s + dlim + e->stringMeta(); } ) + + elim; } DType YIndex::meta() const { Vector v(mIs.size()); - std::transform(mIs.begin(), mIs.end(), v.begin(), [](auto& x) { return x->meta(); }); + std::transform(mIs.begin(), mIs.end(), v.begin(), [](const auto& x) { return x->meta(); }); return DType(v); } @@ -145,17 +268,17 @@ namespace CNORXZ { auto& v = std::any_cast&>(meta.get()); assert(v.size() == mIs.size()); + IB::mPos = 0; for(SizeT i = 0; i != mIs.size(); ++i){ mIs[i]->at(v[i]); + IB::mPos += mIs[i]->pos() * mBlockSizes[i]; } return *this; } - DXpr YIndex::ifor(const DXpr& xpr, std::function&& f) const + DXpr YIndex::ifor(const DXpr& xpr, const std::function& f) const { - assert(0); - f(0,0); - return DXpr(); + return mkIFor(0, xpr, f); } /********************** @@ -176,7 +299,7 @@ namespace CNORXZ void YRangeFactory::make() { - Vector key; + Vector key(mRVec.size()); std::transform(mRVec.begin(), mRVec.end(), key.begin(), [&](const RangePtr& r) { return r->id(); } ); mProd = this->fromCreated(typeid(YRange), key); @@ -191,6 +314,11 @@ namespace CNORXZ * YRange * ***************/ + RangePtr YRange::sub(SizeT i) const + { + return mRVec[i]; + } + SizeT YRange::size() const { SizeT out = 1; diff --git a/src/tests/range_unit_test.cc b/src/tests/range_unit_test.cc index 2cc9d9e..a655a03 100644 --- a/src/tests/range_unit_test.cc +++ b/src/tests/range_unit_test.cc @@ -51,6 +51,21 @@ namespace Vector mMeta; SizeT mSize; }; + + class YR_Test : public ::testing::Test + { + protected: + + YR_Test() + { + mMeta = { "test", "strings", "foo" }; + std::sort(mMeta.begin(), mMeta.end(), std::less()); + mSize = 7; + } + + Vector mMeta; + SizeT mSize; + }; TEST_F(CR_Test, Basics) { @@ -175,7 +190,22 @@ namespace ++cnt; } } - + + TEST_F(YR_Test, Basics) + { + auto cr = CRangeFactory(mSize).create(); + auto ur = URangeFactory(mMeta).create(); + auto yr = cr * ur; + + EXPECT_EQ(yr->size(), mMeta.size()*mSize); + EXPECT_EQ(yr->dim(), 2u); + + EXPECT_TRUE(yr->begin() != yr->end()); + EXPECT_FALSE(yr->begin() == yr->end()); + EXPECT_EQ(yr->begin().pos(), 0u); + EXPECT_EQ(yr->end().pos(), yr->size()); + + } // RCast_Test }