From c043008217cf4d0814934c54eba9275a379f0176 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Thu, 19 Jul 2018 19:29:52 +0200 Subject: [PATCH] function structs corresponding to math.h functions + some code optimizations --- src/include/arith.h | 43 +++++++++-- src/include/extensions/math.h | 31 ++++++++ src/include/multi_array.h | 54 +++++++++++++- src/include/multi_array_header.h | 1 + src/include/multi_array_operation.h | 104 ++++----------------------- src/include/operation_def.h | 94 ++++++++++++++++++++++++ src/include/pack_num.h | 14 ++++ src/include/ranges/anonymous_range.h | 1 - 8 files changed, 246 insertions(+), 96 deletions(-) create mode 100644 src/include/extensions/math.h create mode 100644 src/include/operation_def.h diff --git a/src/include/arith.h b/src/include/arith.h index a2dd583..336f71d 100644 --- a/src/include/arith.h +++ b/src/include/arith.h @@ -60,7 +60,7 @@ namespace MultiArrayTools }; template - struct plus + struct plus : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; @@ -71,7 +71,7 @@ namespace MultiArrayTools }; template - struct minus + struct minus : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; @@ -82,7 +82,7 @@ namespace MultiArrayTools }; template - struct multiplies + struct multiplies : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; @@ -93,7 +93,7 @@ namespace MultiArrayTools }; template - struct divides + struct divides : public StaticFunctionBase, T, T> { static constexpr bool FISSTATIC = true; @@ -102,6 +102,41 @@ namespace MultiArrayTools return a1 / a2; } }; + +#include +#define regFunc1(fff) template \ + struct x_##fff : public StaticFunctionBase, T> {\ + static constexpr bool FISSTATIC = true;\ + static inline T apply(T a){\ + return fff(a); } }; + +#include "extensions/math.h" +#undef regFunc1 + + template + struct x_ipow + { + static constexpr bool FISSTATIC = true; + + template + static inline T apply(T a) + { + return a * x_ipow::apply(a); + } + }; + + template <> + struct x_ipow<0> + { + static constexpr bool FISSTATIC = true; + + template + static inline T apply(T a) + { + return a; + } + }; + /* template struct dynamic_function diff --git a/src/include/extensions/math.h b/src/include/extensions/math.h new file mode 100644 index 0000000..394fb0e --- /dev/null +++ b/src/include/extensions/math.h @@ -0,0 +1,31 @@ + +#ifdef regFunc1 + +regFunc1(exp) +regFunc1(exp2) +regFunc1(expm1) +regFunc1(log) +regFunc1(log10) +regFunc1(log2) +regFunc1(log1p) +regFunc1(sqrt) +regFunc1(cbrt) +regFunc1(sin) +regFunc1(cos) +regFunc1(tan) +regFunc1(asin) +regFunc1(acos) +regFunc1(atan) +regFunc1(atan2) +regFunc1(sinh) +regFunc1(cosh) +regFunc1(tanh) +regFunc1(asinh) +regFunc1(acosh) +regFunc1(atanh) +regFunc1(erf) +regFunc1(erfc) +regFunc1(tgamma) +regFunc1(lgamma) + +#endif diff --git a/src/include/multi_array.h b/src/include/multi_array.h index a6aefcf..9273ba9 100644 --- a/src/include/multi_array.h +++ b/src/include/multi_array.h @@ -3,6 +3,8 @@ #ifndef __multi_array_h__ #define __multi_array_h__ +#include + #include "multi_array_base.h" #include "ranges/anonymous_range.h" @@ -77,6 +79,11 @@ namespace MultiArrayTools -> decltype(ArrayCatter::cat(*this)); operator T() const; + + MultiArray& operator+=(const MultiArray& in); + MultiArray& operator-=(const MultiArray& in); + MultiArray& operator*=(const T& in); + MultiArray& operator/=(const T& in); template friend class MultiArray; @@ -187,7 +194,8 @@ namespace MultiArrayTools template MultiArray::MultiArray(MultiArray& ama, SIZET... sizes) : - MutableMultiArrayBase( ama.range()->template scast(sizes...)->space() ), + MutableMultiArrayBase + ( ama.range()->template get<0>().template scast(sizes...)->space() ), mCont( std::move( ama.mCont ) ) { MAB::mInit = true; @@ -297,6 +305,50 @@ namespace MultiArrayTools std::move(mCont) ); } + template + MultiArray& MultiArray::operator+=(const MultiArray& in) + { + if(not MAB::mInit){ // not initialized by default constructor !! + (*this) = in; + } + else { + assert( PackNum::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) ); + std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::plus()); + } + return *this; + } + + template + MultiArray& MultiArray::operator-=(const MultiArray& in) + { + if(not MAB::mInit){ // not initialized by default constructor !! + (*this) = in; + } + else { + assert( PackNum::checkIfSameInstance( MAB::mRange->space(), in.mRange->space() ) ); + std::transform(mCont.begin(), mCont.end(), in.mCont.begin(), mCont.begin(), std::minus()); + } + return *this; + } + + template + MultiArray& MultiArray::operator*=(const T& in) + { + for(auto& x: mCont){ + x *= in; + } + return *this; + } + + template + MultiArray& MultiArray::operator/=(const T& in) + { + for(auto& x: mCont){ + x /= in; + } + return *this; + } + template MultiArray::operator T() const { diff --git a/src/include/multi_array_header.h b/src/include/multi_array_header.h index ab6021d..0879676 100644 --- a/src/include/multi_array_header.h +++ b/src/include/multi_array_header.h @@ -16,6 +16,7 @@ #include "multi_array.h" #include "functional_multi_array.h" #include "helper_tools.h" +#include "operation_def.h" //#include "slice.h" //#include "manipulator.h" //#include "range_transformer.h" diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index b3754ae..d7fdfd6 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -33,32 +33,27 @@ namespace MultiArrayTools OperationClass& THIS() { return static_cast(*this); } const OperationClass& THIS() const { return static_cast(*this); } - inline auto operator+(const T& in) const - -> Operation,OperationClass,OperationValue >; - - // !!! - template - auto operator+(const Second& in) const + auto operator+(const OperationBase& in) const -> Operation,OperationClass,Second>; template - auto operator-(const Second& in) const + auto operator-(const OperationBase& in) const -> Operation,OperationClass,Second>; template - auto operator*(const Second& in) const + auto operator*(const OperationBase& in) const -> Operation,OperationClass,Second>; template - auto operator/(const Second& in) const + auto operator/(const OperationBase& in) const -> Operation,OperationClass,Second>; template auto c(std::shared_ptr& ind) const -> Contraction; - - private: + + private: friend OperationClass; friend OperationTemplate; OperationBase() = default; @@ -306,69 +301,6 @@ namespace MultiArrayTools return Operation(ops...); } - template - auto operator+(const T& a, const OperationBase& b) - -> Operation,OperationValue,OperationClass> - { - OperationValue v(a); - return Operation,OperationValue,OperationClass>(v, b.THIS()); - } - - template - auto operator-(const T& a, const OperationBase& b) - -> Operation,OperationValue,OperationClass> - { - OperationValue v(a); - return Operation,OperationValue,OperationClass>(v, b.THIS()); - } - - template - auto operator*(const T& a, const OperationBase& b) - -> Operation,OperationValue,OperationClass> - { - OperationValue v(a); - return Operation,OperationValue,OperationClass>(v, b.THIS()); - } - - template - auto operator/(const T& a, const OperationBase& b) - -> Operation,OperationValue,OperationClass> - { - OperationValue v(a); - return Operation,OperationValue,OperationClass>(v, b.THIS()); - } - - template - auto operator+(const OperationBase& a, const T& b) - -> Operation,OperationClass,OperationValue > - { - OperationValue v(b); - return Operation,OperationClass,OperationValue >(a.THIS(), v); - } - - template - auto operator-(const OperationBase& a, const T& b) - -> Operation,OperationClass,OperationValue > - { - OperationValue v(b); - return Operation,OperationClass,OperationValue >(a.THIS(), v); - } - - template - auto operator*(const OperationBase& a, const T& b) - -> Operation,OperationClass,OperationValue > - { - OperationValue v(b); - return Operation,OperationClass,OperationValue >(a.THIS(), v); - } - - template - auto operator/(const OperationBase& a, const T& b) - -> Operation,OperationClass,OperationValue > - { - OperationValue v(b); - return Operation,OperationClass,OperationValue >(a.THIS(), v); - } template @@ -418,45 +350,37 @@ namespace MultiArrayTools * OperationTemplate * ***************************/ - - template - auto OperationBase::operator+(const T& in) const - -> Operation,OperationClass,OperationValue > - { - return Operation,OperationClass,OperationValue >(THIS(), in); - } - template template - auto OperationBase::operator+(const Second& in) const + auto OperationBase::operator+(const OperationBase& in) const -> Operation,OperationClass,Second> { - return Operation,OperationClass,Second>(THIS(), in); + return Operation,OperationClass,Second>(THIS(), in.THIS()); } template template - auto OperationBase::operator-(const Second& in) const + auto OperationBase::operator-(const OperationBase& in) const -> Operation,OperationClass,Second> { - return Operation,OperationClass,Second>(THIS(), in); + return Operation,OperationClass,Second>(THIS(), in.THIS()); } template template - auto OperationBase::operator*(const Second& in) const + auto OperationBase::operator*(const OperationBase& in) const -> Operation,OperationClass,Second> { - return Operation,OperationClass,Second>(THIS(), in); + return Operation,OperationClass,Second>(THIS(), in.THIS()); } template template - auto OperationBase::operator/(const Second& in) const + auto OperationBase::operator/(const OperationBase& in) const -> Operation,OperationClass,Second> { - return Operation,OperationClass,Second>(THIS(), in); + return Operation,OperationClass,Second>(THIS(), in.THIS()); } template diff --git a/src/include/operation_def.h b/src/include/operation_def.h new file mode 100644 index 0000000..ec4fafc --- /dev/null +++ b/src/include/operation_def.h @@ -0,0 +1,94 @@ + +#ifndef __operation_def_h__ +#define __operation_def_h__ + +#include "multi_array_operation.h" + +namespace MultiArrayTools +{ + + template + auto operator+(const T& a, const OperationBase& b) + -> Operation,OperationValue,OperationClass> + { + OperationValue v(a); + return Operation,OperationValue,OperationClass>(v, b.THIS()); + } + + template + auto operator-(const T& a, const OperationBase& b) + -> Operation,OperationValue,OperationClass> + { + OperationValue v(a); + return Operation,OperationValue,OperationClass>(v, b.THIS()); + } + + template + auto operator*(const T& a, const OperationBase& b) + -> Operation,OperationValue,OperationClass> + { + OperationValue v(a); + return Operation,OperationValue,OperationClass>(v, b.THIS()); + } + + template + auto operator/(const T& a, const OperationBase& b) + -> Operation,OperationValue,OperationClass> + { + OperationValue v(a); + return Operation,OperationValue,OperationClass>(v, b.THIS()); + } + + template + auto operator+(const OperationBase& a, const T& b) + -> Operation,OperationClass,OperationValue > + { + OperationValue v(b); + return Operation,OperationClass,OperationValue >(a.THIS(), v); + } + + template + auto operator-(const OperationBase& a, const T& b) + -> Operation,OperationClass,OperationValue > + { + OperationValue v(b); + return Operation,OperationClass,OperationValue >(a.THIS(), v); + } + + template + auto operator*(const OperationBase& a, const T& b) + -> Operation,OperationClass,OperationValue > + { + OperationValue v(b); + return Operation,OperationClass,OperationValue >(a.THIS(), v); + } + + template + auto operator/(const OperationBase& a, const T& b) + -> Operation,OperationClass,OperationValue > + { + OperationValue v(b); + return Operation,OperationClass,OperationValue >(a.THIS(), v); + } + +#define regFunc1(fff) template \ + auto fff(const OperationBase& a) \ + -> Operation,OperationClass> { \ + return Operation,OperationClass>(a.THIS()); } + + +#include "extensions/math.h" +#undef regFunc1 + + + template + auto ipow(const OperationBase& a) + -> Operation,OperationClass> + { + return Operation,OperationClass>(a.THIS()); + } + + +} + +#endif diff --git a/src/include/pack_num.h b/src/include/pack_num.h index 69cf12a..bb38001 100644 --- a/src/include/pack_num.h +++ b/src/include/pack_num.h @@ -100,6 +100,13 @@ namespace MultiArrayHelper std::get(blocks) = tmp; PackNum::template mkSliceBlocks(blocks, index, op, total * tmp); } + + template + static bool checkIfSameInstance(const std::tuple...>& rtp1, + const std::tuple...>& rtp2) + { + return std::get(rtp1).get() == std::get(rtp2).get() and PackNum::checkIfSameInstance(rtp1,rtp2); + } }; template<> @@ -164,6 +171,13 @@ namespace MultiArrayHelper std::get<0>(blocks) = total * tmp; // this is not correct, but not used so far ... !!! } + template + static bool checkIfSameInstance(const std::tuple...>& rtp1, + const std::tuple...>& rtp2) + { + return std::get<0>(rtp1).get() == std::get<0>(rtp2).get(); + } + }; diff --git a/src/include/ranges/anonymous_range.h b/src/include/ranges/anonymous_range.h index 7eaab27..324680e 100644 --- a/src/include/ranges/anonymous_range.h +++ b/src/include/ranges/anonymous_range.h @@ -100,7 +100,6 @@ namespace MultiArrayTools std::vector > mOrig; }; - } /* ========================= *