00001
00002
00003
00004
00005
00006
00007
00008
00017 #ifndef matrix_comparison_h
00018 #define matrix_comparison_h
00019
00020 #include <cml/core/cml_assert.h>
00021 #include <cml/et/size_checking.h>
00022 #include <cml/et/scalar_ops.h>
00023
00024
00025
00026
00027 struct matrix_comparison_expects_matrix_args_error;
00028
00029 #define CML_MAT_MAT_ORDER(_order_, _op_, _OpT_) \
00030 template<typename E1, class AT1, typename L1, \
00031 typename E2, class AT2, typename L2, typename BO> \
00032 inline bool \
00033 _op_ ( \
00034 const matrix<E1,AT1,L1,BO>& left, \
00035 const matrix<E2,AT2,L2,BO>& right) \
00036 { \
00037 return detail::matrix_##_order_ (left, right, _OpT_ <E1,E2>()); \
00038 }
00039
00040 #define CML_MAT_MATXPR_ORDER(_order_, _op_, _OpT_) \
00041 template<typename E, class AT, typename L, typename BO, class XprT> \
00042 inline bool \
00043 _op_ ( \
00044 const matrix<E,AT,L,BO>& left, \
00045 MATXPR_ARG_TYPE right) \
00046 { \
00047 return detail::matrix_##_order_ (left, right, \
00048 _OpT_ <E, typename XprT::value_type>()); \
00049 }
00050
00051 #define CML_MATXPR_MAT_ORDER(_order_, _op_, _OpT_) \
00052 template<class XprT, typename E, class AT, typename L, typename BO> \
00053 inline bool \
00054 _op_ ( \
00055 MATXPR_ARG_TYPE left, \
00056 const matrix<E,AT,L,BO>& right) \
00057 { \
00058 return detail::matrix_##_order_ (left, right, \
00059 _OpT_ <typename XprT::value_type, E>()); \
00060 }
00061
00062 #define CML_MATXPR_MATXPR_ORDER(_order_, _op_, _OpT_) \
00063 template<class XprT1, class XprT2> \
00064 inline bool \
00065 _op_ ( \
00066 MATXPR_ARG_TYPE_N(1) left, \
00067 MATXPR_ARG_TYPE_N(2) right) \
00068 { \
00069 return detail::matrix_##_order_ (left, right, \
00070 _OpT_ < \
00071 typename XprT1::value_type, \
00072 typename XprT2::value_type>()); \
00073 }
00074
00075
00076 namespace cml {
00077 namespace detail {
00078
00085 template<typename LeftT, typename RightT, typename OpT>
00086 inline bool
00087 matrix_weak_order(const LeftT& left, const RightT& right, OpT)
00088 {
00089
00090 typedef et::ExprTraits<LeftT> left_traits;
00091 typedef et::ExprTraits<RightT> right_traits;
00092
00093
00094 CML_STATIC_REQUIRE_M(
00095 (et::MatrixExpressions<LeftT,RightT>::is_true),
00096 matrix_comparison_expects_matrix_args_error);
00097
00098
00099
00100
00101 typedef typename et::MatrixPromote<
00102 typename left_traits::result_type,
00103 typename right_traits::result_type
00104 >::type result_type;
00105 typedef typename result_type::size_tag size_tag;
00106
00107
00108 matrix_size N = et::CheckedSize(left,right,size_tag());
00109 for(ssize_t i = 0; i < N.first; ++ i) {
00110 for(ssize_t j = 0; j < N.second; ++ j) {
00111 if(OpT().apply(
00112 left_traits().get(left,i,j),
00113 right_traits().get(right,i,j)
00114 ))
00115 {
00116
00117 return true;
00118 } else if(OpT().apply(
00119 right_traits().get(right,i,j),
00120 left_traits().get(left,i,j)
00121 ))
00122 {
00123
00124 return false;
00125 } else {
00126
00127
00128
00129
00130 continue;
00131 }
00132 }
00133 }
00134
00135
00136
00137 return false;
00138 }
00139
00145 template<typename LeftT, typename RightT, typename OpT>
00146 inline bool
00147 matrix_total_order(const LeftT& left, const RightT& right, OpT)
00148 {
00149
00150 typedef et::ExprTraits<LeftT> left_traits;
00151 typedef et::ExprTraits<RightT> right_traits;
00152
00153
00154 CML_STATIC_REQUIRE_M(
00155 (et::MatrixExpressions<LeftT,RightT>::is_true),
00156 matrix_comparison_expects_matrix_args_error);
00157
00158
00159
00160
00161 typedef typename et::MatrixPromote<
00162 typename left_traits::result_type,
00163 typename right_traits::result_type
00164 >::type result_type;
00165 typedef typename result_type::size_tag size_tag;
00166
00167
00168 matrix_size N = et::CheckedSize(left,right,size_tag());
00169 for(ssize_t i = 0; i < N.first; ++ i) {
00170 for(ssize_t j = 0; j < N.second; ++ j) {
00171
00172
00173 if(OpT().apply(
00174 left_traits().get(left,i,j),
00175 right_traits().get(right,i,j)
00176 ))
00177 {
00178
00179
00180
00181 if(!OpT().apply(
00182 right_traits().get(right,i,j),
00183 left_traits().get(left,i,j)
00184 ))
00185 return true;
00186
00187
00188
00189
00190 else
00191 continue;
00192
00193 } else {
00194
00195
00196 return false;
00197 }
00198 }
00199 }
00200
00201
00202
00203 return true;
00204 }
00205
00206 }
00207
00208 }
00209
00210
00211
00212 CML_MAT_VEC_ORDER( total_order, operator==, et::OpEqual)
00213 CML_MATXPR_MAT_ORDER( total_order, operator==, et::OpEqual)
00214 CML_MAT_MATXPR_ORDER( total_order, operator==, et::OpEqual)
00215 CML_MATXPR_VECXPR_ORDER( total_order, operator==, et::OpEqual)
00216
00217 CML_MAT_VEC_ORDER( weak_order, operator!=, et::OpNotEqual)
00218 CML_MATXPR_MAT_ORDER( weak_order, operator!=, et::OpNotEqual)
00219 CML_MAT_MATXPR_ORDER( weak_order, operator!=, et::OpNotEqual)
00220 CML_MATXPR_VECXPR_ORDER( weak_order, operator!=, et::OpNotEqual)
00221
00222 CML_MAT_VEC_ORDER( weak_order, operator<, et::OpLess)
00223 CML_MATXPR_MAT_ORDER( weak_order, operator<, et::OpLess)
00224 CML_MAT_MATXPR_ORDER( weak_order, operator<, et::OpLess)
00225 CML_MATXPR_VECXPR_ORDER( weak_order, operator<, et::OpLess)
00226
00227 CML_MAT_VEC_ORDER( weak_order, operator>, et::OpGreater)
00228 CML_MATXPR_MAT_ORDER( weak_order, operator>, et::OpGreater)
00229 CML_MAT_MATXPR_ORDER( weak_order, operator>, et::OpGreater)
00230 CML_MATXPR_VECXPR_ORDER( weak_order, operator>, et::OpGreater)
00231
00232 CML_MAT_VEC_ORDER( total_order, operator<=, et::OpLessEqual)
00233 CML_MATXPR_MAT_ORDER( total_order, operator<=, et::OpLessEqual)
00234 CML_MAT_MATXPR_ORDER( total_order, operator<=, et::OpLessEqual)
00235 CML_MATXPR_VECXPR_ORDER( total_order, operator<=, et::OpLessEqual)
00236
00237 CML_MAT_VEC_ORDER( total_order, operator>=, et::OpGreaterEqual)
00238 CML_MATXPR_MAT_ORDER( total_order, operator>=, et::OpGreaterEqual)
00239 CML_MAT_MATXPR_ORDER( total_order, operator>=, et::OpGreaterEqual)
00240 CML_MATXPR_VECXPR_ORDER( total_order, operator>=, et::OpGreaterEqual)
00241
00242 #endif
00243
00244
00245