mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
	
	
		
			221 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			221 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | //  (C) Copyright John Maddock 2006-7.
 | ||
|  | //  Use, modification and distribution are subject to the
 | ||
|  | //  Boost Software License, Version 1.0. (See accompanying file
 | ||
|  | //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||
|  | 
 | ||
|  | #ifndef BOOST_MATH_HANDLE_TEST_RESULT
 | ||
|  | #define BOOST_MATH_HANDLE_TEST_RESULT
 | ||
|  | 
 | ||
|  | #include <boost/math/tools/stats.hpp>
 | ||
|  | #include <boost/math/tools/test.hpp>
 | ||
|  | #include <boost/math/tools/precision.hpp>
 | ||
|  | #include <boost/regex.hpp>
 | ||
|  | #include <boost/test/test_tools.hpp>
 | ||
|  | #include <iostream>
 | ||
|  | #include <iomanip>
 | ||
|  | 
 | ||
|  | #if defined(BOOST_INTEL)
 | ||
|  | #  pragma warning(disable:239)
 | ||
|  | #  pragma warning(disable:264)
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | //
 | ||
|  | // Every client of this header has to define this function,
 | ||
|  | // and initialise the table of expected results:
 | ||
|  | //
 | ||
|  | void expected_results(); | ||
|  | 
 | ||
|  | typedef std::pair<boost::regex, std::pair<boost::uintmax_t, boost::uintmax_t> > expected_data_type; | ||
|  | typedef std::list<expected_data_type> list_type; | ||
|  | 
 | ||
|  | inline list_type&  | ||
|  |    get_expected_data() | ||
|  | { | ||
|  |    static list_type data; | ||
|  |    return data; | ||
|  | } | ||
|  | 
 | ||
|  | inline void add_expected_result( | ||
|  |    const char* compiler, | ||
|  |    const char* library, | ||
|  |    const char* platform, | ||
|  |    const char* type_name, | ||
|  |    const char* test_name, | ||
|  |    const char* group_name,  | ||
|  |    boost::uintmax_t max_peek_error,  | ||
|  |    boost::uintmax_t max_mean_error) | ||
|  | { | ||
|  |    std::string re("(?:"); | ||
|  |    re += compiler; | ||
|  |    re += ")"; | ||
|  |    re += "\\|"; | ||
|  |    re += "(?:"; | ||
|  |    re += library; | ||
|  |    re += ")"; | ||
|  |    re += "\\|"; | ||
|  |    re += "(?:"; | ||
|  |    re += platform; | ||
|  |    re += ")"; | ||
|  |    re += "\\|"; | ||
|  |    re += "(?:"; | ||
|  |    re += type_name; | ||
|  |    re += ")"; | ||
|  |    re += "\\|"; | ||
|  |    re += "(?:"; | ||
|  |    re += test_name; | ||
|  |    re += ")"; | ||
|  |    re += "\\|"; | ||
|  |    re += "(?:"; | ||
|  |    re += group_name; | ||
|  |    re += ")"; | ||
|  |    get_expected_data().push_back( | ||
|  |       std::make_pair(boost::regex(re, boost::regex::perl | boost::regex::icase),  | ||
|  |          std::make_pair(max_peek_error, max_mean_error))); | ||
|  | } | ||
|  | 
 | ||
|  | inline std::string build_test_name(const char* type_name, const char* test_name, const char* group_name) | ||
|  | { | ||
|  |    std::string result(BOOST_COMPILER); | ||
|  |    result += "|"; | ||
|  |    result += BOOST_STDLIB; | ||
|  |    result += "|"; | ||
|  |    result += BOOST_PLATFORM; | ||
|  |    result += "|"; | ||
|  |    result += type_name; | ||
|  |    result += "|"; | ||
|  |    result += group_name; | ||
|  |    result += "|"; | ||
|  |    result += test_name; | ||
|  |    return result; | ||
|  | } | ||
|  | 
 | ||
|  | inline const std::pair<boost::uintmax_t, boost::uintmax_t>& | ||
|  |    get_max_errors(const char* type_name, const char* test_name, const char* group_name) | ||
|  | { | ||
|  |    static const std::pair<boost::uintmax_t, boost::uintmax_t> defaults(1, 1); | ||
|  |    std::string name = build_test_name(type_name, test_name, group_name); | ||
|  |    list_type& l = get_expected_data(); | ||
|  |    list_type::const_iterator a(l.begin()), b(l.end()); | ||
|  |    while(a != b) | ||
|  |    { | ||
|  |       if(regex_match(name, a->first)) | ||
|  |       { | ||
|  | #if 0
 | ||
|  |          std::cout << name << std::endl; | ||
|  |          std::cout << a->first.str() << std::endl; | ||
|  | #endif
 | ||
|  |          return a->second; | ||
|  |       } | ||
|  |       ++a; | ||
|  |    } | ||
|  |    return defaults; | ||
|  | } | ||
|  | 
 | ||
|  | template <class T, class Seq> | ||
|  | void handle_test_result(const boost::math::tools::test_result<T>& result, | ||
|  |                        const Seq& worst, int row,  | ||
|  |                        const char* type_name,  | ||
|  |                        const char* test_name,  | ||
|  |                        const char* group_name) | ||
|  | { | ||
|  | #ifdef BOOST_MSVC
 | ||
|  | #pragma warning(push)
 | ||
|  | #pragma warning(disable:4127)
 | ||
|  | #endif
 | ||
|  |    using namespace std; // To aid selection of the right pow.
 | ||
|  |    T eps = boost::math::tools::epsilon<T>(); | ||
|  |    std::cout << std::setprecision(4); | ||
|  | 
 | ||
|  |    T max_error_found = (result.max)()/eps; | ||
|  |    T mean_error_found = result.rms()/eps; | ||
|  |    //
 | ||
|  |    // Begin by printing the main tag line with the results:
 | ||
|  |    //
 | ||
|  |    std::cout << test_name << "<" << type_name << "> Max = " << max_error_found | ||
|  |       << " RMS Mean=" << mean_error_found; | ||
|  |    //
 | ||
|  |    // If the max error is non-zero, give the row of the table that
 | ||
|  |    // produced the worst error:
 | ||
|  |    //
 | ||
|  |    if((result.max)() != 0) | ||
|  |    { | ||
|  |       std::cout << "\n    worst case at row: " | ||
|  |          << row << "\n    { "; | ||
|  |       if(std::numeric_limits<T>::digits10) | ||
|  |       { | ||
|  |          std::cout << std::setprecision(std::numeric_limits<T>::digits10 + 2); | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |          std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 2); | ||
|  |       } | ||
|  |       for(unsigned i = 0; i < worst.size(); ++i) | ||
|  |       { | ||
|  |          if(i) | ||
|  |             std::cout << ", "; | ||
|  | #if defined(__SGI_STL_PORT)
 | ||
|  |          std::cout << boost::math::tools::real_cast<double>(worst[i]); | ||
|  | #else
 | ||
|  |          std::cout << worst[i]; | ||
|  | #endif
 | ||
|  |       } | ||
|  |       std::cout << " }"; | ||
|  |    } | ||
|  |    std::cout << std::endl; | ||
|  |    //
 | ||
|  |    // Now verify that the results are within our expected bounds:
 | ||
|  |    //
 | ||
|  |    std::pair<boost::uintmax_t, boost::uintmax_t> const& bounds = get_max_errors(type_name, test_name, group_name); | ||
|  |    if(bounds.first < max_error_found) | ||
|  |    { | ||
|  |       std::cerr << "Peak error greater than expected value of " << bounds.first << std::endl; | ||
|  |       BOOST_CHECK(bounds.first >= max_error_found); | ||
|  |    } | ||
|  |    if(bounds.second < mean_error_found) | ||
|  |    { | ||
|  |       std::cerr << "Mean error greater than expected value of " << bounds.second << std::endl; | ||
|  |       BOOST_CHECK(bounds.second >= mean_error_found); | ||
|  |    } | ||
|  |    std::cout << std::endl; | ||
|  | #ifdef BOOST_MSVC
 | ||
|  | #pragma warning(pop)
 | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | template <class T, class Seq> | ||
|  | void print_test_result(const boost::math::tools::test_result<T>& result, | ||
|  |                        const Seq& worst, int row, const char* name, const char* test) | ||
|  | { | ||
|  |    using namespace std; // To aid selection of the right pow.
 | ||
|  |    T eps = boost::math::tools::epsilon<T>(); | ||
|  |    std::cout << std::setprecision(4); | ||
|  | 
 | ||
|  |    T max_error_found = (result.max)()/eps; | ||
|  |    T mean_error_found = result.rms()/eps; | ||
|  |    //
 | ||
|  |    // Begin by printing the main tag line with the results:
 | ||
|  |    //
 | ||
|  |    std::cout << test << "(" << name << ") Max = " << max_error_found | ||
|  |       << " RMS Mean=" << mean_error_found; | ||
|  |    //
 | ||
|  |    // If the max error is non-zero, give the row of the table that
 | ||
|  |    // produced the worst error:
 | ||
|  |    //
 | ||
|  |    if((result.max)() != 0) | ||
|  |    { | ||
|  |       std::cout << "\n    worst case at row: " | ||
|  |          << row << "\n    { "; | ||
|  |       for(unsigned i = 0; i < worst.size(); ++i) | ||
|  |       { | ||
|  |          if(i) | ||
|  |             std::cout << ", "; | ||
|  |          std::cout << worst[i]; | ||
|  |       } | ||
|  |       std::cout << " }"; | ||
|  |    } | ||
|  |    std::cout << std::endl; | ||
|  | } | ||
|  | 
 | ||
|  | #endif // BOOST_MATH_HANDLE_TEST_RESULT
 | ||
|  | 
 |