Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / performance / voronoi_performance.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 //  Copyright 2012 John Maddock. Distributed under the Boost
3 //  Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifdef _MSC_VER
7 #pragma warning(disable : 4244)
8 #endif
9
10 #include <boost/polygon/detail/voronoi_predicates.hpp>
11 #include <boost/polygon/detail/voronoi_structures.hpp>
12 #include <boost/polygon/detail/skeleton_predicates.hpp>
13 #include <boost/random/mersenne_twister.hpp>
14 #include <boost/random/uniform_int_distribution.hpp>
15 #include <vector>
16 #include <map>
17 #include <boost/chrono.hpp>
18 #include <boost/multiprecision/cpp_int.hpp>
19
20 #ifdef TEST_GMP
21 #include <boost/multiprecision/gmp.hpp>
22 #endif
23 #ifdef TEST_TOMMATH
24 #include <boost/multiprecision/tommath.hpp>
25 #endif
26
27 #include "arithmetic_backend.hpp"
28
29 typedef boost::polygon::detail::point_2d<boost::int32_t> i_point;
30
31 template <class Clock>
32 struct stopwatch
33 {
34    typedef typename Clock::duration duration;
35    stopwatch()
36    {
37       m_start = Clock::now();
38    }
39    duration elapsed()
40    {
41       return Clock::now() - m_start;
42    }
43    void reset()
44    {
45       m_start = Clock::now();
46    }
47
48  private:
49    typename Clock::time_point m_start;
50 };
51
52 std::vector<i_point>   points;
53 boost::random::mt19937 gen;
54
55 template <class Big>
56 struct cpp_int_voronoi_traits
57 {
58    typedef boost::int32_t                                          int_type;
59    typedef boost::int64_t                                          int_x2_type;
60    typedef boost::uint64_t                                         uint_x2_type;
61    typedef Big                                                     big_int_type;
62    typedef double                                                  fpt_type;
63    typedef boost::polygon::detail::extended_exponent_fpt<fpt_type> efpt_type;
64    typedef boost::polygon::detail::ulp_comparison<fpt_type>        ulp_cmp_type;
65    struct to_fpt_converter_type
66    {
67       template <class B, boost::multiprecision::expression_template_option ET>
68       double operator()(const boost::multiprecision::number<B, ET>& val)
69       {
70          return val.template convert_to<double>();
71       }
72       double operator()(double val)
73       {
74          return val;
75       }
76       double operator()(const efpt_type& that) const
77       {
78          return that.d();
79       }
80       template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
81       double operator()(const boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
82       {
83          typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type r_t;
84          r_t                                                                                                  r(e);
85          return r.template convert_to<double>();
86       }
87    };
88    struct to_efpt_converter_type
89    {
90       template <class B, boost::multiprecision::expression_template_option ET>
91       efpt_type operator()(const boost::multiprecision::number<B, ET>& val)
92       {
93          return efpt_type(val.template convert_to<double>(), 0);
94       }
95       efpt_type operator()(double val)
96       {
97          return efpt_type(val, 0);
98       }
99       template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
100       double operator()(const boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
101       {
102          typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type r_t;
103          r_t                                                                                                  r(e);
104          return efpt_type(r.template convert_to<double>(), 0);
105       }
106    };
107 };
108
109 template <class Big>
110 struct native_int_voronoi_traits
111 {
112    typedef boost::int32_t                                          int_type;
113    typedef boost::int64_t                                          int_x2_type;
114    typedef boost::uint64_t                                         uint_x2_type;
115    typedef Big                                                     big_int_type;
116    typedef double                                                  fpt_type;
117    typedef boost::polygon::detail::extended_exponent_fpt<fpt_type> efpt_type;
118    typedef boost::polygon::detail::ulp_comparison<fpt_type>        ulp_cmp_type;
119    struct to_fpt_converter_type
120    {
121       template <class T>
122       double operator()(const T& val) const
123       {
124          return val;
125       }
126       double operator()(const efpt_type& that) const
127       {
128          return that.d();
129       }
130    };
131    struct to_efpt_converter_type
132    {
133       template <class T>
134       efpt_type operator()(const T& val) const
135       {
136          return efpt_type(val, 0);
137       }
138    };
139 };
140
141 std::map<std::string, double> results;
142 double                        min_time = (std::numeric_limits<double>::max)();
143
144 template <class Traits>
145 double test(const char* name)
146 {
147    typedef boost::polygon::detail::voronoi_predicates<Traits>                             preds;
148    typedef boost::polygon::detail::circle_event<boost::int32_t>                           circle_event;
149    typedef boost::polygon::detail::site_event<boost::int32_t>                             site_event;
150    typedef typename preds::template mp_circle_formation_functor<site_event, circle_event> circle_pred;
151
152    boost::random::uniform_int_distribution<> dist(0, points.size() - 1);
153    circle_pred                               pc;
154    circle_event                              event;
155
156    stopwatch<boost::chrono::high_resolution_clock> w;
157
158    for (unsigned i = 0; i < 10000; ++i)
159    {
160       site_event s1(points[dist(gen)]);
161       site_event s2(points[dist(gen)]);
162       site_event s3(points[dist(gen)]);
163       pc.ppp(s1, s2, s3, event);
164       pc.pps(s1, s2, s3, 0, event);
165       pc.pss(s1, s2, s3, 0, event);
166       pc.sss(s1, s2, s3, event);
167    }
168    double d = boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
169    if (d < min_time)
170       min_time = d;
171    results[name] = d;
172    std::cout << "Time for " << std::setw(30) << std::left << name << " = " << d << std::endl;
173    return d;
174 }
175
176 void generate_quickbook()
177 {
178    std::cout << "[table\n[[Integer Type][Relative Performance (Actual time in parenthesis)]]\n";
179
180    std::map<std::string, double>::const_iterator i(results.begin()), j(results.end());
181
182    while (i != j)
183    {
184       double rel = i->second / min_time;
185       std::cout << "[[" << i->first << "][" << rel << "(" << i->second << "s)]]\n";
186       ++i;
187    }
188
189    std::cout << "]\n";
190 }
191
192 int main()
193 {
194    boost::random::uniform_int_distribution<> dist((std::numeric_limits<boost::int32_t>::min)() / 2, (std::numeric_limits<boost::int32_t>::max)() / 2);
195
196    for (unsigned i = 0; i < 100; ++i)
197    {
198       points.push_back(i_point(dist(gen), dist(gen)));
199    }
200
201    test<boost::polygon::detail::voronoi_ctype_traits<boost::int32_t> >("extended_int");
202
203    test<cpp_int_voronoi_traits<boost::multiprecision::int256_t> >("int256_t");
204    test<cpp_int_voronoi_traits<boost::multiprecision::int512_t> >("int512_t");
205    test<cpp_int_voronoi_traits<boost::multiprecision::int1024_t> >("int1024_t");
206
207    test<cpp_int_voronoi_traits<boost::multiprecision::checked_int256_t> >("checked_int256_t");
208    test<cpp_int_voronoi_traits<boost::multiprecision::checked_int512_t> >("checked_int512_t");
209    test<cpp_int_voronoi_traits<boost::multiprecision::checked_int1024_t> >("checked_int1024_t");
210
211    test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off> > >("cpp_int");
212
213 #ifdef TEST_GMP
214    test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::gmp_int, boost::multiprecision::et_off> > >("mpz_int");
215 #endif
216 #ifdef TEST_TOMMATH
217    test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::tommath_int, boost::multiprecision::et_off> > >("tom_int");
218 #endif
219
220    generate_quickbook();
221
222    test<native_int_voronoi_traits<boost::int64_t> >("int64_t");
223    test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<boost::int64_t>, boost::multiprecision::et_off> > >("number<arithmetic_backend<boost::int64_t>, et_off>");
224    //test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<boost::int64_t>, boost::multiprecision::et_on> > >("number<arithmetic_backend<boost::int64_t>, et_on>");
225
226    return 0;
227 }