expression.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //
  2. // Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // The authors gratefully acknowledge the support of
  9. // Fraunhofer IOSB, Ettlingen, Germany
  10. //
  11. #ifndef BOOST_UBLAS_TENSOR_EXPRESSIONS_HPP
  12. #define BOOST_UBLAS_TENSOR_EXPRESSIONS_HPP
  13. #include <cstddef>
  14. #include <boost/numeric/ublas/expression_types.hpp>
  15. namespace boost {
  16. namespace numeric {
  17. namespace ublas {
  18. template<class element_type, class storage_format, class storage_type>
  19. class tensor;
  20. template<class size_type>
  21. class basic_extents;
  22. //TODO: put in fwd.hpp
  23. struct tensor_tag {};
  24. }
  25. }
  26. }
  27. namespace boost {
  28. namespace numeric {
  29. namespace ublas {
  30. namespace detail {
  31. /** @\brief base class for tensor expressions
  32. *
  33. * \note implements crtp - no use of virtual function calls
  34. *
  35. * \tparam T type of the tensor
  36. * \tparam E type of the derived expression (crtp)
  37. *
  38. **/
  39. template<class T, class E>
  40. struct tensor_expression
  41. : public ublas_expression<E>
  42. {
  43. // static const unsigned complexity = 0;
  44. using expression_type = E;
  45. using type_category = tensor_tag;
  46. using tensor_type = T;
  47. BOOST_UBLAS_INLINE
  48. auto const& operator()() const { return *static_cast<const expression_type*> (this); }
  49. protected :
  50. explicit tensor_expression() = default;
  51. tensor_expression(const tensor_expression&) = delete;
  52. tensor_expression& operator=(const tensor_expression&) = delete;
  53. };
  54. template<class T, class EL, class ER, class OP>
  55. struct binary_tensor_expression
  56. : public tensor_expression <T, binary_tensor_expression<T,EL,ER,OP>>
  57. {
  58. using self_type = binary_tensor_expression<T,EL,ER,OP>;
  59. using tensor_type = T;
  60. using binary_operation = OP;
  61. using expression_type_left = EL;
  62. using expression_type_right = ER;
  63. using derived_type = tensor_expression <tensor_type,self_type>;
  64. using size_type = typename tensor_type::size_type;
  65. explicit binary_tensor_expression(expression_type_left const& l, expression_type_right const& r, binary_operation o)
  66. : el(l) , er(r) , op(o) {}
  67. binary_tensor_expression() = delete;
  68. binary_tensor_expression(const binary_tensor_expression& l) = delete;
  69. binary_tensor_expression(binary_tensor_expression&& l)
  70. : el(l.el), er(l.er), op(l.op) {}
  71. BOOST_UBLAS_INLINE
  72. decltype(auto) operator()(size_type i) const { return op(el(i), er(i)); }
  73. expression_type_left const& el;
  74. expression_type_right const& er;
  75. binary_operation op;
  76. };
  77. /// @brief helper function to simply instantiation of lambda proxy class
  78. template<class T, class EL, class ER, class OP>
  79. auto make_binary_tensor_expression( tensor_expression<T,EL> const& el, tensor_expression<T,ER> const& er, OP op)
  80. {
  81. return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
  82. }
  83. template<class T, class EL, class ER, class OP>
  84. auto make_binary_tensor_expression( matrix_expression<EL> const& el, tensor_expression<T,ER> const& er, OP op)
  85. {
  86. return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
  87. }
  88. template<class T, class EL, class ER, class OP>
  89. auto make_binary_tensor_expression( tensor_expression<T,EL> const& el, matrix_expression<ER> const& er, OP op)
  90. {
  91. return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
  92. }
  93. template<class T, class EL, class ER, class OP>
  94. auto make_binary_tensor_expression( vector_expression<EL> const& el, tensor_expression<T,ER> const& er, OP op)
  95. {
  96. return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
  97. }
  98. template<class T, class EL, class ER, class OP>
  99. auto make_binary_tensor_expression( tensor_expression<T,EL> const& el, vector_expression<ER> const& er, OP op)
  100. {
  101. return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
  102. }
  103. template<class T, class E, class OP>
  104. struct unary_tensor_expression
  105. : public tensor_expression <T, unary_tensor_expression<T,E,OP>>
  106. {
  107. using self_type = unary_tensor_expression<T,E,OP>;
  108. using tensor_type = T;
  109. using expression_type = E;
  110. using derived_type = tensor_expression <T, unary_tensor_expression<T,E,OP>>;
  111. using size_type = typename tensor_type::size_type;
  112. explicit unary_tensor_expression(E const& ee, OP o) : e(ee) , op(o) {}
  113. unary_tensor_expression() = delete;
  114. unary_tensor_expression(const unary_tensor_expression& l) = delete;
  115. unary_tensor_expression(unary_tensor_expression&& l)
  116. : e(l.e), op(op.l) {}
  117. BOOST_UBLAS_INLINE
  118. decltype(auto) operator()(size_type i) const { return op(e(i)); }
  119. E const& e;
  120. OP op;
  121. };
  122. // \brief helper function to simply instantiation of lambda proxy class
  123. template<class T, class E, class OP>
  124. auto make_unary_tensor_expression( tensor_expression<T,E> const& e, OP op)
  125. {
  126. return unary_tensor_expression<T,E,OP>( e() , op);
  127. }
  128. template<class T, class E, class OP>
  129. auto make_unary_tensor_expression( matrix_expression<E> const& e, OP op)
  130. {
  131. return unary_tensor_expression<T,E,OP>( e() , op);
  132. }
  133. template<class T, class E, class OP>
  134. auto make_unary_tensor_expression( vector_expression<E> const& e, OP op)
  135. {
  136. return unary_tensor_expression<T,E,OP>( e() , op);
  137. }
  138. }
  139. }
  140. }
  141. }
  142. #endif