From 55922490b2dcf754899a87cbb0554dcb9ede303d Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Wed, 11 Jan 2023 17:32:52 +0100 Subject: [PATCH] change operator* for indices -> creates index packs instead of m/yindices --- src/include/array/array_base.cc.h | 118 ++++++++++++++++++++++++--- src/include/array/array_base.h | 38 +++++++-- src/include/ranges/index_mul.cc.h | 124 ++++++++++------------------- src/include/ranges/index_mul.h | 43 +++++----- src/include/ranges/index_pack.cc.h | 74 ++++++++++++++++- src/include/ranges/index_pack.h | 29 ++++++- src/include/ranges/mrange.cc.h | 20 +++-- src/include/ranges/mrange.h | 9 ++- src/include/ranges/yrange.h | 1 + src/lib/ranges/index_pack.cc | 31 ++++++-- src/lib/ranges/yrange.cc | 5 ++ src/tests/range_unit_test.cc | 8 +- 12 files changed, 357 insertions(+), 143 deletions(-) diff --git a/src/include/array/array_base.cc.h b/src/include/array/array_base.cc.h index 43e0ad2..9bfb345 100644 --- a/src/include/array/array_base.cc.h +++ b/src/include/array/array_base.cc.h @@ -20,7 +20,7 @@ namespace CNORXZ template const T& CArrayBase::operator[](const IndexInterface& i) const { - auto ai = this->begin() + i.lex(); + auto ai = itLex(i); return *ai; } @@ -28,11 +28,37 @@ namespace CNORXZ template const T& CArrayBase::at(const IndexInterface& i) const { - CXZ_ASSERT(i.lex() < this->size(), "index out of range"); - auto beg = this->begin(); - //CXZ_ASSERT(false, "IMPLEMENT CHECKS!!"); - // check further compatibility of index/range format!!! - auto ai = beg + i.lex(); + auto ai = itLexSave(i); + return *ai; + } + + template + template + const T& CArrayBase::operator[](const SPack& pack) const + { + auto ai = itLex(pack); + return *ai; + } + + template + template + const T& CArrayBase::at(const SPack& pack) const + { + auto ai = itLexSave(pack); + return *ai; + } + + template + const T& CArrayBase::operator[](const DPack& pack) const + { + auto ai = itLex(pack); + return *ai; + } + + template + const T& CArrayBase::at(const DPack& pack) const + { + auto ai = itLexSave(pack); return *ai; } @@ -78,6 +104,27 @@ namespace CNORXZ return coproot(*this, i); } + /****************************** + * CArrayBase (protected) * + ******************************/ + + template + template + typename CArrayBase::const_iterator CArrayBase::itLex(const Acc& acc) const + { + return begin() + acc.lex(); + } + + template + template + typename CArrayBase::const_iterator CArrayBase::itLexSave(const Acc& acc) const + { + CXZ_ASSERT(acc.lex() < this->size(), "index out of range"); + //CXZ_ASSERT(false, "IMPLEMENT CHECKS!!"); + // check further compatibility of index/range format!!! + return begin() + acc.lex(); + } + /***************** * ArrayBase * *****************/ @@ -91,17 +138,45 @@ namespace CNORXZ template T& ArrayBase::operator[](const IndexInterface& i) { - auto ai = this->begin() + i.lex(); + auto ai = itLex(i); return *ai; } - + template template T& ArrayBase::at(const IndexInterface& i) { - CXZ_ASSERT(i.lex() < this->size(), "index out of range"); - // check further compatibility of index/range format!!! - auto ai = this->begin() + i.lex(); + auto ai = itLexSave(i); + return *ai; + } + + template + template + T& ArrayBase::operator[](const SPack& pack) + { + auto ai = itLex(pack); + return *ai; + } + + template + template + T& ArrayBase::at(const SPack& pack) + { + auto ai = itLexSave(pack); + return *ai; + } + + template + T& ArrayBase::operator[](const DPack& pack) + { + auto ai = itLex(pack); + return *ai; + } + + template + T& ArrayBase::at(const DPack& pack) + { + auto ai = itLexSave(pack); return *ai; } @@ -135,6 +210,27 @@ namespace CNORXZ return oproot(*this, i); } + /***************************** + * ArrayBase (protected) * + *****************************/ + + template + template + typename ArrayBase::iterator ArrayBase::itLex(const Acc& acc) + { + return begin() + acc.lex(); + } + + template + template + typename ArrayBase::iterator ArrayBase::itLexSave(const Acc& acc) + { + CXZ_ASSERT(acc.lex() < this->size(), "index out of range"); + //CXZ_ASSERT(false, "IMPLEMENT CHECKS!!"); + // check further compatibility of index/range format!!! + return begin() + acc.lex(); + } + } #endif diff --git a/src/include/array/array_base.h b/src/include/array/array_base.h index 65d5ad0..7bdd25d 100644 --- a/src/include/array/array_base.h +++ b/src/include/array/array_base.h @@ -19,11 +19,6 @@ namespace CNORXZ public: typedef AIndex const_iterator; - protected: - RangePtr mRange; - - public: - CArrayBase(const RangePtr& range); DEFAULT_MEMBERS(CArrayBase); @@ -35,6 +30,15 @@ namespace CNORXZ template const T& at(const IndexInterface& i) const; + template + const T& operator[](const SPack& pack) const; + + template + const T& at(const SPack& pack) const; + + const T& operator[](const DPack& pack) const; + const T& at(const DPack& pack) const; + template Sptr> sl(const IndexInterface& i) const; @@ -52,6 +56,14 @@ namespace CNORXZ template COpRoot operator()(const Sptr& i) const; + protected: + RangePtr mRange; + + template + const_iterator itLex(const Acc& acc) const; + + template + const_iterator itLexSave(const Acc& acc) const; }; template @@ -80,6 +92,15 @@ namespace CNORXZ template T& at(const IndexInterface& i); + template + T& operator[](const SPack& pack); + + template + T& at(const SPack& pack); + + T& operator[](const DPack& pack); + T& at(const DPack& pack); + template Sptr> sl(const IndexInterface& i); @@ -91,6 +112,13 @@ namespace CNORXZ template OpRoot operator()(const Sptr& i); + protected: + + template + iterator itLex(const Acc& acc); + + template + iterator itLexSave(const Acc& acc); }; } diff --git a/src/include/ranges/index_mul.cc.h b/src/include/ranges/index_mul.cc.h index 1a43174..e3961e5 100644 --- a/src/include/ranges/index_mul.cc.h +++ b/src/include/ranges/index_mul.cc.h @@ -6,41 +6,6 @@ namespace CNORXZ { - /***************** - * MIndexMul * - *****************/ - - template - constexpr decltype(auto) MIndexMul::evalMX(const GMIndex& a, - const IndexInterface& b, - Isq is) - { - static_assert(sizeof...(Is) == sizeof...(Indices), "inconsistent index sequence"); - return MIndex( a.pack()[CSizeT{}]..., - std::make_shared(b.THIS()) ); - } - - template - constexpr decltype(auto) MIndexMul::evalXM(const IndexInterface& a, - const GMIndex& b, - Isq js) - { - static_assert(sizeof...(Js) == sizeof...(Indices), "inconsistent index sequence"); - return MIndex( std::make_shared(a.THIS()), - b.pack()[CSizeT{}]... ); - } - - template - constexpr decltype(auto) MIndexMul::evalMM(const GMIndex& a, - const GMIndex& b, - Isq is, Isq js) - { - static_assert(sizeof...(Is) == sizeof...(Indices1), "inconsistent index sequence"); - static_assert(sizeof...(Js) == sizeof...(Indices2), "inconsistent index sequence"); - return MIndex( a.pack()[CSizeT{}]..., - b.pack()[CSizeT{}]... ); - } /********************* * MIndexSptrMul * @@ -79,58 +44,57 @@ namespace CNORXZ /***************** * operator* * *****************/ - + template - constexpr decltype(auto) operator*(const IndexInterface& a, - const IndexInterface& b) + inline decltype(auto) operator*(const IndexInterface& a, + const IndexInterface& b) { - if constexpr(std::is_same::value){ - if constexpr(std::is_same::value){ - return YIndex({ a.THIS().xptr(), b.THIS().xptr() }); - } - else if constexpr(std::is_same::value){ - auto p = b.THIS().pack(); - auto n = p.lmul( a.THIS().xptr() ); - return YIndex(n.all()); - } - } - else if constexpr(std::is_same::value){ - if constexpr(std::is_same::value){ - auto p = a.THIS().pack(); - auto n = p.rmul( b.THIS().xptr() ); - return YIndex(n.all()); - } - else if constexpr(std::is_same::value){ - auto ap = a.THIS().pack().all(); - const auto& bp = b.THIS().pack(); - ap.insert(ap.end(), bp.all().begin(), bp.all().end()); - return YIndex(ap); - } + if constexpr(std::is_same::value or std::is_same::value or + std::is_same::value or std::is_same::value) { + return dpack(a.THIS(), b.THIS()); } else { - constexpr SizeT I1D = index_dim::value; - constexpr SizeT I2D = index_dim::value; - if constexpr(I1D == 1){ - if constexpr(I2D == 1){ - return MIndex(a.THIS(),b.THIS()); - } - else { - return MIndexMul::evalXM(a, b.THIS(), std::make_index_sequence{}); - } - } - else { - if constexpr(I2D == 1){ - return MIndexMul::evalMX(a.THIS(), b, std::make_index_sequence{}); - } - else { - return MIndexMul::evalMM(a.THIS(), b.THIS(), - std::make_index_sequence{}, - std::make_index_sequence{}); - } - } + return spack(a.THIS(), b.THIS()); } } + template + inline decltype(auto) operator*(const IndexInterface& a, + const SPack& b) + { + return b.lmul(std::make_shared(a.THIS())); + } + + template + inline decltype(auto) operator*(const SPack& a, + const IndexInterface& b) + { + return a.rmul(std::make_shared(b.THIS())); + } + + template + inline decltype(auto) operator*(const SPack& a, const SPack& b) + { + return a.mul(b); + } + + template + inline decltype(auto) operator*(const IndexInterface& a, const DPack& b) + { + return b.lmul(std::make_shared(a.THIS())); + } + + template + inline decltype(auto) operator*(const DPack& a, const IndexInterface& b) + { + return a.rmul(std::make_shared(b.THIS())); + } + + inline decltype(auto) operator*(const DPack& a, const DPack& b) + { + return a.mul(b); + } + /*************** * iptrMul * ***************/ diff --git a/src/include/ranges/index_mul.h b/src/include/ranges/index_mul.h index 5a53595..91cbec6 100644 --- a/src/include/ranges/index_mul.h +++ b/src/include/ranges/index_mul.h @@ -7,25 +7,6 @@ namespace CNORXZ { - struct MIndexMul - { - template - static constexpr decltype(auto) evalMX(const GMIndex& a, - const IndexInterface& b, - Isq is); - - template - static constexpr decltype(auto) evalXM(const IndexInterface& a, - const GMIndex& b, - Isq js); - - template - static constexpr decltype(auto) evalMM(const GMIndex& a, - const GMIndex& b, - Isq is, Isq js); - }; - struct MIndexSptrMul { template @@ -44,9 +25,29 @@ namespace CNORXZ }; template - constexpr decltype(auto) operator*(const IndexInterface& a, - const IndexInterface& b); + inline decltype(auto) operator*(const IndexInterface& a, + const IndexInterface& b); + template + inline decltype(auto) operator*(const IndexInterface& a, + const SPack& b); + + template + inline decltype(auto) operator*(const SPack& a, + const IndexInterface& b); + + template + inline decltype(auto) operator*(const SPack& a, const SPack& b); + + template + inline decltype(auto) operator*(const IndexInterface& a, const DPack& b); + + template + inline decltype(auto) operator*(const DPack& a, const IndexInterface& b); + + inline decltype(auto) operator*(const DPack& a, const DPack& b); + + template decltype(auto) iptrMul(const Sptr& a, const Sptr& b); } diff --git a/src/include/ranges/index_pack.cc.h b/src/include/ranges/index_pack.cc.h index 4d6c5a6..104aee3 100644 --- a/src/include/ranges/index_pack.cc.h +++ b/src/include/ranges/index_pack.cc.h @@ -6,6 +6,10 @@ namespace CNORXZ { + /************* + * SPack * + *************/ + template constexpr SPack::SPack(const Sptr&... is) : mIs(is...) @@ -40,14 +44,14 @@ namespace CNORXZ template constexpr decltype(auto) SPack::rmul(const Sptr& i) const { - return SPack( std::tuple_cat(mIs,i) ); + return SPack( std::tuple_cat(mIs,std::make_tuple(i)) ); } template template constexpr decltype(auto) SPack::lmul(const Sptr& i) const { - return SPack( std::tuple_cat(i, mIs) ); + return SPack( std::tuple_cat(std::make_tuple(i), mIs) ); } template @@ -56,6 +60,72 @@ namespace CNORXZ { return SPack( std::tuple_cat(mIs, all()) ); } + + template + decltype(auto) SPack::mkRange() const + { + return iter<0,sizeof...(Indices)>( [&](auto i) { return get(i)->range(); }, + [](const auto&... e) { return mrange(e...); } ); + } + + template + SizeT SPack::lex() const + { + return iter<0,sizeof...(Indices)-1> + ( [&](auto i) { return get(i)->lex() * iter + ( [&](auto j) { return get(j)->lmax().val(); }, + [](const auto&... m) { return ( m * ... ); } ); }, + [](const auto&... e) { return ( e + ... ); } ) + + get(CSizeT{})->lex() ; + } + + /************************** + * SPack (non-member) * + **************************/ + + template + constexpr decltype(auto) spack(const Indices&... inds) + { + static_assert((is_index::value and ...), "got non-index type"); + return SPack( std::make_shared(inds)... ); + } + + template + constexpr decltype(auto) spackp(const Sptr&... inds) + { + static_assert((is_index::value and ...), "got non-index type"); + return SPack( inds... ); + } + + /************* + * DPack * + *************/ + + template + DPack::DPack(const SPack& p) : + mIs( iter<0,sizeof...(Indices)> + ( [&](auto i) { return xindexPtr(p[i]); }, + [](const auto&... e) { return { e... }; } ) + ) + {} + + + /************************** + * DPack (non-member) * + **************************/ + + template + DPack dpack(const Indices&... inds) + { + return DPack( Vector( { xindexPtr( std::make_shared( inds ) )... } ) ); + } + + template + DPack dpackp(const Sptr&... inds) + { + return DPack( Vector( { xindexPtr( inds )... } ) ); + } + } #endif diff --git a/src/include/ranges/index_pack.h b/src/include/ranges/index_pack.h index ed985ca..618cd5d 100644 --- a/src/include/ranges/index_pack.h +++ b/src/include/ranges/index_pack.h @@ -33,29 +33,50 @@ namespace CNORXZ template constexpr decltype(auto) mul(const SPack& p) const; + + decltype(auto) mkRange() const; + + SizeT lex() const; private: Tuple...> mIs; }; + template + constexpr decltype(auto) spack(const Indices&... inds); + + template + constexpr decltype(auto) spackp(const Sptr&... inds); + class DPack { public: DEFAULT_MEMBERS(DPack); - DPack(const Vector& is); - DPack(Vector&& is); + explicit DPack(const Vector& is); + explicit DPack(Vector&& is); + template + explicit DPack(const SPack& p); + const Vector& all() const; SizeT size() const; const XIndexPtr& get(SizeT i) const; const XIndexPtr& operator[](SizeT i) const; - DPack rmul(const XIndexPtr& i) const; - DPack lmul(const XIndexPtr& i) const; + DPack rmul(const Sptr& i) const; + DPack lmul(const Sptr& i) const; DPack mul(const DPack& p) const; + RangePtr mkRange() const; + SizeT lex() const; private: Vector mIs; }; + + template + DPack dpack(const Indices&... inds); + + template + DPack dpackp(const Sptr&... inds); } #endif diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 9ceac77..7c718e1 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -163,10 +163,10 @@ namespace CNORXZ } template - constexpr GMIndex::GMIndex(const Indices&... is) : + constexpr GMIndex::GMIndex(const SPack& pack) : IndexInterface,Tuple>(0), - mRange(std::dynamic_pointer_cast(mrange(is.range()...))), - mIPack(std::make_shared(is)...), + mRange(std::dynamic_pointer_cast(pack.mkRange())), + mIPack(pack), mLexFormat(mkLexFormat(mIPack,Isqr<1,NI>{})), mFormat(), mLMax(mkLMax(mIPack)), @@ -176,10 +176,10 @@ namespace CNORXZ } template - constexpr GMIndex::GMIndex(const FormatT& bs, const Indices&... is) : + constexpr GMIndex::GMIndex(const FormatT& bs, const SPack& pack) : IndexInterface,Tuple>(0), - mRange(std::dynamic_pointer_cast(mrange(is.range()...))), - mIPack(std::make_shared(is)...), + mRange(std::dynamic_pointer_cast(pack.mkRange())), + mIPack(pack), mLexFormat(mkLexFormat(mIPack,Isqr<1,NI>{})), mFormat(bs), mLMax(mkLMax(mIPack)), @@ -482,7 +482,13 @@ namespace CNORXZ constexpr decltype(auto) mindex(const Sptr&... is) { return MIndex(is...); - } + } + + template + constexpr decltype(auto) mindex(const SPack& pack) + { + return MIndex(pack); + } template constexpr decltype(auto) gmindexPtr(const FormatT& bs, const Sptr&... is) diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index 51bc994..9b0034b 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -34,10 +34,8 @@ namespace CNORXZ constexpr GMIndex(const GMIndex& i); constexpr GMIndex& operator=(const GMIndex& i); - //constexpr GMIndex(const SPack& is); - //constexpr GMIndex(const FormatT& format, const SPack& is); - constexpr GMIndex(const Indices&... is); - constexpr GMIndex(const FormatT& format, const Indices&... is); + constexpr GMIndex(const SPack& pack); + constexpr GMIndex(const FormatT& format, const SPack& pack); constexpr GMIndex(const Sptr&... is); constexpr GMIndex(const FormatT& format, const Sptr&... is); constexpr GMIndex(const RangePtr& range, SizeT lexpos = 0); @@ -146,6 +144,9 @@ namespace CNORXZ template constexpr decltype(auto) mindex(const Sptr&... is); + template + constexpr decltype(auto) mindex(const SPack& pack); + template constexpr decltype(auto) gmindexPtr(const FormatT& bs, const Sptr&... is); diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index 5000418..579d7d8 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -87,6 +87,7 @@ namespace CNORXZ UPos mLMax = 0; }; + YIndex yindex(const DPack& pack); YIndex yindex(const Vector& is); Sptr yindexPtr(const Vector& is); Sptr yindexPtr(const Vector& bs, const Vector& is); diff --git a/src/lib/ranges/index_pack.cc b/src/lib/ranges/index_pack.cc index 9be8479..1782aac 100644 --- a/src/lib/ranges/index_pack.cc +++ b/src/lib/ranges/index_pack.cc @@ -1,5 +1,5 @@ -#include "ranges/index_pack.h" +#include "ranges/ranges.h" namespace CNORXZ { @@ -31,18 +31,18 @@ namespace CNORXZ return get(i); } - DPack DPack::rmul(const XIndexPtr& i) const + DPack DPack::rmul(const Sptr& i) const { auto o = mIs; - o.push_back(i); + o.push_back(i->xptr()); return DPack(std::move(o)); } - DPack DPack::lmul(const XIndexPtr& i) const + DPack DPack::lmul(const Sptr& i) const { Vector o; o.reserve(size()+1); - o.push_back(i); + o.push_back(i->xptr()); o.insert(o.end(), mIs.begin(), mIs.end()); return DPack(std::move(o)); } @@ -56,4 +56,25 @@ namespace CNORXZ return DPack(std::move(o)); } + RangePtr DPack::mkRange() const + { + Vector o(mIs.size()); + std::transform(mIs.begin(), mIs.end(), o.begin(), + [](const auto& i) { return i->range(); } ); + return yrange(o); + } + + SizeT DPack::lex() const + { + if(mIs.size() == 0) { return 0; } + const SizeT isizem1 = mIs.size()-1; + SizeT o = mIs[isizem1]->lex(); + SizeT m = mIs[isizem1]->lmax().val(); + for(SizeT i = isizem1; i != 0; --i){ + const SizeT j = i-1; + o += mIs[j]->lex() * m; + m *= mIs[j]->lmax().val(); + } + return o; + } } diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index 61c78a9..e2c129f 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -382,6 +382,11 @@ namespace CNORXZ * non-member functions * ****************************/ + YIndex yindex(const DPack& pack) + { + return YIndex(pack.all()); + } + YIndex yindex(const Vector& is) { return YIndex(is); diff --git a/src/tests/range_unit_test.cc b/src/tests/range_unit_test.cc index 45389e1..23ff686 100644 --- a/src/tests/range_unit_test.cc +++ b/src/tests/range_unit_test.cc @@ -419,20 +419,20 @@ namespace for(auto cix = crx->begin(); cix != crx->end(); ++cix){ for(auto uix = urx->begin(); uix != urx->end(); ++uix){ const SizeT p1 = cix.lex()*s1 + uix.lex(); - EXPECT_EQ((cix*uix).lex(), p1); + EXPECT_EQ(mindex(cix*uix).lex(), p1); for(auto ci2x = crx->begin(); ci2x != crx->end(); ++ci2x){ const SizeT p2 = cix.lex()*s1*s2 + uix.lex()*s2 + ci2x.lex(); - EXPECT_EQ((cix*uix*ci2x).lex(), p2); + EXPECT_EQ(mindex(cix*uix*ci2x).lex(), p2); } } } for(auto ci = cr->begin(); ci != cr->end(); ++ci){ for(auto ui = ur->begin(); ui != ur->end(); ++ui){ const SizeT p = ci.lex()*s1 + ui.lex(); - EXPECT_EQ((ci*ui).lex(), p); + EXPECT_EQ(yindex(ci*ui).lex(), p); for(auto ci2 = cr->begin(); ci2 != cr->end(); ++ci2){ const SizeT p2 = ci.lex()*s1*s2 + ui.lex()*s2 + ci2.lex(); - EXPECT_EQ((ci*ui*ci2).lex(), p2); + EXPECT_EQ(yindex(ci*ui*ci2).lex(), p2); } } }