Ticket #7296: utils-fix_complex-201208281922.patch

File utils-fix_complex-201208281922.patch, 7.9 KB (added by Marco Guazzone <marco.guazzone@…>, 10 years ago)

Patch file for utils.hpp to make it works with complex numbers. To be applied to the version of utils.hpp in the current boost trunk.

  • libs/numeric/ublas/test/utils.hpp

    diff -Naur /old/libs/numeric/ublas/test/utils.hpp /new/libs/numeric/ublas/test/utils.hpp
    old new  
    11/**
    2  *  \file util.hpp
     2 * \file util.hpp
    33 *
    4  *  \brief Utility macros/functions for testing and debugging purpose.
     4 * \brief Utility macros/functions for testing and debugging purpose.
     5 *
     6 * Basic usage:
     7 * <pre>
     8 * BOOST_UBLAS_TEST_DEF( test_case_1 )
     9 * {
     10 *   // do your test stuff
     11 * }
     12 *
     13 * BOOST_UBLAS_TEST_DEF( test_case_2 )
     14 * {
     15 *   // do your test stuff
     16 * }
     17 *
     18 * // ...
     19 *
     20 * BOOST_UBLAS_TEST_DEF( test_case_n )
     21 * {
     22 *   // do your test stuff
     23 * }
     24 *
     25 * int main()
     26 * {
     27 *   BOOST_UBLAS_TEST_SUITE( "My Test Suite" ); // optional
     28 *
     29 *   BOOST_UBLAS_TEST_BEGIN();
     30 *     BOOST_UBLAS_TEST_DO( test_case_1 );
     31 *     BOOST_UBLAS_TEST_DO( test_case_2 );
     32 *     // ...
     33 *     BOOST_UBLAS_TEST_DO( test_case_n );
     34 *   BOOST_UBLAS_TEST_END();
     35 * }
     36 * </pre>
     37 * Inside each <em>test_case_<code>k</code></em> you can use the various
     38 * \c BOOST_UBLAS_TEST_CHECK* macros.
     39 *
     40 * <hr/>
    541 *
    642 *  Copyright (c) 2009-2012, Marco Guazzone
    743 *
     
    1652#define BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP
    1753
    1854
     55#include <boost/numeric/ublas/detail/config.hpp>
     56#include <boost/numeric/ublas/traits.hpp>
    1957#include <cmath>
     58#include <complex>
    2059#include <iostream>
    2160#include <limits>
    2261#include <stdexcept>
     
    2463
    2564namespace boost { namespace numeric { namespace ublas { namespace test { namespace detail { namespace /*<unnamed>*/ {
    2665
     66/// Check if the given complex number is a NaN.
     67template <typename T>
     68BOOST_UBLAS_INLINE
     69bool isnan(::std::complex<T> const& z)
     70{
     71        // According to IEEE, NaN is different even by itself
     72        return (z != z) || ::std::isnan(z.real()) || ::std::isnan(z.imag());
     73}
     74
     75/// Check if two (real) numbers are close each other (wrt a given tolerance).
    2776template <typename T1, typename T2, typename T3>
    28 inline
     77BOOST_UBLAS_INLINE
    2978bool close_to(T1 x, T2 y, T3 tol)
    3079{
     80        typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
     81                                                                        T3>::promote_type real_type;
     82
     83    if (::std::isnan(x) || ::std::isnan(y))
     84    {
     85        // According to IEEE, NaN is different even by itself
     86        return false;
     87    }
     88    return ::std::abs(x-y) <= (::std::max(static_cast<real_type>(::std::abs(x)), static_cast<real_type>(::std::abs(y)))*tol);
     89}
     90
     91/// Check if two complex numbers are close each other (wrt a given tolerance).
     92template <typename T1, typename T2, typename T3>
     93BOOST_UBLAS_INLINE
     94bool close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol)
     95{
     96        typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
     97                                                                        T3>::promote_type real_type;
     98
     99    if (isnan(x) || isnan(y))
     100    {
     101        // According to IEEE, NaN is different even by itself
     102        return false;
     103    }
     104        ::std::complex<real_type> xx(x);
     105        ::std::complex<real_type> yy(y);
     106    return ::std::abs(xx-yy) <= (::std::max(::std::abs(xx), ::std::abs(yy))*tol);
     107}
     108
     109/// Check if two (real) numbers are close each other (wrt a given tolerance).
     110template <typename T1, typename T2, typename T3>
     111BOOST_UBLAS_INLINE
     112bool rel_close_to(T1 x, T2 y, T3 tol)
     113{
     114        typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
     115                                                                        T3>::promote_type real_type;
     116
    31117    if (::std::isnan(x) || ::std::isnan(y))
    32118    {
    33         // According to IEEE, NaN are different event by itself
     119        // According to IEEE, NaN is different even by itself
     120        return false;
     121    }
     122    return ::std::abs(x-y)/::std::abs(y) <= tol;
     123}
     124
     125/// Check if two complex numbers are close each other (wrt a given tolerance).
     126template <typename T1, typename T2, typename T3>
     127BOOST_UBLAS_INLINE
     128bool rel_close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol)
     129{
     130        typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
     131                                                                        T3>::promote_type real_type;
     132
     133    if (isnan(x) || isnan(y))
     134    {
     135        // According to IEEE, NaN is different even by itself
    34136        return false;
    35137    }
    36     return ::std::abs(x-y) <= (::std::max(::std::abs(x), ::std::abs(y))*tol);
     138        ::std::complex<real_type> xx(x);
     139        ::std::complex<real_type> yy(y);
     140    return ::std::abs(xx-yy)/::std::abs(yy) <= tol;
    37141}
    38142
    39143}}}}}} // Namespace boost::numeric::ublas::test::detail::<unnamed>
     
    60164
    61165
    62166/// Define the name of the entire test suite.
    63 #define DCS_TEST_SUITE(m) ::std::cerr << "--- Test Suite: " << m << " ---" << ::std::endl;
     167#define BOOST_UBLAS_TEST_SUITE(m) ::std::cerr << "--- Test Suite: " << m << " ---" << ::std::endl;
    64168
    65169
    66170/// Define the beginning of a test suite.
     
    72176
    73177
    74178/// Define a test case \a x inside the current test suite.
    75 #define BOOST_UBLAS_TEST_DEF(x) void BOOST_UBLAS_TEST_EXPAND_(x)(unsigned int& test_fails__)
     179#define BOOST_UBLAS_TEST_DEF(x) static void BOOST_UBLAS_TEST_EXPAND_(x)(unsigned int& test_fails__)
    76180
    77181
    78182/// Call the test case \a x.
     
    107211                                                                /* [/BOOST_UBLAS_TEST_END] */
    108212
    109213
     214/// Output the message \a m.
     215#define BOOST_UBLAS_TEST_TRACE(m) ::std::cerr << "[Info>> " << BOOST_UBLAS_TEST_EXPAND_(m) << ::std::endl
     216
     217
    110218/// Check the truth of assertion \a x.
    111219#define BOOST_UBLAS_TEST_CHECK(x)       /* [BOOST_UBLAS_TEST_CHECK] */ \
    112220                                                                        if (!(x)) \
     
    119227
    120228/// Check for the equality of \a x against \a y.
    121229#define BOOST_UBLAS_TEST_CHECK_EQ(x,y)  /* [BOOST_UBLAS_TEST_CHECK_EQUAL] */ \
    122                                                                                 if (!(BOOST_UBLAS_TEST_PARAM_EXPAND_(x) == BOOST_UBLAS_TEST_PARAM_EXPAND_(y))) \
     230                                                                                if (!(BOOST_UBLAS_TEST_EXPAND_(x) == BOOST_UBLAS_TEST_EXPAND_(y))) \
    123231                                                                                { \
    124232                                                                                        BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")" ); \
    125233                                                                                        ++test_fails__; \
     
    146254
    147255
    148256/// Check that \a x is close to \a y with respect to a given relative precision.
    149 #define BOOST_UBLAS_TEST_CHECK_REL_PRECISION(x,y,e)     /* [BOOST_UBLAS_TEST_CHECK_REL_PRECISION] */ \
    150                                                                                                         if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPAND_(x)/BOOST_UBLAS_TEST_EXPAND_(y), 1.0, BOOST_UBLAS_TEST_EXPAND_(e))) \
    151                                                                                                         { \
    152                                                                                                                 BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")/" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e)  << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPAND_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPAND_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPAND_(e) << "]" ); \
    153                                                                                                                 ++test_fails__; \
    154                                                                                                         } \
    155                                                                                                         /* [/BOOST_UBLAS_TEST_CHECK_REL_PRECISION] */
     257#define BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e) /* [BOOST_UBLAS_TEST_CHECK_REL_PRECISION] */ \
     258                                                                                                if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPAND_(x), BOOST_UBLAS_TEST_EXPAND_(y), BOOST_UBLAS_TEST_EXPAND_(e))) \
     259                                                                                                { \
     260                                                                                                        BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")/" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e)  << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPAND_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPAND_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPAND_(e) << "]" ); \
     261                                                                                                        ++test_fails__; \
     262                                                                                                } \
     263                                                                                                /* [/BOOST_UBLAS_TEST_CHECK_REL_PRECISION] */
     264
     265
     266/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_REL_CLOSE (for backward compatibility),
     267#define BOOST_UBLAS_TEST_CHECK_REL_PRECISION(x,y,e) BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e)
    156268
    157269
    158270/// Check that elements of \a x and \a y are equal.