More transparent definition of equals
Moved to namespace detail svn path=/trunk/boost/boost/numeric/ublas/; revision=27346
This commit is contained in:
parent
d25599dc28
commit
c93dbadfa9
@ -23,16 +23,26 @@
|
||||
// Iterators based on ideas of Jeremy Siek
|
||||
|
||||
namespace boost { namespace numeric { namespace ublas {
|
||||
namespace detail {
|
||||
|
||||
// Weak equality check - useful to compare equality two arbitary matrix expression results.
|
||||
// Since the actual expressions are unknown, we check for and arbitary error bound
|
||||
// on the relative error.
|
||||
// For a linear expression the infinity norm makes sense as we do not know how the elements will be
|
||||
// combined in the expression. False positive results are inevitable for arbirary expressions!
|
||||
template<class E1, class E2, class S>
|
||||
BOOST_UBLAS_INLINE
|
||||
bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2, S epsilon, S min_norm) {
|
||||
return norm_inf (e1 - e2) < epsilon *
|
||||
std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
|
||||
}
|
||||
|
||||
template<class E1, class E2>
|
||||
BOOST_UBLAS_INLINE
|
||||
bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
|
||||
bool expression_type_check (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
|
||||
typedef typename type_traits<typename promote_traits<typename E1::value_type,
|
||||
typename E2::value_type>::promote_type>::real_type real_type;
|
||||
return norm_inf (e1 - e2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
|
||||
std::max<real_type> (std::max<real_type> (norm_inf (e1),
|
||||
norm_inf (e2)),
|
||||
BOOST_UBLAS_TYPE_CHECK_MIN);
|
||||
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
|
||||
}
|
||||
|
||||
|
||||
@ -244,6 +254,9 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
m (index [k].first, index [k].second) = value_type/*zero*/();
|
||||
}
|
||||
|
||||
}//namespace detail
|
||||
|
||||
|
||||
// Explicitly iterating row major
|
||||
template<template <class T1, class T2> class F, class M, class T>
|
||||
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
||||
@ -635,13 +648,8 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
|
||||
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
|
||||
indexing_matrix_assign<F> (cm, e, row_major_tag ());
|
||||
#else
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
|
||||
indexing_matrix_assign<F>(cm, e, row_major_tag ());
|
||||
#endif
|
||||
#endif
|
||||
typename M::iterator1 it1 (m.begin1 ());
|
||||
typename M::iterator1 it1_end (m.end1 ());
|
||||
@ -754,7 +762,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
}
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
if (! disable_type_check<bool>::value)
|
||||
BOOST_UBLAS_CHECK (equals (m, cm), external_logic ());
|
||||
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
||||
#endif
|
||||
}
|
||||
// Packed (proxy) column major case
|
||||
@ -769,13 +777,8 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
|
||||
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
|
||||
indexing_matrix_assign<F> (cm, e, column_major_tag ());
|
||||
#else
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
|
||||
indexing_matrix_assign<F> (cm, e, column_major_tag ());
|
||||
#endif
|
||||
#endif
|
||||
typename M::iterator2 it2 (m.begin2 ());
|
||||
typename M::iterator2 it2_end (m.end2 ());
|
||||
@ -888,7 +891,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
}
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
if (! disable_type_check<bool>::value)
|
||||
BOOST_UBLAS_CHECK (equals (m, cm), external_logic ());
|
||||
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
||||
#endif
|
||||
}
|
||||
// Sparse row major case
|
||||
@ -968,15 +971,10 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
|
||||
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
|
||||
indexing_matrix_assign<F> (cm, e, row_major_tag ());
|
||||
#else
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
|
||||
indexing_matrix_assign<F> (cm, e, row_major_tag ());
|
||||
#endif
|
||||
#endif
|
||||
make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
|
||||
detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
|
||||
|
||||
typename M::iterator1 it1 (m.begin1 ());
|
||||
typename M::iterator1 it1_end (m.end1 ());
|
||||
@ -1077,7 +1075,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
}
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
if (! disable_type_check<bool>::value)
|
||||
BOOST_UBLAS_CHECK (equals (m, cm), external_logic ());
|
||||
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
||||
#endif
|
||||
}
|
||||
// Sparse proxy or functional column major case
|
||||
@ -1093,15 +1091,10 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
|
||||
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
|
||||
indexing_matrix_assign<F> (cm, e, column_major_tag ());
|
||||
#else
|
||||
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
|
||||
indexing_matrix_assign<F> (cm, e, column_major_tag ());
|
||||
#endif
|
||||
#endif
|
||||
make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
|
||||
detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
|
||||
|
||||
typename M::iterator2 it2 (m.begin2 ());
|
||||
typename M::iterator2 it2_end (m.end2 ());
|
||||
@ -1202,7 +1195,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
}
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
if (! disable_type_check<bool>::value)
|
||||
BOOST_UBLAS_CHECK (equals (m, cm), external_logic ());
|
||||
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1367,9 +1360,9 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
||||
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
||||
|
||||
make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
|
||||
detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
|
||||
// FIXME should be a seperate restriction for E
|
||||
make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
|
||||
detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
|
||||
|
||||
typename M::iterator1 it1 (m.begin1 ());
|
||||
typename M::iterator1 it1_end (m.end1 ());
|
||||
@ -1492,9 +1485,9 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
||||
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
||||
|
||||
make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
|
||||
detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
|
||||
// FIXME should be a seperate restriction for E
|
||||
make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
|
||||
detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
|
||||
|
||||
typename M::iterator2 it2 (m.begin2 ());
|
||||
typename M::iterator2 it2_end (m.end2 ());
|
||||
|
@ -23,16 +23,26 @@
|
||||
// Iterators based on ideas of Jeremy Siek
|
||||
|
||||
namespace boost { namespace numeric { namespace ublas {
|
||||
namespace detail {
|
||||
|
||||
// Weak equality check - useful to compare equality two arbitary vector expression results.
|
||||
// Since the actual expressions are unknown, we check for and arbitary error bound
|
||||
// on the relative error.
|
||||
// For a linear expression the infinity norm makes sense as we do not know how the elements will be
|
||||
// combined in the expression. False positive results are inevitable for arbirary expressions!
|
||||
template<class E1, class E2, class S>
|
||||
BOOST_UBLAS_INLINE
|
||||
bool equals (const vector_expression<E1> &e1, const vector_expression<E2> &e2, S epsilon, S min_norm) {
|
||||
return norm_inf (e1 - e2) < epsilon *
|
||||
std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
|
||||
}
|
||||
|
||||
template<class E1, class E2>
|
||||
BOOST_UBLAS_INLINE
|
||||
bool equals (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
|
||||
bool expression_type_check (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
|
||||
typedef typename type_traits<typename promote_traits<typename E1::value_type,
|
||||
typename E2::value_type>::promote_type>::real_type real_type;
|
||||
return norm_inf (e1 - e2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
|
||||
std::max<real_type> (std::max<real_type> (norm_inf (e1),
|
||||
norm_inf (e2)),
|
||||
BOOST_UBLAS_TYPE_CHECK_MIN);
|
||||
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
|
||||
}
|
||||
|
||||
|
||||
@ -88,6 +98,9 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
v (index [k]) = value_type/*zero*/();
|
||||
}
|
||||
|
||||
}//namespace detail
|
||||
|
||||
|
||||
// Explicitly iterating
|
||||
template<template <class T1, class T2> class F, class V, class T>
|
||||
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
||||
@ -286,13 +299,8 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typedef typename V::value_type value_type;
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
vector<value_type> cv (v.size ());
|
||||
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
|
||||
indexing_vector_assign<scalar_assign> (cv, v);
|
||||
indexing_vector_assign<F> (cv, e);
|
||||
#else
|
||||
indexing_vector_assign<scalar_assign> (cv, v);
|
||||
indexing_vector_assign<F> (cv, e);
|
||||
#endif
|
||||
#endif
|
||||
typename V::iterator it (v.begin ());
|
||||
typename V::iterator it_end (v.end ());
|
||||
@ -333,7 +341,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
}
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
if (! disable_type_check<bool>::value)
|
||||
BOOST_UBLAS_CHECK (equals (v, cv), external_logic ());
|
||||
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv), external_logic ());
|
||||
#endif
|
||||
}
|
||||
// Sparse case
|
||||
@ -346,13 +354,8 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typedef typename V::value_type value_type;
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
vector<value_type> cv (v.size ());
|
||||
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
|
||||
indexing_vector_assign<scalar_assign> (cv, v);
|
||||
indexing_vector_assign<F> (cv, e);
|
||||
#else
|
||||
indexing_vector_assign<scalar_assign> (cv, v);
|
||||
indexing_vector_assign<F> (cv, e);
|
||||
#endif
|
||||
#endif
|
||||
v.clear ();
|
||||
typename E::const_iterator ite (e ().begin ());
|
||||
@ -365,7 +368,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
}
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
if (! disable_type_check<bool>::value)
|
||||
BOOST_UBLAS_CHECK (equals (v, cv), external_logic ());
|
||||
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv), external_logic ());
|
||||
#endif
|
||||
}
|
||||
// Sparse proxy or functional case
|
||||
@ -380,15 +383,10 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typedef typename V::reference reference;
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
vector<value_type> cv (v.size ());
|
||||
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
|
||||
indexing_vector_assign<scalar_assign> (cv, v);
|
||||
indexing_vector_assign<F> (cv, e);
|
||||
#else
|
||||
indexing_vector_assign<scalar_assign> (cv, v);
|
||||
indexing_vector_assign<F> (cv, e);
|
||||
#endif
|
||||
#endif
|
||||
make_conformant (v, e);
|
||||
detail::make_conformant (v, e);
|
||||
|
||||
typename V::iterator it (v.begin ());
|
||||
typename V::iterator it_end (v.end ());
|
||||
@ -436,7 +434,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
}
|
||||
#if BOOST_UBLAS_TYPE_CHECK
|
||||
if (! disable_type_check<bool>::value)
|
||||
BOOST_UBLAS_CHECK (equals (v, cv), external_logic ());
|
||||
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv), external_logic ());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -517,8 +515,9 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typedef typename V::difference_type difference_type;
|
||||
typedef typename V::value_type value_type;
|
||||
|
||||
make_conformant (v, e);
|
||||
make_conformant (e (), v);
|
||||
detail::make_conformant (v, e);
|
||||
// FIXME should be a seperate restriction for E
|
||||
detail::make_conformant (e (), v);
|
||||
|
||||
typename V::iterator it (v.begin ());
|
||||
typename V::iterator it_end (v.end ());
|
||||
|
Loading…
Reference in New Issue
Block a user