diff --git a/src/include/ranges/rbase_def.h b/src/include/ranges/rbase_def.h index fba3ff9..3cffe08 100644 --- a/src/include/ranges/rbase_def.h +++ b/src/include/ranges/rbase_def.h @@ -54,6 +54,18 @@ namespace MultiArrayTools // single_range.h template class SingleIndex; + + // subrange.h + template + class SubIndex; + + // subrange.h + template + class SubRangeFactory; + + // subrange.h + template + class SubRange; // multi_range.h template diff --git a/src/include/ranges/rpheader.h b/src/include/ranges/rpheader.h index c3c4142..4dfd831 100644 --- a/src/include/ranges/rpheader.h +++ b/src/include/ranges/rpheader.h @@ -5,6 +5,7 @@ #include "single_range.h" #include "multi_range.h" #include "container_range.h" +#include "subrange.h" //#include "anonymous_range.h" //#endif diff --git a/src/include/ranges/subrange.h b/src/include/ranges/subrange.h index 8ded014..24cbb4c 100644 --- a/src/include/ranges/subrange.h +++ b/src/include/ranges/subrange.h @@ -24,12 +24,14 @@ namespace MultiArrayTools } template - class SubIndex : public IndexInterface> + class SubIndex : public IndexInterface,typename Index::MetaType> { - typedef IndexInterface> IB; - typedef typename SubIndex::MetaType MetaType; - typedef SubRange::RangeType> RangeType; - typedef SubIndex IndexType; + public: + + typedef IndexInterface,typename Index::MetaType> IB; + typedef typename Index::MetaType MetaType; + typedef SubRange RangeType; + typedef SubIndex IType; SubIndex(const std::shared_ptr& range); @@ -37,7 +39,7 @@ namespace MultiArrayTools static constexpr size_t totalDim() { return typename Index::totalDim(); } static constexpr size_t sDim() { return typename Index::sDim(); } - static constexpr SpaceType STYPE = typename Index::STYPE; + static constexpr SpaceType STYPE = Index::STYPE; IndexType type() const; @@ -45,16 +47,18 @@ namespace MultiArrayTools SubIndex& operator++(); SubIndex& operator--(); + SubIndex& operator()(const std::shared_ptr& ind); // set full index + int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); std::string stringMeta() const; - U meta() const; - const U* metaPtr() const; - SubIndex& at(const U& metaPos); - size_t posAt(const U& metaPos) const; + MetaType meta() const; + const MetaType* metaPtr() const; + SubIndex& at(const MetaType& metaPos); + size_t posAt(const MetaType& metaPos) const; - bool isMeta(const U& metaPos) const; + bool isMeta(const MetaType& metaPos) const; size_t dim(); // = 1 bool last(); @@ -95,7 +99,7 @@ namespace MultiArrayTools SubRangeFactory(const std::shared_ptr& fullRange, const std::vector& subset); std::shared_ptr create(); - } + }; template class SubRange : public RangeInterface> @@ -116,16 +120,17 @@ namespace MultiArrayTools virtual std::string stringMeta(size_t pos) const final; virtual std::vector data() const final; - bool isMeta(const U& metaPos) const; + bool isMeta(const MetaType& metaPos) const; - const U& get(size_t pos) const; - size_t getMeta(const U& metaPos) const; + const MetaType& get(size_t pos) const; + size_t getMeta(const MetaType& metaPos) const; virtual IndexType begin() const final; virtual IndexType end() const final; std::shared_ptr fullRange() const; const std::vector& subset() const; + std::shared_ptr> outRange() const; friend SubRangeFactory; @@ -156,8 +161,8 @@ namespace MultiArrayTools template SubIndex::SubIndex(const std::shared_ptr& range) : - IndexInterface>(range, 0), - mExplicitRangePtr(std::dynamic_pointer_cast(IB::mRangePtr)), + IndexInterface,typename Index::MetaType>(range, 0), + mExplicitRangePtr(std::dynamic_pointer_cast(IB::mRangePtr)) { mFullIndex = std::make_shared(mExplicitRangePtr->fullRange()); } @@ -170,7 +175,7 @@ namespace MultiArrayTools } template - SubIndex& SubIndex::operator=(size_t pos) + SubIndex& SubIndex::operator=(size_t pos) { IB::mPos = pos; (*mFullIndex) = mExplicitRangePtr->subset()[IB::mPos]; @@ -178,7 +183,7 @@ namespace MultiArrayTools } template - SubIndex& SubIndex::operator++() + SubIndex& SubIndex::operator++() { ++IB::mPos; (*mFullIndex) = mExplicitRangePtr->subset()[IB::mPos]; @@ -186,13 +191,21 @@ namespace MultiArrayTools } template - SubIndex& SubIndex::operator--() + SubIndex& SubIndex::operator--() { --IB::mPos; (*mFullIndex) = mExplicitRangePtr->subset()[IB::mPos]; return *this; } + template + SubIndex& SubIndex::operator()(const std::shared_ptr& ind) + { + assert(mFullIndex->range() == ind->range()); + mFullIndex = ind; + return *this; + } + template int SubIndex::pp(std::intptr_t idxPtrNum) { @@ -210,38 +223,39 @@ namespace MultiArrayTools template std::string SubIndex::stringMeta() const { - return std::dynamic_pointer_cast const>( IB::mRangePtr )->stringMeta(IB::mPos); + return std::dynamic_pointer_cast const>( IB::mRangePtr )->stringMeta(IB::mPos); } template - U SubIndex::meta() const + typename SubIndex::MetaType SubIndex::meta() const { + MetaType* x = nullptr; return MetaPtrHandle::RangeType::HASMETACONT>::getMeta - ( mMetaPtr, IB::mPos, mExplicitRangePtr ); + ( x, IB::mPos, mExplicitRangePtr ); } template - const U* SubIndex::metaPtr() const + const typename SubIndex::MetaType* SubIndex::metaPtr() const { assert(0); // not sure where it is used return mFullIndex->metaPtr(); } template - SubIndex& SubIndex::at(const U& metaPos) + SubIndex& SubIndex::at(const MetaType& metaPos) { (*this) = mExplicitRangePtr->getMeta( metaPos ); return *this; } template - size_t SubIndex::posAt(const U& metaPos) const + size_t SubIndex::posAt(const MetaType& metaPos) const { return mExplicitRangePtr->getMeta( metaPos ); } template - bool SubIndex::isMeta(const U& metaPos) const + bool SubIndex::isMeta(const MetaType& metaPos) const { return mExplicitRangePtr->isMeta( metaPos ); } @@ -265,7 +279,7 @@ namespace MultiArrayTools } template - std::shared_ptr::RangeType> SubIndex::range() + std::shared_ptr::RangeType> SubIndex::range() { return mExplicitRangePtr; } @@ -303,7 +317,7 @@ namespace MultiArrayTools -> For,SubExpr> { return For,SubExpr> - (this, /**/, SubExpr( mFullIndex, /**/ ) ); + (this, 1, SubExpr( mFullIndex, &mExplicitRangePtr->subset(), step, ex ) ); } /************************ @@ -331,7 +345,7 @@ namespace MultiArrayTools template SubRange::SubRange(const std::shared_ptr& fullRange, const std::vector& subset) : - RangeInterface>(), + RangeInterface>(), mFullRange(fullRange), mSubSet(subset) {} template @@ -362,7 +376,8 @@ namespace MultiArrayTools h.multiple = 0; return h; } - + + template std::string SubRange::stringMeta(size_t pos) const { return xToString(get(pos)); @@ -386,7 +401,7 @@ namespace MultiArrayTools } template - bool SubRange::isMeta(const U& metaPos) const + bool SubRange::isMeta(const MetaType& metaPos) const { for(size_t i = 0; i != size(); ++i){ if(get(i) == metaPos){ @@ -397,13 +412,13 @@ namespace MultiArrayTools } template - const SubRange::MetaType& SubRange::get(size_t pos) const + const typename SubRange::MetaType& SubRange::get(size_t pos) const { return mFullRange->get( mSubSet[pos] ); } template - size_t SubRange::getMeta(const U& metaPos) const + size_t SubRange::getMeta(const MetaType& metaPos) const { for(size_t i = 0; i != size(); ++i){ if(get(i) == metaPos){ @@ -414,7 +429,7 @@ namespace MultiArrayTools } template - SubRange::IndexType SubRange::begin() const + typename SubRange::IndexType SubRange::begin() const { SubRange::IndexType i( std::dynamic_pointer_cast> ( std::shared_ptr( RB::mThis ) ) ); @@ -423,7 +438,7 @@ namespace MultiArrayTools } template - SubRange::IndexType SubRange::end() const + typename SubRange::IndexType SubRange::end() const { SubRange::IndexType i( std::dynamic_pointer_cast> ( std::shared_ptr( RB::mThis ) ) ); @@ -443,6 +458,17 @@ namespace MultiArrayTools return mSubSet; } + template + std::shared_ptr::MetaType,SpaceType::ANY>> SubRange::outRange() const + { + std::vector ometa(mSubSet.size()); + size_t i = 0; + for(auto& x: mSubSet){ + ometa[i++] = mFullRange->get(x); + } + SingleRangeFactory srf(ometa); + return std::dynamic_pointer_cast>( srf.create() ); + } } #endif diff --git a/src/include/xfor/xfor.h b/src/include/xfor/xfor.h index 4b11d76..c8a8b4f 100644 --- a/src/include/xfor/xfor.h +++ b/src/include/xfor/xfor.h @@ -132,7 +132,57 @@ namespace MultiArrayHelper auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; auto extension() const -> ExtType; }; - + + template + class SubExpr : public ExpressionBase + { + private: + SubExpr() = default; + + const IndexClass* mIndPtr; + size_t mSPos; + size_t mMax; + + Expr mExpr; + typedef decltype(mExpr.rootSteps()) ExtType; + ExtType mExt; + + const std::vector* mSubSet; + size_t mStep; + + mutable ExtType mRootSteps; + + public: + typedef ExpressionBase EB; + + static constexpr size_t LAYER = Expr::LAYER + 1; + static constexpr size_t SIZE = Expr::SIZE; + + SubExpr(const SubExpr& in) = default; + SubExpr& operator=(const SubExpr& in) = default; + SubExpr(SubExpr&& in) = default; + SubExpr& operator=(SubExpr&& in) = default; + + SubExpr(const std::shared_ptr& indPtr, + const std::vector* subset, + size_t step, Expr expr); + + SubExpr(const IndexClass* indPtr, + const std::vector* subset, + size_t step, Expr expr); + + + inline void operator()(size_t mlast, DExt last) const override final; + inline void operator()(size_t mlast, ExtType last) const; + inline void operator()(size_t mlast = 0) const override final; + + DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final; + DExt dExtension() const override final; + + auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; + auto extension() const -> ExtType; + }; + template class For : public ExpressionBase { @@ -270,7 +320,7 @@ namespace MultiArrayHelper template For::For(const std::shared_ptr& indPtr, size_t step, Expr expr) : - mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), + mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast( mIndPtr ))) { assert(mIndPtr != nullptr); @@ -432,6 +482,96 @@ namespace MultiArrayHelper sizeof(ExtType)/sizeof(size_t)); } + /**************** + * SubExpr * + ****************/ + + template + SubExpr::SubExpr(const std::shared_ptr& indPtr, + const std::vector* subset, + size_t step, + Expr expr) : + mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), + mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast( mIndPtr ))), + mSubSet(subset), mStep(step) + { + assert(mIndPtr != nullptr); + } + + template + SubExpr::SubExpr(const IndexClass* indPtr, + const std::vector* subset, + size_t step, + Expr expr) : + mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), + mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast( mIndPtr ))), + mSubSet(subset), mStep(step) + { + assert(mIndPtr != nullptr); + } + + template + inline void SubExpr::operator()(size_t mlast, DExt last) const + { + operator()(mlast, *reinterpret_cast(last.first)); + } + + template + inline void SubExpr::operator()(size_t mlast, + ExtType last) const + { + // INCLUDE FOR LOOP HERE AGIAN !!!! + const size_t pos = (*mSubSet)[mlast]; + const size_t mnpos = mlast * mStep; + VCHECK(mlast); + VCHECK(pos); + VCHECK(mnpos); + const ExtType npos = last + mExt*pos; + VCHECK(npos.val()); + VCHECK(npos.next().val()); + mExpr(mnpos, npos); + } + + template + inline void SubExpr::operator()(size_t mlast) const + { + const ExtType last; + const size_t pos = (*mSubSet)[mlast]; + const size_t mnpos = mlast * mStep; + const ExtType npos = last + mExt*pos; + mExpr(mnpos, npos); + } + + + template + auto SubExpr::rootSteps(std::intptr_t iPtrNum) const + -> ExtType + { + return mExpr.rootSteps(iPtrNum); + } + + template + auto SubExpr::extension() const + -> ExtType + { + return mExt; + } + + template + DExt SubExpr::dRootSteps(std::intptr_t iPtrNum) const + { + mRootSteps = rootSteps(iPtrNum); + return std::make_pair(reinterpret_cast(&mRootSteps), + sizeof(ExtType)/sizeof(size_t)); + } + + template + DExt SubExpr::dExtension() const + { + return std::make_pair(reinterpret_cast(&mExt), + sizeof(ExtType)/sizeof(size_t)); + } + /*************************** * DynamicExpression * ***************************/ diff --git a/src/tests/op_unit_test.cc b/src/tests/op_unit_test.cc index 5917d02..a2b002d 100644 --- a/src/tests/op_unit_test.cc +++ b/src/tests/op_unit_test.cc @@ -159,6 +159,38 @@ namespace { -14.364, -1.868, -25.703, 13.836, 23.563, 41.339 }; }; + class OpTest_Sub : public ::testing::Test + { + protected: + + typedef SingleRangeFactory SRF; + typedef SRF::oType SRange; + + OpTest_Sub() + { + swapFactory(rfbptr, {'x', 'l'} ); + sr1ptr = std::dynamic_pointer_cast( rfbptr->create() ); + + swapFactory(rfbptr, {'1', '2', '3'} ); + sr2ptr = std::dynamic_pointer_cast( rfbptr->create() ); + + swapFactory(rfbptr, {'a', 'b'} ); + sr3ptr = std::dynamic_pointer_cast( rfbptr->create() ); + + } + + std::shared_ptr rfbptr; + std::shared_ptr sr1ptr; + std::shared_ptr sr2ptr; + std::shared_ptr sr3ptr; + + std::vector v1 = { 2.917, 9.436, 0.373, 0.353, 4.005, 1.070, + -14.364, -1.868, -25.703, 13.836, 23.563, 41.339 }; + + std::vector v2 = { 0.353, 4.005, 1.070, 2.310, 9.243, 2.911 }; + }; + + class MapTest : public ::testing::Test { protected: @@ -506,6 +538,59 @@ namespace { EXPECT_EQ( fabs( res.at('g') - (7.192+5.063) ) < 0.0001, true ); } + TEST_F(OpTest_Sub, Exec) + { + MultiArray ma1(sr1ptr, sr2ptr, sr3ptr, v1); + MultiArray ma2(sr3ptr, sr2ptr, v2); + + SubRangeFactory subf(sr2ptr, std::vector({0,2})); + auto subptr = MAT::createExplicit(subf); + + MultiArray,SRange,SRange> res(subptr,sr3ptr,sr1ptr,0.); + + auto i1 = MAT::getIndex( sr1ptr ); + auto i2 = MAT::getIndex( sr2ptr ); + auto i3 = MAT::getIndex( sr3ptr ); + auto si = MAT::getIndex( subptr ); + (*si)(i2); + + res(si,i3,i1) = ma2(i3,i2) - ma1(i1,i2,i3); + + EXPECT_EQ( res.size(), 8 ); + EXPECT_EQ( res.vdata().size(), 8 ); + EXPECT_EQ( MAT::rptr<0>( res )->size(), 2 ); + + EXPECT_EQ( MAT::rptr<0>( res )->isMeta('1'), true ); + EXPECT_EQ( MAT::rptr<0>( res )->isMeta('3'), true ); + + EXPECT_EQ( xround( res.at(mkt('1','a','x')) ), xround(ma2.at(mkt('a','1')) - ma1.at(mkt('x','1','a'))) ); + EXPECT_EQ( xround( res.at(mkt('1','a','l')) ), xround(ma2.at(mkt('a','1')) - ma1.at(mkt('l','1','a'))) ); + + EXPECT_EQ( xround( res.at(mkt('1','b','x')) ), xround(ma2.at(mkt('b','1')) - ma1.at(mkt('x','1','b'))) ); + EXPECT_EQ( xround( res.at(mkt('1','b','l')) ), xround(ma2.at(mkt('b','1')) - ma1.at(mkt('l','1','b'))) ); + + EXPECT_EQ( xround( res.at(mkt('3','a','x')) ), xround(ma2.at(mkt('a','3')) - ma1.at(mkt('x','3','a'))) ); + EXPECT_EQ( xround( res.at(mkt('3','a','l')) ), xround(ma2.at(mkt('a','3')) - ma1.at(mkt('l','3','a'))) ); + + EXPECT_EQ( xround( res.at(mkt('3','b','x')) ), xround(ma2.at(mkt('b','3')) - ma1.at(mkt('x','3','b'))) ); + EXPECT_EQ( xround( res.at(mkt('3','b','l')) ), xround(ma2.at(mkt('b','3')) - ma1.at(mkt('l','3','b'))) ); + + auto res2 = res.format( subptr->outRange(), sr3ptr, sr1ptr ); + + EXPECT_EQ( xround( res2.at(mkt('1','a','x')) ), xround(ma2.at(mkt('a','1')) - ma1.at(mkt('x','1','a'))) ); + EXPECT_EQ( xround( res2.at(mkt('1','a','l')) ), xround(ma2.at(mkt('a','1')) - ma1.at(mkt('l','1','a'))) ); + + EXPECT_EQ( xround( res2.at(mkt('1','b','x')) ), xround(ma2.at(mkt('b','1')) - ma1.at(mkt('x','1','b'))) ); + EXPECT_EQ( xround( res2.at(mkt('1','b','l')) ), xround(ma2.at(mkt('b','1')) - ma1.at(mkt('l','1','b'))) ); + + EXPECT_EQ( xround( res2.at(mkt('3','a','x')) ), xround(ma2.at(mkt('a','3')) - ma1.at(mkt('x','3','a'))) ); + EXPECT_EQ( xround( res2.at(mkt('3','a','l')) ), xround(ma2.at(mkt('a','3')) - ma1.at(mkt('l','3','a'))) ); + + EXPECT_EQ( xround( res2.at(mkt('3','b','x')) ), xround(ma2.at(mkt('b','3')) - ma1.at(mkt('x','3','b'))) ); + EXPECT_EQ( xround( res2.at(mkt('3','b','l')) ), xround(ma2.at(mkt('b','3')) - ma1.at(mkt('l','3','b'))) ); + + } + TEST_F(OpTest_MDim, ExecOp1) { MultiArray res(sr2ptr,sr4ptr);