// // Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // The authors gratefully acknowledge the support of // Fraunhofer IOSB, Ettlingen, Germany // #ifndef BOOST_UBLAS_TENSOR_EXPRESSIONS_HPP #define BOOST_UBLAS_TENSOR_EXPRESSIONS_HPP #include #include namespace boost { namespace numeric { namespace ublas { template class tensor; template class basic_extents; //TODO: put in fwd.hpp struct tensor_tag {}; } } } namespace boost { namespace numeric { namespace ublas { namespace detail { /** @\brief base class for tensor expressions * * \note implements crtp - no use of virtual function calls * * \tparam T type of the tensor * \tparam E type of the derived expression (crtp) * **/ template struct tensor_expression : public ublas_expression { // static const unsigned complexity = 0; using expression_type = E; using type_category = tensor_tag; using tensor_type = T; BOOST_UBLAS_INLINE auto const& operator()() const { return *static_cast (this); } protected : explicit tensor_expression() = default; tensor_expression(const tensor_expression&) = delete; tensor_expression& operator=(const tensor_expression&) = delete; }; template struct binary_tensor_expression : public tensor_expression > { using self_type = binary_tensor_expression; using tensor_type = T; using binary_operation = OP; using expression_type_left = EL; using expression_type_right = ER; using derived_type = tensor_expression ; using size_type = typename tensor_type::size_type; explicit binary_tensor_expression(expression_type_left const& l, expression_type_right const& r, binary_operation o) : el(l) , er(r) , op(o) {} binary_tensor_expression() = delete; binary_tensor_expression(const binary_tensor_expression& l) = delete; binary_tensor_expression(binary_tensor_expression&& l) : el(l.el), er(l.er), op(l.op) {} BOOST_UBLAS_INLINE decltype(auto) operator()(size_type i) const { return op(el(i), er(i)); } expression_type_left const& el; expression_type_right const& er; binary_operation op; }; /// @brief helper function to simply instantiation of lambda proxy class template auto make_binary_tensor_expression( tensor_expression const& el, tensor_expression const& er, OP op) { return binary_tensor_expression( el(), er(), op) ; } template auto make_binary_tensor_expression( matrix_expression const& el, tensor_expression const& er, OP op) { return binary_tensor_expression( el(), er(), op) ; } template auto make_binary_tensor_expression( tensor_expression const& el, matrix_expression const& er, OP op) { return binary_tensor_expression( el(), er(), op) ; } template auto make_binary_tensor_expression( vector_expression const& el, tensor_expression const& er, OP op) { return binary_tensor_expression( el(), er(), op) ; } template auto make_binary_tensor_expression( tensor_expression const& el, vector_expression const& er, OP op) { return binary_tensor_expression( el(), er(), op) ; } template struct unary_tensor_expression : public tensor_expression > { using self_type = unary_tensor_expression; using tensor_type = T; using expression_type = E; using derived_type = tensor_expression >; using size_type = typename tensor_type::size_type; explicit unary_tensor_expression(E const& ee, OP o) : e(ee) , op(o) {} unary_tensor_expression() = delete; unary_tensor_expression(const unary_tensor_expression& l) = delete; unary_tensor_expression(unary_tensor_expression&& l) : e(l.e), op(op.l) {} BOOST_UBLAS_INLINE decltype(auto) operator()(size_type i) const { return op(e(i)); } E const& e; OP op; }; // \brief helper function to simply instantiation of lambda proxy class template auto make_unary_tensor_expression( tensor_expression const& e, OP op) { return unary_tensor_expression( e() , op); } template auto make_unary_tensor_expression( matrix_expression const& e, OP op) { return unary_tensor_expression( e() , op); } template auto make_unary_tensor_expression( vector_expression const& e, OP op) { return unary_tensor_expression( e() , op); } } } } } #endif