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
|
|
|