• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* test_piecewise_linear_distribution.cpp
2  *
3  * Copyright Steven Watanabe 2011
4  * Distributed under the Boost Software License, Version 1.0. (See
5  * accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  * $Id$
9  *
10  */
11 
12 #include <boost/random/piecewise_linear_distribution.hpp>
13 #include <boost/random/linear_congruential.hpp>
14 #include <boost/assign/list_of.hpp>
15 #include <sstream>
16 #include <vector>
17 #include "concepts.hpp"
18 
19 #define BOOST_TEST_MAIN
20 #include <boost/test/unit_test.hpp>
21 
22 using boost::random::test::RandomNumberDistribution;
23 using boost::random::piecewise_linear_distribution;
24 BOOST_CONCEPT_ASSERT((RandomNumberDistribution< piecewise_linear_distribution<> >));
25 
26 struct gen {
operator ()gen27     double operator()(double arg) {
28         if(arg < 97) return 100;
29         else if(arg < 101) return 3;
30         else if(arg < 105) return 1;
31         else if(arg < 109) return 2;
32         else if(arg < 113) return 1;
33         else if(arg < 117) return 5;
34         else return 100;
35     }
36 };
37 
38 #define CHECK_SEQUENCE(actual, expected)            \
39     do {                                            \
40         std::vector<double> _actual = (actual);     \
41         std::vector<double> _expected = (expected); \
42         BOOST_CHECK_EQUAL_COLLECTIONS(              \
43             _actual.begin(), _actual.end(),         \
44             _expected.begin(), _expected.end());    \
45     } while(false)
46 
47 using boost::assign::list_of;
48 
BOOST_AUTO_TEST_CASE(test_constructors)49 BOOST_AUTO_TEST_CASE(test_constructors) {
50     boost::random::piecewise_linear_distribution<> dist;
51     CHECK_SEQUENCE(dist.intervals(), list_of(0.0)(1.0));
52     CHECK_SEQUENCE(dist.densities(), list_of(1.0)(1.0));
53 
54 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
55     boost::random::piecewise_linear_distribution<> dist_il = {
56         { 99, 103, 107, 111, 115 },
57         gen()
58     };
59     CHECK_SEQUENCE(dist_il.intervals(), list_of(99)(103)(107)(111)(115));
60     CHECK_SEQUENCE(dist_il.densities(),
61         list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
62 
63     boost::random::piecewise_linear_distribution<> dist_il2 = {
64         { 99 },
65         gen()
66     };
67     CHECK_SEQUENCE(dist_il2.intervals(), list_of(0.0)(1.0));
68     CHECK_SEQUENCE(dist_il2.densities(), list_of(1.0)(1.0));
69 #endif
70     std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
71     std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
72     std::vector<double> intervals2 = boost::assign::list_of(99);
73     std::vector<double> weights2 = boost::assign::list_of(2);
74 
75     boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
76     CHECK_SEQUENCE(dist_r.intervals(), list_of(0)(1)(2)(3)(5));
77     CHECK_SEQUENCE(dist_r.densities(), list_of(.375)(.125)(.25)(.125)(.25));
78 
79     boost::random::piecewise_linear_distribution<>
80         dist_r2(intervals2, weights2);
81     CHECK_SEQUENCE(dist_r2.intervals(), list_of(0.0)(1.0));
82     CHECK_SEQUENCE(dist_r2.densities(), list_of(1.0)(1.0));
83 
84     boost::random::piecewise_linear_distribution<> dist_it(
85         intervals.begin(), intervals.end(), weights.begin());
86     CHECK_SEQUENCE(dist_it.intervals(), list_of(0)(1)(2)(3)(5));
87     CHECK_SEQUENCE(dist_it.densities(), list_of(.375)(.125)(.25)(.125)(.25));
88 
89     boost::random::piecewise_linear_distribution<> dist_it2(
90         intervals2.begin(), intervals2.end(), weights2.begin());
91     CHECK_SEQUENCE(dist_it2.intervals(), list_of(0.0)(1.0));
92     CHECK_SEQUENCE(dist_it2.densities(), list_of(1.0)(1.0));
93 
94     boost::random::piecewise_linear_distribution<> dist_fun(4, 99,115, gen());
95     CHECK_SEQUENCE(dist_fun.intervals(), list_of(99)(103)(107)(111)(115));
96     CHECK_SEQUENCE(dist_fun.densities(),
97         list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
98 
99     boost::random::piecewise_linear_distribution<>
100         dist_fun2(1, 99, 115, gen());
101     CHECK_SEQUENCE(dist_fun2.intervals(), list_of(99)(115));
102     CHECK_SEQUENCE(dist_fun2.densities(), list_of(0.046875)(0.078125));
103 
104     boost::random::piecewise_linear_distribution<> copy(dist);
105     BOOST_CHECK_EQUAL(dist, copy);
106     boost::random::piecewise_linear_distribution<> copy_r(dist_r);
107     BOOST_CHECK_EQUAL(dist_r, copy_r);
108 
109     boost::random::piecewise_linear_distribution<> notpow2(3, 99, 111, gen());
110     BOOST_REQUIRE_EQUAL(notpow2.densities().size(), 4u);
111     BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[0], 0.15, 1e-12);
112     BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[1], 0.05, 1e-12);
113     BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[2], 0.1, 1e-12);
114     BOOST_CHECK_CLOSE_FRACTION(notpow2.densities()[3], 0.05, 1e-12);
115     boost::random::piecewise_linear_distribution<> copy_notpow2(notpow2);
116     BOOST_CHECK_EQUAL(notpow2, copy_notpow2);
117 }
118 
BOOST_AUTO_TEST_CASE(test_param)119 BOOST_AUTO_TEST_CASE(test_param) {
120     std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
121     std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
122     std::vector<double> intervals2 = boost::assign::list_of(99);
123     std::vector<double> weights2 = boost::assign::list_of(2);
124     boost::random::piecewise_linear_distribution<> dist(intervals, weights);
125     boost::random::piecewise_linear_distribution<>::param_type
126         param = dist.param();
127     CHECK_SEQUENCE(param.intervals(), list_of(0)(1)(2)(3)(5));
128     CHECK_SEQUENCE(param.densities(), list_of(.375)(.125)(.25)(.125)(.25));
129     boost::random::piecewise_linear_distribution<> copy1(param);
130     BOOST_CHECK_EQUAL(dist, copy1);
131     boost::random::piecewise_linear_distribution<> copy2;
132     copy2.param(param);
133     BOOST_CHECK_EQUAL(dist, copy2);
134 
135     boost::random::piecewise_linear_distribution<>::param_type
136         param_copy = param;
137     BOOST_CHECK_EQUAL(param, param_copy);
138     BOOST_CHECK(param == param_copy);
139     BOOST_CHECK(!(param != param_copy));
140     boost::random::piecewise_linear_distribution<>::param_type param_default;
141     CHECK_SEQUENCE(param_default.intervals(), list_of(0.0)(1.0));
142     CHECK_SEQUENCE(param_default.densities(), list_of(1.0)(1.0));
143     BOOST_CHECK(param != param_default);
144     BOOST_CHECK(!(param == param_default));
145 
146 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
147     boost::random::piecewise_linear_distribution<>::param_type parm_il = {
148         { 99, 103, 107, 111, 115 },
149         gen()
150     };
151     CHECK_SEQUENCE(parm_il.intervals(), list_of(99)(103)(107)(111)(115));
152     CHECK_SEQUENCE(parm_il.densities(),
153         list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
154 
155     boost::random::piecewise_linear_distribution<>::param_type parm_il2 = {
156         { 99 },
157         gen()
158     };
159     CHECK_SEQUENCE(parm_il2.intervals(), list_of(0.0)(1.0));
160     CHECK_SEQUENCE(parm_il2.densities(), list_of(1.0)(1.0));
161 #endif
162 
163     boost::random::piecewise_linear_distribution<>::param_type
164         parm_r(intervals, weights);
165     CHECK_SEQUENCE(parm_r.intervals(), list_of(0)(1)(2)(3)(5));
166     CHECK_SEQUENCE(parm_r.densities(), list_of(.375)(.125)(.25)(.125)(.25));
167 
168     boost::random::piecewise_linear_distribution<>::param_type
169         parm_r2(intervals2, weights2);
170     CHECK_SEQUENCE(parm_r2.intervals(), list_of(0.0)(1.0));
171     CHECK_SEQUENCE(parm_r2.densities(), list_of(1.0)(1.0));
172 
173     boost::random::piecewise_linear_distribution<>::param_type
174         parm_it(intervals.begin(), intervals.end(), weights.begin());
175     CHECK_SEQUENCE(parm_it.intervals(), list_of(0)(1)(2)(3)(5));
176     CHECK_SEQUENCE(parm_it.densities(), list_of(.375)(.125)(.25)(.125)(.25));
177 
178     boost::random::piecewise_linear_distribution<>::param_type
179         parm_it2(intervals2.begin(), intervals2.end(), weights2.begin());
180     CHECK_SEQUENCE(parm_it2.intervals(), list_of(0.0)(1.0));
181     CHECK_SEQUENCE(parm_it2.densities(), list_of(1.0)(1.0));
182 
183     boost::random::piecewise_linear_distribution<>::param_type
184         parm_fun(4, 99, 115, gen());
185     CHECK_SEQUENCE(parm_fun.intervals(), list_of(99)(103)(107)(111)(115));
186     CHECK_SEQUENCE(parm_fun.densities(),
187         list_of(.09375)(.03125)(0.0625)(.03125)(.15625));
188 
189     boost::random::piecewise_linear_distribution<>::param_type
190         parm_fun2(1, 99, 115, gen());
191     CHECK_SEQUENCE(parm_fun2.intervals(), list_of(99)(115));
192     CHECK_SEQUENCE(parm_fun2.densities(), list_of(0.046875)(0.078125));
193 }
194 
BOOST_AUTO_TEST_CASE(test_min_max)195 BOOST_AUTO_TEST_CASE(test_min_max) {
196     std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
197     std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
198     boost::random::piecewise_linear_distribution<> dist;
199     BOOST_CHECK_EQUAL((dist.min)(), 0.0);
200     BOOST_CHECK_EQUAL((dist.max)(), 1.0);
201     boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
202     BOOST_CHECK_EQUAL((dist_r.min)(), 0.0);
203     BOOST_CHECK_EQUAL((dist_r.max)(), 5.0);
204 }
205 
BOOST_AUTO_TEST_CASE(test_comparison)206 BOOST_AUTO_TEST_CASE(test_comparison) {
207     std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
208     std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
209     boost::random::piecewise_linear_distribution<> dist;
210     boost::random::piecewise_linear_distribution<> dist_copy(dist);
211     boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
212     boost::random::piecewise_linear_distribution<> dist_r_copy(dist_r);
213     BOOST_CHECK(dist == dist_copy);
214     BOOST_CHECK(!(dist != dist_copy));
215     BOOST_CHECK(dist_r == dist_r_copy);
216     BOOST_CHECK(!(dist_r != dist_r_copy));
217     BOOST_CHECK(dist != dist_r);
218     BOOST_CHECK(!(dist == dist_r));
219 }
220 
BOOST_AUTO_TEST_CASE(test_streaming)221 BOOST_AUTO_TEST_CASE(test_streaming) {
222     std::vector<double> intervals = boost::assign::list_of(0)(1)(2)(3)(5);
223     std::vector<double> weights = boost::assign::list_of(3)(1)(2)(1)(2);
224     boost::random::piecewise_linear_distribution<> dist(intervals, weights);
225     std::stringstream stream;
226     stream << dist;
227     boost::random::piecewise_linear_distribution<> restored_dist;
228     stream >> restored_dist;
229     BOOST_CHECK_EQUAL(dist, restored_dist);
230 }
231 
BOOST_AUTO_TEST_CASE(test_generation)232 BOOST_AUTO_TEST_CASE(test_generation) {
233     std::vector<double> intervals = boost::assign::list_of(1)(2);
234     std::vector<double> weights = boost::assign::list_of(1)(1);
235     boost::minstd_rand0 gen;
236     boost::random::piecewise_linear_distribution<> dist;
237     boost::random::piecewise_linear_distribution<> dist_r(intervals, weights);
238     for(int i = 0; i < 10; ++i) {
239         double value = dist(gen);
240         BOOST_CHECK_GE(value, 0.0);
241         BOOST_CHECK_LT(value, 1.0);
242         double value_r = dist_r(gen);
243         BOOST_CHECK_GE(value_r, 1.0);
244         BOOST_CHECK_LT(value_r, 2.0);
245         double value_param = dist_r(gen, dist.param());
246         BOOST_CHECK_GE(value_param, 0.0);
247         BOOST_CHECK_LT(value_param, 1.0);
248         double value_r_param = dist(gen, dist_r.param());
249         BOOST_CHECK_GE(value_r_param, 1.0);
250         BOOST_CHECK_LT(value_r_param, 2.0);
251     }
252 }
253