From 1c7a21a8b8061381bf74845c6da650f6f1aa49c0 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Thu, 22 Mar 2018 22:29:21 +0100 Subject: [PATCH 1/3] functional operations work --- src/tests/op_unit_test.cc | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/tests/op_unit_test.cc b/src/tests/op_unit_test.cc index 9d4c693..6aad473 100644 --- a/src/tests/op_unit_test.cc +++ b/src/tests/op_unit_test.cc @@ -15,6 +15,7 @@ namespace { double xround(double arg) { + if(std::isnan(arg)) { return 0.; } return roundf(arg * 100000.) / 100000.; } @@ -265,6 +266,15 @@ namespace { std::vector mv1; std::vector mv2; + + double vcontract(size_t i) + { + double res = 0.; + for(auto& x: mv2){ + res += pow(mv1[i],x); + } + return res; + } }; @@ -276,6 +286,32 @@ namespace { EXPECT_EQ( xround( fma[ i.at( mkt(9.665, -0.0765) ) ] ), xround( pow(9.665, -0.0765) ) ); } + + TEST_F(MetaOp_Test, Operation) + { + FunctionalMultiArray,SR,SR> fma(sr1ptr, sr2ptr); + MultiArray res( sr1ptr ); + + auto i1 = MAT::getIndex(sr1ptr); + auto i2 = MAT::getIndex(sr2ptr); + + res(i1) = fma(i1,i2).c(i2); + + auto i = res.begin(); + + EXPECT_EQ( xround( res[ i.at( 2.476 ) ] ), xround( vcontract(0) ) ); + EXPECT_EQ( xround( res[ i.at( 9.665 ) ] ), xround( vcontract(1) ) ); + EXPECT_EQ( xround( res[ i.at( 1.289 ) ] ), xround( vcontract(2) ) ); + EXPECT_EQ( xround( res[ i.at( 2.89 ) ] ), xround( vcontract(3) ) ); + EXPECT_EQ( xround( res[ i.at( 77.04 ) ] ), xround( vcontract(4) ) ); + + EXPECT_EQ( xround( res[ i.at( -11.09 ) ] ), xround( vcontract(5) ) ); + EXPECT_EQ( xround( res[ i.at( 100.4 ) ] ), xround( vcontract(6) ) ); + EXPECT_EQ( xround( res[ i.at( 2.0 ) ] ), xround( vcontract(7) ) ); + EXPECT_EQ( xround( res[ i.at( -26.5 ) ] ), xround( vcontract(8) ) ); + EXPECT_EQ( xround( res[ i.at( -0.001 ) ] ), xround( vcontract(9) ) ); + } + TEST_F(OpTest_Spin, Contract) { From 714eecd6633e230e4357397291bac0240d2532c2 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Sat, 28 Apr 2018 17:33:57 +0200 Subject: [PATCH 2/3] non-static function call in Operation + utils in anonymous range --- src/include/multi_array_operation.h | 17 +++++++++++++-- src/include/pack_num.h | 31 +++++++++++++++++++++++----- src/include/ranges/anonymous_range.h | 13 +++++++++++- src/lib/ranges/anonymous_range.cc | 5 +++++ 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index 6a9f3bc..6eb82b8 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -248,6 +248,7 @@ namespace MultiArrayTools typedef decltype(PackNum::template mkSteps(0, mOps)) ETuple; Operation(const Ops&... ops); + Operation(std::shared_ptr ff, const Ops&... ops); template inline T get(ET pos) const; @@ -522,7 +523,19 @@ namespace MultiArrayTools template Operation::Operation(const Ops&... ops) : - mOps(ops...) {} + mOps(ops...) + { + static_assert( FISSTATIC, "need function instance for non-static function" ); + } + + template + Operation::Operation(std::shared_ptr ff, + const Ops&... ops) : + mOps(ops...), + mF(ff) + { + static_assert( not FISSTATIC, "using instance of function supposed to be static" ); + } template template @@ -530,7 +543,7 @@ namespace MultiArrayTools { typedef std::tuple OpTuple; return PackNum:: - template mkOpExpr(pos, mOps); + template mkOpExpr(mF, pos, mOps); } template diff --git a/src/include/pack_num.h b/src/include/pack_num.h index b0b968a..f197c6e 100644 --- a/src/include/pack_num.h +++ b/src/include/pack_num.h @@ -13,6 +13,26 @@ namespace MultiArrayHelper { + template + struct Application + { + template + static inline T apply(std::shared_ptr f, T a, Ts... as) + { + return (*f)(a, as...); + } + }; + + template <> + struct Application + { + template + static inline T apply(std::shared_ptr f, T a, Ts... as) + { + return OpFunction::apply(a, as...); + } + }; + template struct PackNum @@ -41,13 +61,13 @@ namespace MultiArrayHelper } template - static inline T mkOpExpr(const ETuple& pos, const OpTuple& ops, const Args&... args) + static inline T mkOpExpr(std::shared_ptr f, const ETuple& pos, const OpTuple& ops, const Args&... args) { typedef typename std::remove_reference(ops))>::type NextOpType; static_assert(LAST > NextOpType::SIZE, "inconsistent array positions"); static constexpr size_t NEXT = LAST - NextOpType::SIZE; return PackNum::template mkOpExpr - ( pos, ops, std::get(ops).get(Getter::template getX( pos )), args...); + ( f, pos, ops, std::get(ops).get(Getter::template getX( pos )), args...); } template @@ -94,14 +114,15 @@ namespace MultiArrayHelper { std::get<0>(out) = second.rootSteps( std::get<0>(siar) ); } - + template - static inline T mkOpExpr(const ETuple& pos, const OpTuple& ops, const Args&... args) + static inline T mkOpExpr(std::shared_ptr f, const ETuple& pos, const OpTuple& ops, const Args&... args) { typedef typename std::remove_reference(ops))>::type NextOpType; static constexpr size_t NEXT = LAST - NextOpType::SIZE; static_assert(NEXT == 0, "inconsistent array positions"); - return OpFunction::apply(std::get<0>(ops).get(Getter<0>::template getX( pos )), args...); + return Application::apply(f, std::get<0>(ops).get(Getter<0>::template getX( pos )), args...); + //return OpFunction::apply(std::get<0>(ops).get(Getter<0>::template getX( pos )), args...); } template diff --git a/src/include/ranges/anonymous_range.h b/src/include/ranges/anonymous_range.h index c22f6dd..d47999c 100644 --- a/src/include/ranges/anonymous_range.h +++ b/src/include/ranges/anonymous_range.h @@ -51,7 +51,12 @@ namespace MultiArrayTools virtual IndexType begin() const override; virtual IndexType end() const override; - + + std::shared_ptr sub(size_t num) const; + + template + std::shared_ptr fullsub(size_t num) const; + friend AnonymousRangeFactory; protected: @@ -118,6 +123,12 @@ namespace MultiArrayTools //RPackNum::getSize( rst ); } + template + std::shared_ptr AnonymousRange::fullsub(size_t num) const + { + return std::dynamic_pointer_cast( mOrig.at(num) ); + } + /***************** * Functions * *****************/ diff --git a/src/lib/ranges/anonymous_range.cc b/src/lib/ranges/anonymous_range.cc index a302dc1..61271dc 100644 --- a/src/lib/ranges/anonymous_range.cc +++ b/src/lib/ranges/anonymous_range.cc @@ -54,6 +54,11 @@ namespace MultiArrayTools i = size(); return i; } + + std::shared_ptr AnonymousRange::sub(size_t num) const + { + return mOrig.at(num); + } /***************** * Functions * From 6e1da5eed392d8a650dd620a47ac512dbd0597fe Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Sun, 29 Apr 2018 17:41:28 +0200 Subject: [PATCH 3/3] add Scalar + cast to T --- src/include/multi_array.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/include/multi_array.h b/src/include/multi_array.h index 014976c..120877c 100644 --- a/src/include/multi_array.h +++ b/src/include/multi_array.h @@ -50,6 +50,8 @@ namespace MultiArrayTools virtual const T* data() const override; virtual T* data() override; + + operator T() const; template friend class MultiArray; @@ -57,6 +59,9 @@ namespace MultiArrayTools private: std::vector mCont; }; + + template + using Scalar = MultiArray; } @@ -193,6 +198,13 @@ namespace MultiArrayTools { return mCont.data(); } + + template + MultiArray::operator T() const + { + static_assert( sizeof...(SRanges) == 0, "try to cast non-scalar type into scalar" ); + return mCont[0]; + } } #endif