From 9e5c51428a75f42bc7dc89d065df146481cb6b49 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Mon, 20 Aug 2018 17:50:04 +0200 Subject: [PATCH] various fixes and adds -> map range test works --- src/include/arith.h | 4 + src/include/functional_multi_array.h | 13 +++ src/include/map_range.h | 138 +++++++++++++++++---------- src/include/multi_array_base.h | 34 +++++-- src/include/multi_array_operation.h | 6 +- src/include/ranges/container_range.h | 5 +- src/include/ranges/single_range.h | 11 ++- src/tests/op_unit_test.cc | 68 +++++++++++++ 8 files changed, 211 insertions(+), 68 deletions(-) diff --git a/src/include/arith.h b/src/include/arith.h index 76cfb71..af47bdc 100644 --- a/src/include/arith.h +++ b/src/include/arith.h @@ -63,6 +63,7 @@ namespace MultiArrayTools struct plus : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; + using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { @@ -74,6 +75,7 @@ namespace MultiArrayTools struct minus : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; + using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { @@ -85,6 +87,7 @@ namespace MultiArrayTools struct multiplies : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; + using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { @@ -96,6 +99,7 @@ namespace MultiArrayTools struct divides : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; + using StaticFunctionBase, T, T>::apply; static inline T apply(T a1, T a2) { diff --git a/src/include/functional_multi_array.h b/src/include/functional_multi_array.h index 3429b9c..a919417 100644 --- a/src/include/functional_multi_array.h +++ b/src/include/functional_multi_array.h @@ -104,6 +104,7 @@ namespace MultiArrayTools typedef ContainerIndex IndexType; //typedef typename CRange::IndexType IndexType; typedef MultiArray MAType; + typedef T value_type; private: mutable T mVal; @@ -116,6 +117,8 @@ namespace MultiArrayTools DEFAULT_MEMBERS(FunctionalMultiArray); FunctionalMultiArray(const std::shared_ptr&... ranges, const Function& func); FunctionalMultiArray(const std::shared_ptr&... ranges); + FunctionalMultiArray(const typename CRange::Space& space); + FunctionalMultiArray(const typename CRange::Space& space, const Function& func); virtual const T& operator[](const IndexType& i) const override; virtual const T& at(const typename CRange::IndexType::MetaType& meta) const override; @@ -186,6 +189,16 @@ namespace MultiArrayTools FunctionalMultiArray::FunctionalMultiArray(const std::shared_ptr&... ranges) : MultiArrayBase(ranges...) {} + template + FunctionalMultiArray::FunctionalMultiArray(const typename CRange::Space& space) : + MultiArrayBase(space) {} + + template + FunctionalMultiArray::FunctionalMultiArray(const typename CRange::Space& space, + const Function& func) : + MultiArrayBase(space), mFunc(func) {} + + template const T& FunctionalMultiArray::operator[](const IndexType& i) const { diff --git a/src/include/map_range.h b/src/include/map_range.h index e434641..a3aea41 100644 --- a/src/include/map_range.h +++ b/src/include/map_range.h @@ -29,17 +29,17 @@ namespace MultiArrayTools template auto mkMapOp(const MA& ma, const std::tuple...>& itp) - -> ConstOperationRoot + -> decltype(PackNum::mkMapOp(ma, itp)) { return PackNum::mkMapOp(ma, itp); } - template + template class OpExpr { public: typedef SingleIndex OIType; - typedef typename MapF::IndexPack IndexPack; + //typedef typename MapF::IndexPack IndexPack; static constexpr size_t LAYER = Expr::LAYER + 1; static constexpr size_t SIZE = Expr::SIZE; @@ -82,13 +82,13 @@ namespace MultiArrayTools std::tuple > IB; typedef std::tuple...> IndexPack; typedef std::tuple MetaType; - typedef MapRange RangeType; + typedef MapRange RangeType; typedef MapIndex IType; typedef SingleIndex OIType; static constexpr IndexType sType() { return IndexType::MULTI; } static constexpr size_t sDim() { return sizeof...(Indices); } - static constexpr size_t totalDim() { return mkTotalDim(); } + static constexpr size_t totalDim() { return mkTotalDim(); } static constexpr SpaceType STYPE = SpaceType::ANY; @@ -148,23 +148,23 @@ namespace MultiArrayTools MetaType meta() const; MapIndex& at(const MetaType& metaPos); - size_t dim(); - bool first(); - bool last(); - std::shared_ptr range(); + size_t dim() const; + bool first() const; + bool last() const; + std::shared_ptr range() const; template auto getPtr() -> decltype( std::get( mIPack ) )&; - size_t getStepSize(size_t n); + size_t getStepSize(size_t n) const; std::string id() const; - void print(size_t offset); + void print(size_t offset) const; template auto ifor(Exprs exs) const - -> decltype(RPackNum::mkFor - (mIPack, OpExpr( range()->map(), mIPack, mOutIndex, exs ) ) ); + -> decltype(RPackNum::mkForh + (mIPack, OpExpr( range()->map(), mIPack, mOutIndex, exs ) ) ); /* template @@ -208,12 +208,12 @@ namespace MultiArrayTools ******************/ template - class MapRange : public RangeInterface > + class MapRange : public RangeInterface > { public: typedef RangeBase RB; typedef std::tuple...> Space; - typedef MapIndex IndexType; + typedef MapIndex IndexType; typedef MapRange RangeType; typedef SingleRange ORType; typedef SingleRangeFactory ORFType; @@ -230,10 +230,14 @@ namespace MultiArrayTools Space mSpace; const MapF& mMapf; std::shared_ptr mOutRange; + MultiArray mMapMult; + private: + void mkOutRange(); + public: - static const size_t sdim = sizeof...(Ranges); + static constexpr size_t sdim = sizeof...(Ranges); template auto get() const -> decltype( *std::get( mSpace ) )&; @@ -257,6 +261,8 @@ namespace MultiArrayTools virtual IndexType begin() const final; virtual IndexType end() const final; + const MultiArray& mapMultiplicity() const; + template auto cat(const std::shared_ptr >& erange) -> std::shared_ptr >; @@ -287,42 +293,44 @@ namespace MultiArrayTools * OpExpr * **************/ - template - OpExpr::OpExpr(const MapF& mapf, const IndexPack& ipack, - const std::shared_ptr oind, Expr ex) : + template + OpExpr::OpExpr(const MapF& mapf, const IndexPack& ipack, + const std::shared_ptr oind, Expr ex) : mIndPtr(oind.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mExpr(ex), - mExt(ex.rootSteps( reinterpret_cast( mIndPtr.get() ))), - mOp(mapf, ipack) + mOp(mkMapOp(mapf, ipack)), + //mExt(ex.rootSteps( reinterpret_cast( mIndPtr ))) + mExt( mOp.rootSteps( reinterpret_cast( mIndPtr) ).extend + ( mExpr.rootSteps( reinterpret_cast( mIndPtr) ) ) ) { assert(mIndPtr != nullptr); //VCHECK(mIndPtr->id()); //VCHECK(mIndPtr->max()); } - template - inline void OpExpr::operator()(size_t mlast, - ExtType last) const + template + inline void OpExpr::operator()(size_t mlast, + ExtType last) const { constexpr size_t NEXT = Op::SIZE; const ExtType npos = last; - const size_t pos = mIndPtr->getMeta( mOp.get( npos ) ); + const size_t pos = mIndPtr->posAt( mOp.get( npos ) ); const size_t mnpos = PosForward::value(mlast, mMax, pos); mExpr(mnpos, Getter::template getX( npos ) ); } - template - inline void OpExpr::operator()(size_t mlast) const + template + inline void OpExpr::operator()(size_t mlast) const { const ExtType last; constexpr size_t NEXT = Op::SIZE; const ExtType npos = last; - const size_t pos = mIndPtr->at( mOp.get( npos ) ).pos(); + const size_t pos = mIndPtr->posAt( mOp.get( npos ) ); const size_t mnpos = PosForward::value(mlast, mMax, pos); mExpr(mnpos, Getter::template getX( npos )); } - template - auto OpExpr::rootSteps(std::intptr_t iPtrNum) const + template + auto OpExpr::rootSteps(std::intptr_t iPtrNum) const -> ExtType { return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) ); @@ -364,7 +372,8 @@ namespace MultiArrayTools IB::mPos = RPackNum::makePos(mIPack); std::get(mBlockSizes) = 1; RPackNum::initBlockSizes(mBlockSizes, mIPack); // has one more element! - mOutIndex = std::dynamic_pointer_cast( IB::mRangePtr )->outRange()->begin(); + mOutIndex = std::make_shared + ( std::dynamic_pointer_cast( IB::mRangePtr )->outRange()->begin() ); } template @@ -484,26 +493,26 @@ namespace MultiArrayTools } template - size_t MapIndex::dim() + size_t MapIndex::dim() const { return sizeof...(Indices); } template - bool MapIndex::first() + bool MapIndex::first() const { return IB::mPos == 0; } template - bool MapIndex::last() + bool MapIndex::last() const { return IB::mPos == IB::mMax - 1; } template std::shared_ptr::RangeType> - MapIndex::range() + MapIndex::range() const { return std::dynamic_pointer_cast( IB::mRangePtr ); } @@ -516,7 +525,7 @@ namespace MultiArrayTools } template - size_t MapIndex::getStepSize(size_t n) + size_t MapIndex::getStepSize(size_t n) const { if(n >= sizeof...(Indices)){ assert(0); @@ -532,7 +541,7 @@ namespace MultiArrayTools } template - void MapIndex::print(size_t offset) + void MapIndex::print(size_t offset) const { if(offset == 0){ std::cout << " === " << std::endl; @@ -546,11 +555,11 @@ namespace MultiArrayTools template template auto MapIndex::ifor(Exprs exs) const - -> decltype(RPackNum::mkFor - (mIPack, OpExpr( range()->map(), mIPack, mOutIndex, exs ) ) ) + -> decltype(RPackNum::mkForh + (mIPack, OpExpr( range()->map(), mIPack, mOutIndex, exs ) ) ) { - return RPackNum::mkFor - (mIPack, OpExpr( range()->map(), mIPack, mOutIndex, exs ) ); + return RPackNum::mkForh + (mIPack, OpExpr( range()->map(), mIPack, mOutIndex, exs ) ); } /* template @@ -603,7 +612,7 @@ namespace MultiArrayTools std::vector pv(sizeof...(Ranges)); RPackNum::RangesToVec(ptp, pv); pv.push_back( reinterpret_cast - ( &std::dynamic_pointer_cast( mProd ).mMapf ) ); + ( &std::dynamic_pointer_cast( mProd )->mMapf ) ); MapRangeFactoryProductMap::mAleadyCreated[mProd] = pv; out = mProd; } @@ -614,15 +623,36 @@ namespace MultiArrayTools * MapRange * ******************/ + template + void MapRange::mkOutRange() + { + //FunctionalMultiArray fma(mSpace, mMapf); + std::map mult; + for(auto ii = mMapf.begin(); ii.max() != ii.pos(); ++ii) { + mult[mMapf[ii]]++; + } + + std::vector outmeta(mult.size()); + std::vector outmult(mult.size()); + + size_t cnt = 0; + for(auto& x: mult){ + outmeta[cnt] = x.first; + outmult[cnt] = x.second; + ++cnt; + } + + ORFType orf(outmeta); + mOutRange = std::dynamic_pointer_cast( orf.create() ); + mMapMult = MultiArray( mOutRange, outmult ); + } + template MapRange::MapRange(const MapF& mapf, const std::shared_ptr&... rs) : mSpace(std::make_tuple(rs...)), mMapf(mapf) { - std::vector outmeta; - // set !!!! - ORFType orf(outmeta); - mOutRange = std::dynamic_pointer_cast( orf.create() ); + mkOutRange(); } template @@ -630,10 +660,7 @@ namespace MultiArrayTools mSpace( space ), mMapf(mapf) { - std::vector outmeta; - // set !!!! - ORFType orf(outmeta); - mOutRange = std::dynamic_pointer_cast( orf.create() ); + mkOutRange(); } template @@ -712,7 +739,7 @@ namespace MultiArrayTools template typename MapRange::IndexType MapRange::begin() const { - MapIndex + MapIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = 0; @@ -722,13 +749,20 @@ namespace MultiArrayTools template typename MapRange::IndexType MapRange::end() const { - MapIndex + MapIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis )) ); i = size(); return i; } + template + auto MapRange::mapMultiplicity() const + -> const MultiArray& + { + return mMapMult; + } + template template auto MapRange::cat(const std::shared_ptr >& erange) diff --git a/src/include/multi_array_base.h b/src/include/multi_array_base.h index ebc5f92..684dc27 100644 --- a/src/include/multi_array_base.h +++ b/src/include/multi_array_base.h @@ -63,8 +63,8 @@ namespace MultiArrayTools operator()(const std::shared_ptr&... inds) const; template - ConstOperationRoot - operator()(const std::shared_ptr&... inds) const; + ConstOperationRoot + m(const std::shared_ptr&... inds) const; virtual bool isInit() const; @@ -111,8 +111,12 @@ namespace MultiArrayTools virtual OperationRoot operator()(const std::shared_ptr&... inds); template - ConstOperationRoot - operator()(const std::shared_ptr&... inds); + OperationRoot + m(const std::shared_ptr&... inds); + + template + ConstOperationRoot + m(const std::shared_ptr&... inds) const; }; @@ -210,12 +214,12 @@ namespace MultiArrayTools template template - ConstOperationRoot - MultiArrayBase::operator()(const std::shared_ptr&... inds) const + ConstOperationRoot + MultiArrayBase::m(const std::shared_ptr&... inds) const { static_assert(sizeof...(SRanges) == sizeof...(MappedRanges), "number of mapped ranges must be equal to number of original ranges"); - return (*this)(MapResult(inds)...); // NO !!!!! + return ConstOperationRoot(*this, inds...); } template @@ -281,12 +285,22 @@ namespace MultiArrayTools template template - ConstOperationRoot - MutableMultiArrayBase::operator()(const std::shared_ptr&... inds) + OperationRoot + MutableMultiArrayBase::m(const std::shared_ptr&... inds) { static_assert(sizeof...(SRanges) == sizeof...(MappedRanges), "number of mapped ranges must be equal to number of original ranges"); - return (*this)(MapResult(inds)...); + return OperationRoot(*this, inds...); + } + + template + template + ConstOperationRoot + MutableMultiArrayBase::m(const std::shared_ptr&... inds) const + { + static_assert(sizeof...(SRanges) == sizeof...(MappedRanges), + "number of mapped ranges must be equal to number of original ranges"); + return ConstOperationRoot(*this, inds...); } } // end namespace MultiArrayTools diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index fc0343e..337554e 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -159,7 +159,7 @@ namespace MultiArrayTools //MultiArrayBase const& mArrayRef; const T* mDataPtr; IndexType mIndex; - std::shared_ptr > mMaPtr; + //std::shared_ptr > mMaPtr; }; template @@ -545,8 +545,8 @@ namespace MultiArrayTools ConstOperationRoot(std::shared_ptr > maptr, const std::shared_ptr&... indices) : mDataPtr(maptr->data()), - mIndex(maptr->begin()), - mMaPtr(maptr) + mIndex(maptr->begin()) + //mMaPtr(maptr) { mIndex(indices...); } diff --git a/src/include/ranges/container_range.h b/src/include/ranges/container_range.h index cda6287..f55983f 100644 --- a/src/include/ranges/container_range.h +++ b/src/include/ranges/container_range.h @@ -42,7 +42,8 @@ namespace MultiArrayTools bool mExternControl = false; IndexPack mIPack; std::array mBlockSizes; - const T* mData; + const T* mData = nullptr; + //const MultiArrayBase* mMa = nullptr; std::intptr_t mObjPtrNum; public: @@ -465,12 +466,14 @@ namespace MultiArrayTools template const T& ContainerIndex::operator*() const { + //return mMa[*this]; return mData[IB::mPos]; } template const T* ContainerIndex::operator->() const { + //return &mMa[*this]; return &mData[IB::mPos]; } diff --git a/src/include/ranges/single_range.h b/src/include/ranges/single_range.h index c865fcf..e3d18a0 100644 --- a/src/include/ranges/single_range.h +++ b/src/include/ranges/single_range.h @@ -8,7 +8,7 @@ #include #include -//#include "base_def.h" +#include "base_def.h" //#include "ranges/rpack_num.h" #include "ranges/index_base.h" #include "ranges/range_base.h" @@ -57,6 +57,7 @@ namespace MultiArrayTools U meta() const; const U* metaPtr() const; SingleIndex& at(const U& metaPos); + size_t posAt(const U& metaPos) const; size_t dim(); // = 1 bool last(); @@ -258,6 +259,12 @@ namespace MultiArrayTools return *this; } + template + size_t SingleIndex::posAt(const U& metaPos) const + { + return std::dynamic_pointer_cast const>( IB::mRangePtr )->getMeta( metaPos ); + } + template size_t SingleIndex::dim() // = 1 { @@ -354,7 +361,7 @@ namespace MultiArrayTools mSpace(space) { for(size_t i = 0; i != mSpace.size(); ++i){ - mMSpace[mSpace[i]] = i; + mMSpace[mSpace[i]] = i; } } diff --git a/src/tests/op_unit_test.cc b/src/tests/op_unit_test.cc index 7bb1e43..9f86149 100644 --- a/src/tests/op_unit_test.cc +++ b/src/tests/op_unit_test.cc @@ -155,6 +155,43 @@ namespace { std::vector v4 = { 1.470, 2.210 }; }; + class MapTest : public ::testing::Test + { + protected: + + typedef SingleRangeFactory SRF; + typedef SRF::oType SRange; + + typedef FunctionalMultiArray,SRange,SRange> MapF; + + typedef MapRangeFactory MpRF; + typedef MpRF::oType MpRange; + + typedef MpRange::ORType TRange; + + MapTest() + { + SRF srf1( { 1, 3, 7, 10 } ); + SRF srf2( { 2, 6, 8 } ); + + sr1ptr = std::dynamic_pointer_cast( srf1.create() ); + sr2ptr = std::dynamic_pointer_cast( srf2.create() ); + + MapF map(sr1ptr,sr2ptr); + MpRF mprf1( map, sr1ptr, sr2ptr ); + + mpr1ptr = std::dynamic_pointer_cast( mprf1.create() ); + } + + std::shared_ptr sr1ptr; + std::shared_ptr sr2ptr; + std::shared_ptr mpr1ptr; + std::vector v1 = { -31.71, -77.16, -18.81, + -67.06, 72.31, -54.48, + -50.91, -11.62, -59.57, + -42.53, 80.41, 6.35 }; + }; + class OpTest_Performance : public ::testing::Test { protected: @@ -277,6 +314,37 @@ namespace { } }; + + TEST_F(MapTest, Exec1) + { + MultiArray ma1(sr1ptr,sr2ptr,v1); + MultiArray res(mpr1ptr); + + auto ii1 = getIndex( rptr<0>( ma1 ) ); + auto ii2 = getIndex( rptr<1>( ma1 ) ); + + auto jj = getIndex( mpr1ptr ); + (*jj)(ii1,ii2); + + res(jj) = ma1(ii1,ii2); + + MultiArray form = res.format(mpr1ptr->outRange()); + + EXPECT_EQ( jj->range()->outRange()->size(), 10 ); + EXPECT_EQ( jj->range()->mapMultiplicity().at(9), 3 ); + EXPECT_EQ( jj->range()->mapMultiplicity().at(3), 1 ); + + EXPECT_EQ( form.at(3), -31.71 ); + EXPECT_EQ( form.at(7), -77.16 ); + EXPECT_EQ( form.at(9), -18.81 + 72.31 -50.91 ); + EXPECT_EQ( form.at(5), -67.06 ); + EXPECT_EQ( form.at(11), -54.48 ); + EXPECT_EQ( form.at(13), -11.62 ); + EXPECT_EQ( form.at(15), -59.57 ); + EXPECT_EQ( form.at(12), -42.53 ); + EXPECT_EQ( form.at(16), 80.41 ); + EXPECT_EQ( form.at(18), 6.35 ); + } TEST_F(MetaOp_Test, SimpleCall) {