summaryrefslogtreecommitdiff
path: root/boost/math/tools/test_data.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/math/tools/test_data.hpp')
-rw-r--r--boost/math/tools/test_data.hpp767
1 files changed, 0 insertions, 767 deletions
diff --git a/boost/math/tools/test_data.hpp b/boost/math/tools/test_data.hpp
deleted file mode 100644
index 56bae051b4..0000000000
--- a/boost/math/tools/test_data.hpp
+++ /dev/null
@@ -1,767 +0,0 @@
-// (C) Copyright John Maddock 2006.
-// 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_TOOLS_TEST_DATA_HPP
-#define BOOST_MATH_TOOLS_TEST_DATA_HPP
-
-#ifdef _MSC_VER
-#pragma once
-#endif
-
-#include <boost/math/tools/config.hpp>
-#include <boost/assert.hpp>
-#ifdef BOOST_MSVC
-# pragma warning(push)
-# pragma warning(disable: 4127 4701 4512)
-# pragma warning(disable: 4130) // '==' : logical operation on address of string constant.
-#endif
-#include <boost/algorithm/string/trim.hpp>
-#include <boost/lexical_cast.hpp>
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
-#include <boost/type_traits/is_floating_point.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/type_traits/integral_constant.hpp>
-#include <boost/tr1/random.hpp>
-#include <boost/math/tools/tuple.hpp>
-#include <boost/math/tools/real_cast.hpp>
-
-#include <set>
-#include <vector>
-#include <iostream>
-
-#ifdef BOOST_MSVC
-# pragma warning(push)
-# pragma warning(disable: 4130) // '==' : logical operation on address of string constant.
-// Used as a warning with BOOST_ASSERT
-#endif
-
-namespace boost{ namespace math{ namespace tools{
-
-enum parameter_type
-{
- random_in_range = 0,
- periodic_in_range = 1,
- power_series = 2,
- dummy_param = 0x80
-};
-
-parameter_type operator | (parameter_type a, parameter_type b)
-{
- return static_cast<parameter_type>((int)a|(int)b);
-}
-parameter_type& operator |= (parameter_type& a, parameter_type b)
-{
- a = static_cast<parameter_type>(a|b);
- return a;
-}
-
-//
-// If type == random_in_range then
-// z1 and r2 are the endpoints of the half open range and n1 is the number of points.
-//
-// If type == periodic_in_range then
-// z1 and r2 are the endpoints of the half open range and n1 is the number of points.
-//
-// If type == power_series then
-// n1 and n2 are the endpoints of the exponents (closed range) and z1 is the basis.
-//
-// If type & dummy_param then this data is ignored and not stored in the output, it
-// is passed to the generator function however which can do with it as it sees fit.
-//
-template <class T>
-struct parameter_info
-{
- parameter_type type;
- T z1, z2;
- int n1, n2;
-};
-
-template <class T>
-inline parameter_info<T> make_random_param(T start_range, T end_range, int n_points)
-{
- parameter_info<T> result = { random_in_range, start_range, end_range, n_points, 0 };
- return result;
-}
-
-template <class T>
-inline parameter_info<T> make_periodic_param(T start_range, T end_range, int n_points)
-{
- parameter_info<T> result = { periodic_in_range, start_range, end_range, n_points, 0 };
- return result;
-}
-
-template <class T>
-inline parameter_info<T> make_power_param(T basis, int start_exponent, int end_exponent)
-{
- parameter_info<T> result = { power_series, basis, 0, start_exponent, end_exponent };
- return result;
-}
-
-namespace detail{
-
-template <class Seq, class Item, int N>
-inline void unpack_and_append_tuple(Seq& s,
- const Item& data,
- const boost::integral_constant<int, N>&,
- const boost::false_type&)
-{
- // termimation condition nothing to do here
-}
-
-template <class Seq, class Item, int N>
-inline void unpack_and_append_tuple(Seq& s,
- const Item& data,
- const boost::integral_constant<int, N>&,
- const boost::true_type&)
-{
- // extract the N'th element, append, and recurse:
- typedef typename Seq::value_type value_type;
- value_type val = boost::math::get<N>(data);
- s.push_back(val);
-
- typedef boost::integral_constant<int, N+1> next_value;
- typedef boost::integral_constant<bool, (boost::math::tuple_size<Item>::value > N+1)> terminate;
-
- unpack_and_append_tuple(s, data, next_value(), terminate());
-}
-
-template <class Seq, class Item>
-inline void unpack_and_append(Seq& s, const Item& data, const boost::true_type&)
-{
- s.push_back(data);
-}
-
-template <class Seq, class Item>
-inline void unpack_and_append(Seq& s, const Item& data, const boost::false_type&)
-{
- // Item had better be a tuple-like type or we've had it!!!!
- typedef boost::integral_constant<int, 0> next_value;
- typedef boost::integral_constant<bool, (boost::math::tuple_size<Item>::value > 0)> terminate;
-
- unpack_and_append_tuple(s, data, next_value(), terminate());
-}
-
-template <class Seq, class Item>
-inline void unpack_and_append(Seq& s, const Item& data)
-{
- typedef typename Seq::value_type value_type;
- unpack_and_append(s, data, ::boost::is_convertible<Item, value_type>());
-}
-
-} // detail
-
-template <class T>
-class test_data
-{
-public:
- typedef std::vector<T> row_type;
- typedef row_type value_type;
-private:
- typedef std::set<row_type> container_type;
-public:
- typedef typename container_type::reference reference;
- typedef typename container_type::const_reference const_reference;
- typedef typename container_type::iterator iterator;
- typedef typename container_type::const_iterator const_iterator;
- typedef typename container_type::difference_type difference_type;
- typedef typename container_type::size_type size_type;
-
- // creation:
- test_data(){}
- template <class F>
- test_data(F func, const parameter_info<T>& arg1)
- {
- insert(func, arg1);
- }
-
- // insertion:
- template <class F>
- test_data& insert(F func, const parameter_info<T>& arg1)
- {
- // generate data for single argument functor F
-
- typedef typename std::set<T>::const_iterator it_type;
-
- std::set<T> points;
- create_test_points(points, arg1);
- it_type a = points.begin();
- it_type b = points.end();
- row_type row;
- while(a != b)
- {
- if((arg1.type & dummy_param) == 0)
- row.push_back(*a);
- try{
- // domain_error exceptions from func are swallowed
- // and this data point is ignored:
- boost::math::tools::detail::unpack_and_append(row, func(*a));
- m_data.insert(row);
- }
- catch(const std::domain_error&){}
- row.clear();
- ++a;
- }
- return *this;
- }
-
- template <class F>
- test_data& insert(F func, const parameter_info<T>& arg1, const parameter_info<T>& arg2)
- {
- // generate data for 2-argument functor F
-
- typedef typename std::set<T>::const_iterator it_type;
-
- std::set<T> points1, points2;
- create_test_points(points1, arg1);
- create_test_points(points2, arg2);
- it_type a = points1.begin();
- it_type b = points1.end();
- row_type row;
- while(a != b)
- {
- it_type c = points2.begin();
- it_type d = points2.end();
- while(c != d)
- {
- if((arg1.type & dummy_param) == 0)
- row.push_back(*a);
- if((arg2.type & dummy_param) == 0)
- row.push_back(*c);
- try{
- // domain_error exceptions from func are swallowed
- // and this data point is ignored:
- detail::unpack_and_append(row, func(*a, *c));
- m_data.insert(row);
- }
- catch(const std::domain_error&){}
- row.clear();
- ++c;
- }
- ++a;
- }
- return *this;
- }
-
- template <class F>
- test_data& insert(F func, const parameter_info<T>& arg1, const parameter_info<T>& arg2, const parameter_info<T>& arg3)
- {
- // generate data for 3-argument functor F
-
- typedef typename std::set<T>::const_iterator it_type;
-
- std::set<T> points1, points2, points3;
- create_test_points(points1, arg1);
- create_test_points(points2, arg2);
- create_test_points(points3, arg3);
- it_type a = points1.begin();
- it_type b = points1.end();
- row_type row;
- while(a != b)
- {
- it_type c = points2.begin();
- it_type d = points2.end();
- while(c != d)
- {
- it_type e = points3.begin();
- it_type f = points3.end();
- while(e != f)
- {
- if((arg1.type & dummy_param) == 0)
- row.push_back(*a);
- if((arg2.type & dummy_param) == 0)
- row.push_back(*c);
- if((arg3.type & dummy_param) == 0)
- row.push_back(*e);
- try{
- // domain_error exceptions from func are swallowed
- // and this data point is ignored:
- detail::unpack_and_append(row, func(*a, *c, *e));
- m_data.insert(row);
- }
- catch(const std::domain_error&){}
- row.clear();
- ++e;
- }
- ++c;
- }
- ++a;
- }
- return *this;
- }
-
- void clear(){ m_data.clear(); }
-
- // access:
- iterator begin() { return m_data.begin(); }
- iterator end() { return m_data.end(); }
- const_iterator begin()const { return m_data.begin(); }
- const_iterator end()const { return m_data.end(); }
- bool operator==(const test_data& d)const{ return m_data == d.m_data; }
- bool operator!=(const test_data& d)const{ return m_data != d.m_data; }
- void swap(test_data& other){ m_data.swap(other.m_data); }
- size_type size()const{ return m_data.size(); }
- size_type max_size()const{ return m_data.max_size(); }
- bool empty()const{ return m_data.empty(); }
-
- bool operator < (const test_data& dat)const{ return m_data < dat.m_data; }
- bool operator <= (const test_data& dat)const{ return m_data <= dat.m_data; }
- bool operator > (const test_data& dat)const{ return m_data > dat.m_data; }
- bool operator >= (const test_data& dat)const{ return m_data >= dat.m_data; }
-
-private:
- void create_test_points(std::set<T>& points, const parameter_info<T>& arg1);
- std::set<row_type> m_data;
-
- static float extern_val;
- static float truncate_to_float(float const * pf);
- static float truncate_to_float(float c){ return truncate_to_float(&c); }
-};
-
-//
-// This code exists to bemuse the compiler's optimizer and force a
-// truncation to float-precision only:
-//
-template <class T>
-inline float test_data<T>::truncate_to_float(float const * pf)
-{
- BOOST_MATH_STD_USING
- int expon;
- float f = floor(ldexp(frexp(*pf, &expon), 22));
- f = ldexp(f, expon - 22);
- return f;
-
- //extern_val = *pf;
- //return *pf;
-}
-
-template <class T>
-float test_data<T>::extern_val = 0;
-
-template <class T>
-void test_data<T>::create_test_points(std::set<T>& points, const parameter_info<T>& arg1)
-{
- BOOST_MATH_STD_USING
- //
- // Generate a set of test points as requested, try and generate points
- // at only float precision: otherwise when testing float versions of functions
- // there will be a rounding error in our input values which throws off the results
- // (Garbage in garbage out etc).
- //
- switch(arg1.type & 0x7F)
- {
- case random_in_range:
- {
- BOOST_ASSERT(arg1.z1 < arg1.z2);
- BOOST_ASSERT(arg1.n1 > 0);
- typedef float random_type;
-
- std::tr1::mt19937 rnd;
- std::tr1::uniform_real<random_type> ur_a(real_cast<random_type>(arg1.z1), real_cast<random_type>(arg1.z2));
- std::tr1::variate_generator<std::tr1::mt19937, std::tr1::uniform_real<random_type> > gen(rnd, ur_a);
-
- for(int i = 0; i < arg1.n1; ++i)
- {
- random_type r = gen();
- points.insert(truncate_to_float(r));
- }
- }
- break;
- case periodic_in_range:
- {
- BOOST_ASSERT(arg1.z1 < arg1.z2);
- BOOST_ASSERT(arg1.n1 > 0);
- float interval = real_cast<float>((arg1.z2 - arg1.z1) / arg1.n1);
- T val = arg1.z1;
- while(val < arg1.z2)
- {
- points.insert(truncate_to_float(real_cast<float>(val)));
- val += interval;
- }
- }
- break;
- case power_series:
- {
- BOOST_ASSERT(arg1.n1 < arg1.n2);
-
- typedef float random_type;
- typedef typename boost::mpl::if_<
- ::boost::is_floating_point<T>,
- T, long double>::type power_type;
-
- std::tr1::mt19937 rnd;
- std::tr1::uniform_real<random_type> ur_a(1.0, 2.0);
- std::tr1::variate_generator<std::tr1::mt19937, std::tr1::uniform_real<random_type> > gen(rnd, ur_a);
-
- for(int power = arg1.n1; power <= arg1.n2; ++power)
- {
- random_type r = gen();
- power_type p = ldexp(static_cast<power_type>(r), power);
- points.insert(truncate_to_float(real_cast<float>(arg1.z1 + p)));
- }
- }
- break;
- default:
- BOOST_ASSERT(0 == "Invalid parameter_info object");
- // Assert will fail if get here.
- // Triggers warning 4130) // '==' : logical operation on address of string constant.
- }
-}
-
-//
-// Prompt a user for information on a parameter range:
-//
-template <class T>
-bool get_user_parameter_info(parameter_info<T>& info, const char* param_name)
-{
-#ifdef BOOST_MSVC
-# pragma warning(push)
-# pragma warning(disable: 4127)
-#endif
- std::string line;
- do{
- std::cout << "What kind of distribution do you require for parameter " << param_name << "?\n"
- "Choices are:\n"
- " r Random values in a half open range\n"
- " p Evenly spaced periodic values in a half open range\n"
- " e Exponential power series at a particular point: a + 2^b for some range of b\n"
- "[Default=r]";
-
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
-
- if(line == "r")
- {
- info.type = random_in_range;
- break;
- }
- else if(line == "p")
- {
- info.type = periodic_in_range;
- break;
- }
- else if(line == "e")
- {
- info.type = power_series;
- break;
- }
- else if(line == "")
- {
- info.type = random_in_range;
- break;
- }
- //
- // Ooops, not a valid input....
- //
- std::cout << "Sorry don't recognise \"" << line << "\" as a valid input\n"
- "do you want to try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "n")
- return false;
- else if(line == "y")
- continue;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }while(true);
-
- switch(info.type & ~dummy_param)
- {
- case random_in_range:
- case periodic_in_range:
- // get start and end points of range:
- do{
- std::cout << "Data will be in the half open range a <= x < b,\n"
- "enter value for the start point fo the range [default=0]:";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "")
- {
- info.z1 = 0;
- break;
- }
- try{
- info.z1 = boost::lexical_cast<T>(line);
- break;
- }
- catch(const boost::bad_lexical_cast&)
- {
- std::cout << "Sorry, that was not valid input, try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- }while(true);
- do{
- std::cout << "Enter value for the end point fo the range [default=1]:";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "")
- {
- info.z2 = 1;
- }
- else
- {
- try
- {
- info.z2 = boost::lexical_cast<T>(line);
- }
- catch(const boost::bad_lexical_cast&)
- {
- std::cout << "Sorry, that was not valid input, try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- }
- if(info.z1 >= info.z2)
- {
- std::cout << "The end point of the range was <= the start point\n"
- "try a different value for the endpoint [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- break;
- }while(true);
- do{
- // get the number of points:
- std::cout << "How many data points do you want?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- try{
- info.n1 = boost::lexical_cast<int>(line);
- info.n2 = 0;
- if(info.n1 <= 0)
- {
- std::cout << "The number of points should be > 0\n"
- "try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- break;
- }
- catch(const boost::bad_lexical_cast&)
- {
- std::cout << "Sorry, that was not valid input, try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- }while(true);
- break;
- case power_series:
- // get start and end points of range:
- info.z2 = 0;
- do{
- std::cout << "Data will be in the form a + r*2^b\n"
- "for random value r,\n"
- "enter value for the point a [default=0]:";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "")
- {
- info.z1 = 0;
- break;
- }
- try{
- info.z1 = boost::lexical_cast<T>(line);
- break;
- }
- catch(const boost::bad_lexical_cast&)
- {
- std::cout << "Sorry, that was not valid input, try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- }while(true);
-
- do{
- std::cout << "Data will be in the form a + r*2^b\n"
- "for random value r,\n"
- "enter value for the starting exponent b:";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- try{
- info.n1 = boost::lexical_cast<int>(line);
- break;
- }
- catch(const boost::bad_lexical_cast&)
- {
- std::cout << "Sorry, that was not valid input, try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- }while(true);
-
- do{
- std::cout << "Data will be in the form a + r*2^b\n"
- "for random value r,\n"
- "enter value for the ending exponent b:";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- try{
- info.n2 = boost::lexical_cast<int>(line);
- break;
- }
- catch(const boost::bad_lexical_cast&)
- {
- std::cout << "Sorry, that was not valid input, try again [y/n]?";
- std::getline(std::cin, line);
- boost::algorithm::trim(line);
- if(line == "y")
- continue;
- if(line == "n")
- return false;
- std::cout << "Sorry don't recognise that either, giving up...\n\n";
- return false;
- }
- }while(true);
-
- break;
- default:
- BOOST_ASSERT(0); // should never get here!!
- }
-
- return true;
-#ifdef BOOST_MSVC
-# pragma warning(pop)
-#endif
-}
-
-template <class charT, class traits, class T>
-inline std::basic_ostream<charT, traits>& write_csv(std::basic_ostream<charT, traits>& os,
- const test_data<T>& data)
-{
- const charT defarg[] = { ',', ' ', '\0' };
- return write_csv(os, data, defarg);
-}
-
-template <class charT, class traits, class T>
-std::basic_ostream<charT, traits>& write_csv(std::basic_ostream<charT, traits>& os,
- const test_data<T>& data,
- const charT* separator)
-{
- typedef typename test_data<T>::const_iterator it_type;
- typedef typename test_data<T>::value_type value_type;
- typedef typename value_type::const_iterator value_type_iterator;
- it_type a, b;
- a = data.begin();
- b = data.end();
- while(a != b)
- {
- value_type_iterator x, y;
- bool sep = false;
- x = a->begin();
- y = a->end();
- while(x != y)
- {
- if(sep)
- os << separator;
- os << *x;
- sep = true;
- ++x;
- }
- os << std::endl;
- ++a;
- }
- return os;
-}
-
-template <class T>
-std::ostream& write_code(std::ostream& os,
- const test_data<T>& data,
- const char* name)
-{
- typedef typename test_data<T>::const_iterator it_type;
- typedef typename test_data<T>::value_type value_type;
- typedef typename value_type::const_iterator value_type_iterator;
-
- BOOST_ASSERT(os.good());
-
- it_type a, b;
- a = data.begin();
- b = data.end();
- if(a == b)
- return os;
-
- os << "#ifndef SC_\n# define SC_(x) static_cast<T>(BOOST_JOIN(x, L))\n#endif\n"
- " static const boost::array<boost::array<T, "
- << a->size() << ">, " << data.size() << "> " << name << " = {{\n";
-
- while(a != b)
- {
- if(a != data.begin())
- os << ", \n";
-
- value_type_iterator x, y;
- x = a->begin();
- y = a->end();
- os << " { ";
- while(x != y)
- {
- if(x != a->begin())
- os << ", ";
- os << "SC_(" << *x << ")";
- ++x;
- }
- os << " }";
- ++a;
- }
- os << "\n }};\n//#undef SC_\n\n";
- return os;
-}
-
-} // namespace tools
-} // namespace math
-} // namespace boost
-
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
-
-
-#endif // BOOST_MATH_TOOLS_TEST_DATA_HPP
-
-