File indexing completed on 2025-01-18 09:43:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_UBLAS_TENSOR_EXPRESSIONS_HPP
0013 #define BOOST_UBLAS_TENSOR_EXPRESSIONS_HPP
0014
0015 #include <cstddef>
0016 #include <boost/numeric/ublas/expression_types.hpp>
0017
0018
0019 namespace boost {
0020 namespace numeric {
0021 namespace ublas {
0022
0023
0024 template<class element_type, class storage_format, class storage_type>
0025 class tensor;
0026
0027 template<class size_type>
0028 class basic_extents;
0029
0030
0031
0032 struct tensor_tag {};
0033
0034 }
0035 }
0036 }
0037
0038 namespace boost {
0039 namespace numeric {
0040 namespace ublas {
0041 namespace detail {
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 template<class T, class E>
0052 struct tensor_expression
0053 : public ublas_expression<E>
0054 {
0055
0056 using expression_type = E;
0057 using type_category = tensor_tag;
0058 using tensor_type = T;
0059
0060 BOOST_UBLAS_INLINE
0061 auto const& operator()() const { return *static_cast<const expression_type*> (this); }
0062
0063 protected :
0064 explicit tensor_expression() = default;
0065 tensor_expression(const tensor_expression&) = delete;
0066 tensor_expression& operator=(const tensor_expression&) = delete;
0067 };
0068
0069
0070 template<class T, class EL, class ER, class OP>
0071 struct binary_tensor_expression
0072 : public tensor_expression <T, binary_tensor_expression<T,EL,ER,OP>>
0073 {
0074 using self_type = binary_tensor_expression<T,EL,ER,OP>;
0075 using tensor_type = T;
0076 using binary_operation = OP;
0077 using expression_type_left = EL;
0078 using expression_type_right = ER;
0079 using derived_type = tensor_expression <tensor_type,self_type>;
0080
0081 using size_type = typename tensor_type::size_type;
0082
0083 explicit binary_tensor_expression(expression_type_left const& l, expression_type_right const& r, binary_operation o)
0084 : el(l) , er(r) , op(o) {}
0085 binary_tensor_expression() = delete;
0086 binary_tensor_expression(const binary_tensor_expression& l) = delete;
0087 binary_tensor_expression(binary_tensor_expression&& l)
0088 : el(l.el), er(l.er), op(l.op) {}
0089
0090 BOOST_UBLAS_INLINE
0091 decltype(auto) operator()(size_type i) const { return op(el(i), er(i)); }
0092
0093 expression_type_left const& el;
0094 expression_type_right const& er;
0095 binary_operation op;
0096 };
0097
0098
0099 template<class T, class EL, class ER, class OP>
0100 auto make_binary_tensor_expression( tensor_expression<T,EL> const& el, tensor_expression<T,ER> const& er, OP op)
0101 {
0102 return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
0103 }
0104
0105 template<class T, class EL, class ER, class OP>
0106 auto make_binary_tensor_expression( matrix_expression<EL> const& el, tensor_expression<T,ER> const& er, OP op)
0107 {
0108 return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
0109 }
0110
0111 template<class T, class EL, class ER, class OP>
0112 auto make_binary_tensor_expression( tensor_expression<T,EL> const& el, matrix_expression<ER> const& er, OP op)
0113 {
0114 return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
0115 }
0116
0117 template<class T, class EL, class ER, class OP>
0118 auto make_binary_tensor_expression( vector_expression<EL> const& el, tensor_expression<T,ER> const& er, OP op)
0119 {
0120 return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
0121 }
0122
0123 template<class T, class EL, class ER, class OP>
0124 auto make_binary_tensor_expression( tensor_expression<T,EL> const& el, vector_expression<ER> const& er, OP op)
0125 {
0126 return binary_tensor_expression<T,EL,ER,OP>( el(), er(), op) ;
0127 }
0128
0129
0130
0131 template<class T, class E, class OP>
0132 struct unary_tensor_expression
0133 : public tensor_expression <T, unary_tensor_expression<T,E,OP>>
0134 {
0135
0136 using self_type = unary_tensor_expression<T,E,OP>;
0137 using tensor_type = T;
0138 using expression_type = E;
0139
0140 using derived_type = tensor_expression <T, unary_tensor_expression<T,E,OP>>;
0141
0142 using size_type = typename tensor_type::size_type;
0143
0144 explicit unary_tensor_expression(E const& ee, OP o) : e(ee) , op(o) {}
0145 unary_tensor_expression() = delete;
0146 unary_tensor_expression(const unary_tensor_expression& l) = delete;
0147 unary_tensor_expression(unary_tensor_expression&& l)
0148 : e(l.e), op(op.l) {}
0149
0150 BOOST_UBLAS_INLINE
0151 decltype(auto) operator()(size_type i) const { return op(e(i)); }
0152
0153 E const& e;
0154 OP op;
0155 };
0156
0157
0158 template<class T, class E, class OP>
0159 auto make_unary_tensor_expression( tensor_expression<T,E> const& e, OP op)
0160 {
0161 return unary_tensor_expression<T,E,OP>( e() , op);
0162 }
0163
0164 template<class T, class E, class OP>
0165 auto make_unary_tensor_expression( matrix_expression<E> const& e, OP op)
0166 {
0167 return unary_tensor_expression<T,E,OP>( e() , op);
0168 }
0169
0170 template<class T, class E, class OP>
0171 auto make_unary_tensor_expression( vector_expression<E> const& e, OP op)
0172 {
0173 return unary_tensor_expression<T,E,OP>( e() , op);
0174 }
0175
0176
0177 }
0178 }
0179 }
0180 }
0181 #endif