From 8f94c77f4db253eb35be42e775586dd6d4dda779 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Wed, 21 Mar 2018 19:18:57 +0100 Subject: [PATCH] functional multi array test; there are some remaining issues (maybe conceptional)... --- src/include/arith.h | 18 ++- src/include/functional_multi_array.h | 64 ++++++++-- src/include/multi_array_operation.h | 8 +- src/include/ranges/anonymous_range.h | 7 ++ src/include/ranges/range_base.h | 1 + .../ranges/range_types/classic_range.h | 1 + src/include/ranges/range_types/spin_range.h | 1 + src/include/ranges/single_range.h | 15 ++- src/lib/ranges/anonymous_range.cc | 13 -- src/tests/op_unit_test.cc | 119 +++++++++++++++++- 10 files changed, 206 insertions(+), 41 deletions(-) diff --git a/src/include/arith.h b/src/include/arith.h index b77d9aa..54ed0a1 100644 --- a/src/include/arith.h +++ b/src/include/arith.h @@ -8,6 +8,8 @@ namespace MultiArrayHelper template struct plus { + static constexpr bool FISSTATIC = true; + static inline T apply(T a1, T a2) { return a1 + a2; @@ -17,6 +19,8 @@ namespace MultiArrayHelper template struct minus { + static constexpr bool FISSTATIC = true; + static inline T apply(T a1, T a2) { return a1 - a2; @@ -26,6 +30,8 @@ namespace MultiArrayHelper template struct multiplies { + static constexpr bool FISSTATIC = true; + static inline T apply(T a1, T a2) { return a1 * a2; @@ -35,22 +41,26 @@ namespace MultiArrayHelper template struct divides { + static constexpr bool FISSTATIC = true; + static inline T apply(T a1, T a2) { return a1 / a2; } }; - + /* template struct dynamic_function { + static constexpr bool FISSTATIC = false; + template - static inline T apply(const Func& f, Us... args) + inline T apply(Us... args) { return f(args...); } - } - + }; + */ } // end namespace MultiArrayHelper #endif diff --git a/src/include/functional_multi_array.h b/src/include/functional_multi_array.h index 6207432..0e15808 100644 --- a/src/include/functional_multi_array.h +++ b/src/include/functional_multi_array.h @@ -7,6 +7,11 @@ namespace MultiArrayTools { + + template + auto indexToSlice(const std::shared_ptr& i) + -> Slice; + template class FunctionalMultiArray : public MultiArrayBase @@ -15,9 +20,9 @@ namespace MultiArrayTools typedef ContainerRange CRange; typedef MultiArrayBase MAB; - typedef typename MultiArrayBase::const_iterator const_iterator; - typedef typename CRange::IndexType IndexType; - + //typedef typename MultiArrayBase::const_iterator const_iterator; + typedef ContainerIndex IndexType; + //typedef typename CRange::IndexType IndexType; private: mutable T mVal; @@ -27,20 +32,21 @@ namespace MultiArrayTools DEFAULT_MEMBERS(FunctionalMultiArray); FunctionalMultiArray(const std::shared_ptr&... ranges, const Function& func); - + FunctionalMultiArray(const std::shared_ptr&... ranges); + virtual const T& operator[](const IndexType& i) const override; - + virtual bool isConst() const override; virtual bool isSlice() const override; // EVALUTAION CLASS ??!!!! - auto operator()(std::shared_ptr&... inds) const - -> decltype( mkOperation( mFunc, ConstOperationRoot(inds.metaPtr(), inds), ... ) ) + virtual auto operator()(std::shared_ptr&... inds) const + -> decltype( mkOperation( mFunc, ConstOperationRoot( indexToSlice( inds ), inds) ... ) ) override; }; - + } // namespace MultiArrayTools /* ========================= * @@ -49,6 +55,14 @@ namespace MultiArrayTools namespace MultiArrayTools { + + template + auto indexToSlice(const std::shared_ptr& i) + -> Slice + { + return Slice( i->range(), i->metaPtr() ); + } + /**************************** * FunctionalMultiArray * @@ -59,15 +73,39 @@ namespace MultiArrayTools FunctionalMultiArray::FunctionalMultiArray(const Range& range) : MultiArrayBase(range), mFunc() {} */ + template + struct Application + { + template + static inline T apply(const Function& f, const Index& i) + { + return f(i.meta()); + } + }; + + template <> + struct Application + { + template + static inline T apply(const Function& f, const Index& i) + { + return Function::apply(i.meta()); + } + }; + template FunctionalMultiArray::FunctionalMultiArray(const std::shared_ptr&... ranges, - const Function& func) : + const Function& func) : MultiArrayBase(ranges...), mFunc(func) {} template - const T& FunctionalMultiArray::operator[](const typename CRange::IndexType& i) const + FunctionalMultiArray::FunctionalMultiArray(const std::shared_ptr&... ranges) : + MultiArrayBase(ranges...) {} + + template + const T& FunctionalMultiArray::operator[](const IndexType& i) const { - mVal = mFunc(i.meta()); + mVal = Application::template apply(mFunc, i.meta()); return mVal; } @@ -86,9 +124,9 @@ namespace MultiArrayTools template auto FunctionalMultiArray:: operator()(std::shared_ptr&... inds) const - -> decltype( mkOperation( mFunc, ConstOperationRoot(inds.metaPtr(), inds), ... ) ) + -> decltype( mkOperation( mFunc, ConstOperationRoot( indexToSlice( inds ), inds) ... ) ) { - return mkOperation( mFunc, ConstOperationRoot(inds.metaPtr(), inds), ... ); + return mkOperation( mFunc, ConstOperationRoot( indexToSlice( inds ), inds ) ... ); } diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index 4cba9e6..6a9f3bc 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -238,10 +238,12 @@ namespace MultiArrayTools typedef OpFunction F; static constexpr size_t SIZE = RootSum::SIZE; + static constexpr bool FISSTATIC = OpFunction::FISSTATIC; private: std::tuple mOps; - + std::shared_ptr mF; // only if non-static + public: typedef decltype(PackNum::template mkSteps(0, mOps)) ETuple; @@ -261,9 +263,9 @@ namespace MultiArrayTools template auto mkOperation(const OpFunction& f, const Ops&... ops) - -> Operation + -> Operation { - return Operation(ops...); + return Operation(ops...); } template diff --git a/src/include/ranges/anonymous_range.h b/src/include/ranges/anonymous_range.h index 8f0a8bc..c22f6dd 100644 --- a/src/include/ranges/anonymous_range.h +++ b/src/include/ranges/anonymous_range.h @@ -33,6 +33,13 @@ namespace MultiArrayTools class AnonymousRange : public RangeInterface { + public: + + static constexpr bool defaultable = false; + static constexpr size_t ISSTATIC = 0; + static constexpr size_t SIZE = -1; + static constexpr bool HASMETACONT = false; + typedef RangeBase RB; typedef typename RangeInterface::IndexType IndexType; diff --git a/src/include/ranges/range_base.h b/src/include/ranges/range_base.h index d8e3c32..3632d9c 100644 --- a/src/include/ranges/range_base.h +++ b/src/include/ranges/range_base.h @@ -78,6 +78,7 @@ namespace MultiArrayTools { public: + //typedef typename Index::MetaType MetaType; typedef Index IndexType; virtual Index begin() const = 0; diff --git a/src/include/ranges/range_types/classic_range.h b/src/include/ranges/range_types/classic_range.h index e236443..d3cf092 100644 --- a/src/include/ranges/range_types/classic_range.h +++ b/src/include/ranges/range_types/classic_range.h @@ -29,6 +29,7 @@ namespace MultiArrayTools typedef RangeBase RB; typedef typename RangeInterface >::IndexType IndexType; typedef SingleRange RangeType; + typedef size_t MetaType; virtual size_t size() const override; virtual size_t dim() const override; diff --git a/src/include/ranges/range_types/spin_range.h b/src/include/ranges/range_types/spin_range.h index 0a8d118..34f5447 100644 --- a/src/include/ranges/range_types/spin_range.h +++ b/src/include/ranges/range_types/spin_range.h @@ -33,6 +33,7 @@ namespace MultiArrayTools typedef RangeBase RB; typedef typename RangeInterface >::IndexType IndexType; typedef SingleRange RangeType; + typedef size_t MetaType; virtual size_t size() const override; virtual size_t dim() const override; diff --git a/src/include/ranges/single_range.h b/src/include/ranges/single_range.h index 490dd55..8ab53ce 100644 --- a/src/include/ranges/single_range.h +++ b/src/include/ranges/single_range.h @@ -74,7 +74,7 @@ namespace MultiArrayTools -> For,Expr,ForType::HIDDEN>; private: - U* mMetaPtr; + const U* mMetaPtr; }; template @@ -97,6 +97,7 @@ namespace MultiArrayTools typedef RangeBase RB; typedef SingleIndex IndexType; typedef SingleRange RangeType; + typedef U MetaType; //typedef typename RangeInterface >::IndexType IndexType; virtual size_t size() const override; @@ -140,18 +141,19 @@ namespace MultiArrayTools template struct MetaPtrSetter { - template - U* set(Range* r) + template + static const typename Range::MetaType* set(Range* r) { return &r->get(0); } + }; template <> struct MetaPtrSetter { - template - U* set(Range* r) + template + static const typename Range::MetaType* set(Range* r) { return nullptr; } @@ -160,7 +162,8 @@ namespace MultiArrayTools template SingleIndex::SingleIndex(const std::shared_ptr >& range) : IndexInterface,U>(range, 0), - mMetaPtr(MetaPtrSetter::HASMETACONT>::set(IB::mRangePtr)) {} + mMetaPtr(MetaPtrSetter::RangeType::HASMETACONT>::set + ( dynamic_cast(IB::mRangePtr.get() ) ) ) {} template IndexType SingleIndex::type() const diff --git a/src/lib/ranges/anonymous_range.cc b/src/lib/ranges/anonymous_range.cc index 0d3bdd5..a302dc1 100644 --- a/src/lib/ranges/anonymous_range.cc +++ b/src/lib/ranges/anonymous_range.cc @@ -54,19 +54,6 @@ namespace MultiArrayTools i = size(); return i; } - - // put this in the interface class !!! - /* - std::shared_ptr AnonymousRange::index() const - { - //typedef IndexWrapper IW; - return std::shared_ptr(); - std::make_shared - (std::make_shared - ( std::dynamic_pointer_cast - ( std::shared_ptr( RB::mThis ) ) ) ); //!!!! - } - */ /***************** * Functions * diff --git a/src/tests/op_unit_test.cc b/src/tests/op_unit_test.cc index 7c9a99c..2b6f66f 100644 --- a/src/tests/op_unit_test.cc +++ b/src/tests/op_unit_test.cc @@ -62,6 +62,31 @@ namespace { { return std::make_tuple(static_cast( ts )...); } + + template + struct Pow + { + static constexpr bool FISSTATIC = true; + typedef T value_type; + + static inline T apply(T b, T e) + { + return pow(b, e); + } + + template + static auto mk(const Ops&... ops) + -> Operation,Ops...> + { + return Operation,Ops...>(ops...); + } + + static inline T apply(const std::tuple& arg) + { + return pow(std::get<0>(arg), std::get<1>(arg)); + } + }; + class OpTest_1Dim : public ::testing::Test { @@ -208,6 +233,50 @@ namespace { std::shared_ptr sr; }; + class MetaOp_Test : public ::testing::Test + { + protected: + + typedef SingleRangeFactory SRF; + typedef SRF::oType SR; + + const size_t s1 = 10; + const size_t s2 = 17; + + MetaOp_Test() + { + mv1 = { 2.476, 9.665, 1.289, 2.89, 77.04, -11.09, 100.4, 2.0, -26.5, -0.001 }; + mv2 = { 44.56, 23.097, -117.3, -0.0765, 3.445, 0.02389, -4.0112, 10.567, 8.99, -177.2, 475.3, + 11.111, 13.108, -35.6, 64.32, 2.44, -12.}; + + assert(mv1.size() == s1); // just to prevent typos... + assert(mv1.size() == s2); + + swapFactory(rfbptr, mv1); + sr1ptr = std::dynamic_pointer_cast(rfbptr->create()); + + swapFactory(rfbptr, mv2); + sr2ptr = std::dynamic_pointer_cast(rfbptr->create()); + } + + std::shared_ptr rfbptr; + std::shared_ptr sr1ptr; + std::shared_ptr sr2ptr; + + std::vector mv1; + std::vector mv2; + }; + + + TEST_F(MetaOp_Test, SimpleCall) + { + FunctionalMultiArray,SR,SR> fma(sr1ptr, sr2ptr); + + auto i = fma.begin(); + + EXPECT_EQ( xround( i.at( mkt(9.665, -0.0765) ) ), xround( pow(9.665, -0.0765) ) ); + } + TEST_F(OpTest_Spin, Contract) { MultiArray ma(sr, sr, sr, sr, sr, sr, sr, sr, data); @@ -392,6 +461,52 @@ namespace { EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'B')) ), xround(2.911 + 4.790 - 2.210) ); } + template + struct Monopole + { + static constexpr bool FISSTATIC = true; + + static inline T apply(T f0, T x, T n) + { + return f0 / ( 1 + x / n ); + } + + template + static auto mk(const Ops&... ops) + -> Operation,Ops...> + { + return Operation,Ops...>(ops...); + } + }; + + TEST_F(OpTest_MDim, ExecFOp) + { + MultiArray res(mr1ptr,sr4ptr); + MultiArray ma1(mr1ptr, v3); + MultiArray ma2(sr4ptr, v2); + MultiArray ma3(sr4ptr, v4); + + auto i1 = MAT::getIndex( mr1ptr ); + auto i2 = MAT::getIndex( sr4ptr ); + + res(i1,i2) = Monopole::mk( ma1(i1) , ma2(i2) , ma3(i2) ); + + EXPECT_EQ( xround( res.at(mkt(mkt('1','a'),'A')) ), xround(0.353 / ( 1 + 8.870 / 1.470) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('1','a'),'B')) ), xround(0.353 / ( 1 + 4.790 / 2.210) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('1','b'),'A')) ), xround(4.005 / ( 1 + 8.870 / 1.470) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('1','b'),'B')) ), xround(4.005 / ( 1 + 4.790 / 2.210) ) ); + + EXPECT_EQ( xround( res.at(mkt(mkt('2','a'),'A')) ), xround(1.070 / ( 1 + 8.870 / 1.470) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('2','a'),'B')) ), xround(1.070 / ( 1 + 4.790 / 2.210) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('2','b'),'A')) ), xround(2.310 / ( 1 + 8.870 / 1.470) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('2','b'),'B')) ), xround(2.310 / ( 1 + 4.790 / 2.210) ) ); + + EXPECT_EQ( xround( res.at(mkt(mkt('3','a'),'A')) ), xround(9.243 / ( 1 + 8.870 / 1.470) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('3','a'),'B')) ), xround(9.243 / ( 1 + 4.790 / 2.210) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'A')) ), xround(2.911 / ( 1 + 8.870 / 1.470) ) ); + EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'B')) ), xround(2.911 / ( 1 + 4.790 / 2.210) ) ); + } + TEST_F(OpTest_MDim, ExecOp3) { MultiArray res(mr1ptr,sr4ptr); @@ -422,7 +537,7 @@ namespace { EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'A')) ), xround(2.911 + 0.373 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'B')) ), xround(2.911 + 0.373 + 2.210) ); } - + /* TEST_F(OpTest_MDim, ExecAnonOp1) { MultiArray res(mr1ptr,sr4ptr); @@ -453,7 +568,7 @@ namespace { EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'A')) ), xround(2.911 + 0.373 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'B')) ), xround(2.911 + 0.373 + 2.210) ); } - + */ } // anonymous namspace