Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:03

0001 //
0002 //  Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com
0003 //
0004 //  Distributed under the Boost Software License, Version 1.0. (See
0005 //  accompanying file LICENSE_1_0.txt or copy at
0006 //  http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 //  The authors gratefully acknowledge the support of
0009 //  Fraunhofer IOSB, Ettlingen, Germany
0010 //
0011 
0012 #ifndef BOOST_UBLAS_TENSOR_OPERATORS_COMPARISON_HPP
0013 #define BOOST_UBLAS_TENSOR_OPERATORS_COMPARISON_HPP
0014 
0015 #include <boost/numeric/ublas/tensor/expression.hpp>
0016 #include <boost/numeric/ublas/tensor/expression_evaluation.hpp>
0017 #include <type_traits>
0018 #include <functional>
0019 
0020 namespace boost::numeric::ublas {
0021 template<class element_type, class storage_format, class storage_type>
0022 class tensor;
0023 }
0024 
0025 namespace boost::numeric::ublas::detail {
0026 
0027 template<class T, class F, class A, class BinaryPred>
0028 bool compare(tensor<T,F,A> const& lhs, tensor<T,F,A> const& rhs, BinaryPred pred)
0029 {
0030 
0031     if(lhs.extents() != rhs.extents()){
0032         if constexpr(!std::is_same<BinaryPred,std::equal_to<>>::value && !std::is_same<BinaryPred,std::not_equal_to<>>::value)
0033             throw std::runtime_error("Error in boost::numeric::ublas::detail::compare: cannot compare tensors with different shapes.");
0034         else
0035             return false;
0036     }
0037 
0038     if constexpr(std::is_same<BinaryPred,std::greater<>>::value || std::is_same<BinaryPred,std::less<>>::value)
0039         if(lhs.empty())
0040             return false;
0041 
0042     for(auto i = 0u; i < lhs.size(); ++i)
0043         if(!pred(lhs(i), rhs(i)))
0044             return false;
0045     return true;
0046 }
0047 
0048 template<class T, class F, class A, class UnaryPred>
0049 bool compare(tensor<T,F,A> const& rhs, UnaryPred pred)
0050 {
0051     for(auto i = 0u; i < rhs.size(); ++i)
0052         if(!pred(rhs(i)))
0053             return false;
0054     return true;
0055 }
0056 
0057 
0058 template<class T, class L, class R, class BinaryPred>
0059 bool compare(tensor_expression<T,L> const& lhs, tensor_expression<T,R> const& rhs, BinaryPred pred)
0060 {
0061     constexpr bool lhs_is_tensor = std::is_same<T,L>::value;
0062     constexpr bool rhs_is_tensor = std::is_same<T,R>::value;
0063 
0064     if constexpr (lhs_is_tensor && rhs_is_tensor)
0065         return compare(static_cast<T const&>( lhs ), static_cast<T const&>( rhs ), pred);
0066     else if constexpr (lhs_is_tensor && !rhs_is_tensor)
0067         return compare(static_cast<T const&>( lhs ), T( rhs ), pred);
0068     else if constexpr (!lhs_is_tensor && rhs_is_tensor)
0069         return compare(T( lhs ), static_cast<T const&>( rhs ), pred);
0070     else
0071         return compare(T( lhs ), T( rhs ), pred);
0072 
0073 }
0074 
0075 template<class T, class D, class UnaryPred>
0076 bool compare(tensor_expression<T,D> const& expr, UnaryPred pred)
0077 {
0078     if constexpr (std::is_same<T,D>::value)
0079         return compare(static_cast<T const&>( expr ), pred);
0080     else
0081         return compare(T( expr ), pred);
0082 }
0083 
0084 }
0085 
0086 
0087 template<class T, class L, class R>
0088 bool operator==( boost::numeric::ublas::detail::tensor_expression<T,L> const& lhs,
0089                                  boost::numeric::ublas::detail::tensor_expression<T,R> const& rhs) {
0090     return boost::numeric::ublas::detail::compare( lhs, rhs, std::equal_to<>{} );
0091 }
0092 template<class T, class L, class R>
0093 auto operator!=(boost::numeric::ublas::detail::tensor_expression<T,L> const& lhs,
0094                                 boost::numeric::ublas::detail::tensor_expression<T,R> const& rhs) {
0095     return boost::numeric::ublas::detail::compare( lhs, rhs, std::not_equal_to<>{}  );
0096 }
0097 template<class T, class L, class R>
0098 auto operator< ( boost::numeric::ublas::detail::tensor_expression<T,L> const& lhs,
0099                                  boost::numeric::ublas::detail::tensor_expression<T,R> const& rhs) {
0100     return boost::numeric::ublas::detail::compare( lhs, rhs, std::less<>{} );
0101 }
0102 template<class T, class L, class R>
0103 auto operator<=( boost::numeric::ublas::detail::tensor_expression<T,L> const& lhs,
0104                                  boost::numeric::ublas::detail::tensor_expression<T,R> const& rhs) {
0105     return boost::numeric::ublas::detail::compare( lhs, rhs, std::less_equal<>{} );
0106 }
0107 template<class T, class L, class R>
0108 auto operator> ( boost::numeric::ublas::detail::tensor_expression<T,L> const& lhs,
0109                                  boost::numeric::ublas::detail::tensor_expression<T,R> const& rhs) {
0110     return boost::numeric::ublas::detail::compare( lhs, rhs, std::greater<>{} );
0111 }
0112 template<class T, class L, class R>
0113 auto operator>=( boost::numeric::ublas::detail::tensor_expression<T,L> const& lhs,
0114                                  boost::numeric::ublas::detail::tensor_expression<T,R> const& rhs) {
0115     return boost::numeric::ublas::detail::compare( lhs, rhs, std::greater_equal<>{} );
0116 }
0117 
0118 
0119 
0120 
0121 
0122 template<class T, class D>
0123 bool operator==( typename T::const_reference lhs, boost::numeric::ublas::detail::tensor_expression<T,D> const& rhs) {
0124     return boost::numeric::ublas::detail::compare( rhs, [lhs](auto const& r){ return lhs == r; } );
0125 }
0126 template<class T, class D>
0127 auto operator!=( typename T::const_reference lhs, boost::numeric::ublas::detail::tensor_expression<T,D> const& rhs) {
0128     return boost::numeric::ublas::detail::compare( rhs, [lhs](auto const& r){ return lhs != r; } );
0129 }
0130 template<class T, class D>
0131 auto operator< ( typename T::const_reference lhs, boost::numeric::ublas::detail::tensor_expression<T,D> const& rhs) {
0132     return boost::numeric::ublas::detail::compare( rhs, [lhs](auto const& r){ return lhs <  r; } );
0133 }
0134 template<class T, class D>
0135 auto operator<=( typename T::const_reference lhs, boost::numeric::ublas::detail::tensor_expression<T,D> const& rhs) {
0136     return boost::numeric::ublas::detail::compare( rhs, [lhs](auto const& r){ return lhs <= r; } );
0137 }
0138 template<class T, class D>
0139 auto operator> ( typename T::const_reference lhs, boost::numeric::ublas::detail::tensor_expression<T,D> const& rhs) {
0140     return boost::numeric::ublas::detail::compare( rhs, [lhs](auto const& r){ return lhs >  r; } );
0141 }
0142 template<class T, class D>
0143 auto operator>=( typename T::const_reference lhs, boost::numeric::ublas::detail::tensor_expression<T,D> const& rhs) {
0144     return boost::numeric::ublas::detail::compare( rhs, [lhs](auto const& r){ return lhs >= r; } );
0145 }
0146 
0147 
0148 
0149 template<class T, class D>
0150 bool operator==( boost::numeric::ublas::detail::tensor_expression<T,D> const& lhs, typename T::const_reference rhs) {
0151     return boost::numeric::ublas::detail::compare( lhs, [rhs](auto const& l){ return l == rhs; } );
0152 }
0153 template<class T, class D>
0154 auto operator!=( boost::numeric::ublas::detail::tensor_expression<T,D> const& lhs, typename T::const_reference rhs) {
0155     return boost::numeric::ublas::detail::compare( lhs, [rhs](auto const& l){ return l != rhs; } );
0156 }
0157 template<class T, class D>
0158 auto operator< ( boost::numeric::ublas::detail::tensor_expression<T,D> const& lhs, typename T::const_reference rhs) {
0159     return boost::numeric::ublas::detail::compare( lhs, [rhs](auto const& l){ return l <  rhs; } );
0160 }
0161 template<class T, class D>
0162 auto operator<=( boost::numeric::ublas::detail::tensor_expression<T,D> const& lhs, typename T::const_reference rhs) {
0163     return boost::numeric::ublas::detail::compare( lhs, [rhs](auto const& l){ return l <= rhs; } );
0164 }
0165 template<class T, class D>
0166 auto operator> ( boost::numeric::ublas::detail::tensor_expression<T,D> const& lhs, typename T::const_reference rhs) {
0167     return boost::numeric::ublas::detail::compare( lhs, [rhs](auto const& l){ return l >  rhs; } );
0168 }
0169 template<class T, class D>
0170 auto operator>=( boost::numeric::ublas::detail::tensor_expression<T,D> const& lhs, typename T::const_reference rhs) {
0171     return boost::numeric::ublas::detail::compare( lhs, [rhs](auto const& l){ return l >= rhs; } );
0172 }
0173 
0174 
0175 #endif