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