diff --git a/src/include/ranges/crange.h b/src/include/ranges/crange.h index e6934d6..8937d8c 100644 --- a/src/include/ranges/crange.h +++ b/src/include/ranges/crange.h @@ -107,6 +107,9 @@ namespace CNORXZ /** @copydoc IndexInterface::deepFormat() */ SizeT deepFormat() const; + /** @copydoc IndexInterface::reformat() */ + CIndex reformat(const Vector& f, const Vector& s) const; + /** @copydoc IndexInterface::ifor() */ template decltype(auto) ifor(const Xpr& xpr, F&& f) const; diff --git a/src/include/ranges/dindex.h b/src/include/ranges/dindex.h index bdfd741..340a8eb 100644 --- a/src/include/ranges/dindex.h +++ b/src/include/ranges/dindex.h @@ -64,6 +64,9 @@ namespace CNORXZ DIndex& at(const DType& meta); RangePtr prange(const DIndex& end) const; Vector deepFormat() const; + + /** @copydoc IndexInterface::reformat() */ + DIndex reformat(const Vector& f, const Vector& s) const; template decltype(auto) ifor(const Xpr& xpr, F&& f) const; diff --git a/src/include/ranges/index_base.cc.h b/src/include/ranges/index_base.cc.h index bc2dc9a..41a7bd6 100644 --- a/src/include/ranges/index_base.cc.h +++ b/src/include/ranges/index_base.cc.h @@ -146,7 +146,7 @@ namespace CNORXZ template Sptr moveToPtr(I&& i) { - return std::make_shared(std::forward(i)); + return std::make_shared(std::forward(i)); } template diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index bcf6189..4b371f7 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -173,6 +173,12 @@ namespace CNORXZ /** recursive index format */ decltype(auto) deepFormat() const { return THIS().deepFormat(); } + /** reformat index, return new index instance + @param f new format + @param s new sub-index sizes + */ + decltype(auto) reformat(const Vector& f, const Vector& s) const { return THIS().reformat(f,s); } + /** create a for-loop expression @tparam Xpr loop internal expression diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 3f2e0f1..08e7021 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -531,6 +531,44 @@ namespace CNORXZ [&](const auto&... e) { return concat(e...); } ); } + template + decltype(auto) + GMIndex::reformat(const Vector& f, const Vector& s) const + { + CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()"); + // f: input format + // s: input sizes + SizeT j = 0; + SizeT j0 = 0; + Arr nformat; + auto npack = iter<0,NI>( [&](auto i) { + SizeT si = 1; + //if(mIPack[i]->lmax().val() == 1){ + //std::get(npack) = mIPack[i]; + //} + // CHECK!!! + // TODO: DO NOT COPY SINGLE INDEX INSTANCES!!! + for(; si < mIPack[i]->lmax().val(); ++j){ + si *= s[i]; + CXZ_ASSERT(j < f.size(), "incompatible index formats"); + } + CXZ_ASSERT(si == mIPack[i]->lmax().val(), + "incompatible index formats: " << toString(s) << " vs " //!!! + ); + Vector nf(j-j0); + Vector ns(j-j0); + std::copy(f.begin()+j0,f.begin()+j,nf.begin()); + nformat[i] = *std::min_element(nf.begin(), nf.end()); + std::for_each(nf.begin(), nf.end(), [&](SizeT& x) + { CXZ_ASSERT(x % nformat[i].val() == 0, "incompatible"); x /= nformat[i].val(); } ); + std::copy(s.begin()+j0,s.begin()+j,ns.begin()); + return moveToPtr( mIPack[i]->reformat(nf,ns) ); + }, [](auto&... e) { return std::make_tuple( e... ); } ); + GMIndex,Indices...> oi { MFormat(nformat),SPack(npack) }; + oi = lex(); + return oi; + } + template GMIndex& GMIndex::setFormat(const FormatT& bs) { diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index 5faf4f1..ccdc64e 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -91,6 +91,10 @@ namespace CNORXZ const auto& lexFormat() const; RangePtr prange(const MIndex& last) const; auto deepFormat() const; + + /** @copydoc IndexInterface::reformat() */ + decltype(auto) reformat(const Vector& f, const Vector& s) const; + GMIndex& setFormat(const FormatT& bs); /** @copydoc IndexInterface::formatIsTrivial() */ diff --git a/src/include/ranges/prange.cc.h b/src/include/ranges/prange.cc.h index f670991..b4128e4 100644 --- a/src/include/ranges/prange.cc.h +++ b/src/include/ranges/prange.cc.h @@ -167,6 +167,17 @@ namespace CNORXZ return mOrig->deepFormat(); } + template + PIndex PIndex::reformat(const Vector& f, const Vector& s) const + { + CXZ_ASSERT(f.size() == 1, "expected format of dimension 1, got " << toString(f)); + CXZ_ASSERT(s.size() == 1, "expected sizes of dimension 1, got " << toString(s)); + CXZ_ASSERT(f[0] == 1, "trivial format ([1]), got " << toString(f)); + CXZ_ASSERT(s[0] == lmax().val(), "expected size to be equal to index size (" << + lmax().val() << "), got " << s[0]); + return *this; + } + template String PIndex::stringMeta() const { diff --git a/src/include/ranges/prange.h b/src/include/ranges/prange.h index 419212f..729ded2 100644 --- a/src/include/ranges/prange.h +++ b/src/include/ranges/prange.h @@ -56,6 +56,9 @@ namespace CNORXZ RangePtr prange(const PIndex& last) const; decltype(auto) deepFormat() const; + /** @copydoc IndexInterface::reformat() */ + PIndex reformat(const Vector& f, const Vector& s) const; + String stringMeta() const; decltype(auto) meta() const; PIndex& at(const MetaType& metaPos); diff --git a/src/include/ranges/srange.cc.h b/src/include/ranges/srange.cc.h index bffa17f..c8add42 100644 --- a/src/include/ranges/srange.cc.h +++ b/src/include/ranges/srange.cc.h @@ -177,6 +177,17 @@ namespace CNORXZ return 1; } + template + SIndex SIndex::reformat(const Vector& f, const Vector& s) const + { + CXZ_ASSERT(f.size() == 1, "expected format of dimension 1, got " << toString(f)); + CXZ_ASSERT(s.size() == 1, "expected sizes of dimension 1, got " << toString(s)); + CXZ_ASSERT(f[0] == 1, "trivial format ([1]), got " << toString(f)); + CXZ_ASSERT(s[0] == lmax().val(), "expected size to be equal to index size (" << + lmax().val() << "), got " << s[0]); + return *this; + } + template template decltype(auto) SIndex::ifor(const Xpr& xpr, F&& f) const diff --git a/src/include/ranges/srange.h b/src/include/ranges/srange.h index 6325126..3b8b560 100644 --- a/src/include/ranges/srange.h +++ b/src/include/ranges/srange.h @@ -62,6 +62,9 @@ namespace CNORXZ RangePtr prange(const SIndex& last) const; SizeT deepFormat() const; + /** @copydoc IndexInterface::reformat() */ + SIndex reformat(const Vector& f, const Vector& s) const; + template decltype(auto) ifor(const Xpr& xpr, F&& f) const; diff --git a/src/include/ranges/urange.cc.h b/src/include/ranges/urange.cc.h index 978610f..9131ebd 100644 --- a/src/include/ranges/urange.cc.h +++ b/src/include/ranges/urange.cc.h @@ -163,6 +163,17 @@ namespace CNORXZ return 1; } + template + UIndex UIndex::reformat(const Vector& f, const Vector& s) const + { + CXZ_ASSERT(f.size() == 1, "expected format of dimension 1, got " << toString(f)); + CXZ_ASSERT(s.size() == 1, "expected sizes of dimension 1, got " << toString(s)); + CXZ_ASSERT(f[0] == 1, "trivial format ([1]), got " << toString(f)); + CXZ_ASSERT(s[0] == lmax().val(), "expected size to be equal to index size (" << + lmax().val() << "), got " << s[0]); + return *this; + } + template size_t UIndex::dim() const // = 1 { diff --git a/src/include/ranges/urange.h b/src/include/ranges/urange.h index aec0577..534b2d9 100644 --- a/src/include/ranges/urange.h +++ b/src/include/ranges/urange.h @@ -67,6 +67,9 @@ namespace CNORXZ SizeT deepFormat() const; + /** @copydoc IndexInterface::reformat() */ + UIndex reformat(const Vector& f, const Vector& s) const; + template decltype(auto) ifor(const Xpr& xpr, F&& f) const; diff --git a/src/include/ranges/xindex.cc.h b/src/include/ranges/xindex.cc.h index ca866e4..5754c32 100644 --- a/src/include/ranges/xindex.cc.h +++ b/src/include/ranges/xindex.cc.h @@ -158,6 +158,12 @@ namespace CNORXZ return toVec( mI->deepFormat() ); } + template + XIndexPtr XIndex::reformat(const Vector& f, const Vector& s) const + { + return xindexPtr( moveToPtr( mI->reformat(f,s) ) ); + } + template String XIndex::stringMeta() const { diff --git a/src/include/ranges/xindex.h b/src/include/ranges/xindex.h index d7bed28..4dce7bf 100644 --- a/src/include/ranges/xindex.h +++ b/src/include/ranges/xindex.h @@ -52,6 +52,7 @@ namespace CNORXZ virtual UPos stepSize(const IndexId<0>& id) const = 0; virtual RangePtr prange(const XIndexPtr& last) const = 0; virtual Vector deepFormat() const = 0; + virtual XIndexPtr reformat(const Vector& f, const Vector& s) const = 0; virtual String stringMeta() const = 0; virtual DType meta() const = 0; @@ -104,6 +105,7 @@ namespace CNORXZ virtual UPos stepSize(const IndexId<0>& id) const override final; virtual RangePtr prange(const XIndexPtr& last) const override final; virtual Vector deepFormat() const override final; + virtual XIndexPtr reformat(const Vector& f, const Vector& s) const override final; virtual String stringMeta() const override final; virtual DType meta() const override final; diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index 59f03b5..547aa04 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -76,10 +76,10 @@ namespace CNORXZ const DPack& pack() const; RangePtr prange(const YIndex& last) const; Vector deepFormat() const; - YIndex& setFormat(const Vector& f, const Vector& s); const YFormat& format() const; const YFormat& lexFormat() const; YIndex& setFormat(const YFormat& bs); + YIndex reformat(const Vector& f, const Vector& s) const; /** @copydoc IndexInterface::formatIsTrivial() */ bool formatIsTrivial() const; diff --git a/src/lib/ranges/crange.cc b/src/lib/ranges/crange.cc index fc1924a..159c30f 100644 --- a/src/lib/ranges/crange.cc +++ b/src/lib/ranges/crange.cc @@ -139,6 +139,16 @@ namespace CNORXZ return 1; } + CIndex CIndex::reformat(const Vector& f, const Vector& s) const + { + CXZ_ASSERT(f.size() == 1, "expected format of dimension 1, got " << toString(f)); + CXZ_ASSERT(s.size() == 1, "expected sizes of dimension 1, got " << toString(s)); + CXZ_ASSERT(f[0] == 1, "trivial format ([1]), got " << toString(f)); + CXZ_ASSERT(s[0] == lmax().val(), "expected size to be equal to index size (" << + lmax().val() << "), got " << s[0]); + return *this; + } + bool CIndex::formatIsTrivial() const { return true; diff --git a/src/lib/ranges/dindex.cc b/src/lib/ranges/dindex.cc index 5e16be6..4c7e066 100644 --- a/src/lib/ranges/dindex.cc +++ b/src/lib/ranges/dindex.cc @@ -177,6 +177,11 @@ namespace CNORXZ return mI->deepFormat(); } + DIndex DIndex::reformat(const Vector& f, const Vector& s) const + { + return DIndex(mI->reformat(f,s)); + } + bool DIndex::formatIsTrivial() const { return true; diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index 9f7aac5..41067a6 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -396,7 +396,7 @@ namespace CNORXZ return o; } - YIndex& YIndex::setFormat(const Vector& f, const Vector& s) + YIndex YIndex::reformat(const Vector& f, const Vector& s) const { CXZ_ASSERT(f.size() == s.size(), "input error: f.size() != s.size()"); // f: input format @@ -404,10 +404,11 @@ namespace CNORXZ SizeT j = 0; SizeT j0 = 0; Vector nformat(dim()); + Vector npack(dim()); for(SizeT i = 0; i != dim(); ++i){ SizeT si = 1; if(mIs[i]->lmax().val() == 1){ - continue; + npack[i] = mIs[i]; } for(; si < mIs[i]->lmax().val(); ++j){ si *= s[i]; @@ -421,13 +422,13 @@ namespace CNORXZ std::copy(f.begin()+j0,f.begin()+j,nf.begin()); nformat[i] = *std::min_element(nf.begin(), nf.end()); std::for_each(nf.begin(), nf.end(), [&](SizeT& x) - { CXZ_ASSERT(x % mFormat[i].val() == 0, "incompatible"); x /= nformat[i].val(); } ); + { CXZ_ASSERT(x % nformat[i].val() == 0, "incompatible"); x /= nformat[i].val(); } ); std::copy(s.begin()+j0,s.begin()+j,ns.begin()); - CXZ_ERROR("implement for all indices!!!"); - //mIs[i]->setFormat(nf,ns); + npack[i] = mIs[i]->reformat(nf,ns); } - mFormat = nformat; - return *this; + YIndex oi ( YFormat(nformat), npack ); + oi = lex(); + return oi; } bool YIndex::formatIsTrivial() const