1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2014 Roshan <thisisroshansmail@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10
11 #define BOOST_TEST_MODULE TestDiscreteDistribution
12 #include <boost/test/unit_test.hpp>
13
14 #include <vector>
15
16 #include <boost/compute/system.hpp>
17 #include <boost/compute/command_queue.hpp>
18 #include <boost/compute/algorithm/count_if.hpp>
19 #include <boost/compute/container/vector.hpp>
20 #include <boost/compute/random/default_random_engine.hpp>
21 #include <boost/compute/random/discrete_distribution.hpp>
22 #include <boost/compute/lambda.hpp>
23
24 #include "context_setup.hpp"
25
BOOST_AUTO_TEST_CASE(discrete_distribution_doctest)26 BOOST_AUTO_TEST_CASE(discrete_distribution_doctest)
27 {
28 using boost::compute::uint_;
29 using boost::compute::lambda::_1;
30
31 boost::compute::vector<uint_> vec(100, context);
32
33 //! [generate]
34 // initialize the default random engine
35 boost::compute::default_random_engine engine(queue);
36
37 // initialize weights
38 int weights[] = {2, 2};
39
40 // setup the discrete distribution to produce integers 0 and 1
41 // with equal weights
42 boost::compute::discrete_distribution<uint_> distribution(weights, weights+2);
43
44 // generate the random values and store them to 'vec'
45 distribution.generate(vec.begin(), vec.end(), engine, queue);
46 // ! [generate]
47
48 BOOST_CHECK_EQUAL(
49 boost::compute::count_if(
50 vec.begin(), vec.end(), _1 > 1, queue
51 ),
52 size_t(0)
53 );
54 }
55
BOOST_AUTO_TEST_CASE(discrete_distribution)56 BOOST_AUTO_TEST_CASE(discrete_distribution)
57 {
58 using boost::compute::uint_;
59 using boost::compute::lambda::_1;
60
61 size_t size = 100;
62 boost::compute::vector<uint_> vec(size, context);
63
64 // initialize the default random engine
65 boost::compute::default_random_engine engine(queue);
66
67 // initialize weights
68 int weights[] = {10, 40, 40, 10};
69
70 // setup the discrete distribution
71 boost::compute::discrete_distribution<uint_> distribution(
72 weights, weights + 4
73 );
74
75 std::vector<double> p = distribution.probabilities();
76 BOOST_CHECK_CLOSE(p[0], double(0.1), 0.001);
77 BOOST_CHECK_CLOSE(p[1], double(0.4), 0.001);
78 BOOST_CHECK_CLOSE(p[2], double(0.4), 0.001);
79 BOOST_CHECK_CLOSE(p[3], double(0.1), 0.001);
80
81 BOOST_CHECK_EQUAL((distribution.min)(), uint_(0));
82 BOOST_CHECK_EQUAL((distribution.max)(), uint_(3));
83
84 // generate the random values and store them to 'vec'
85 distribution.generate(vec.begin(), vec.end(), engine, queue);
86
87 BOOST_CHECK_EQUAL(
88 boost::compute::count_if(
89 vec.begin(), vec.end(), _1 < 4, queue
90 ),
91 size
92 );
93 }
94
BOOST_AUTO_TEST_CASE(discrete_distribution_default_ctor)95 BOOST_AUTO_TEST_CASE(discrete_distribution_default_ctor)
96 {
97 using boost::compute::uint_;
98 using boost::compute::lambda::_1;
99
100 size_t size = 100;
101 boost::compute::vector<uint_> vec(size, context);
102
103 // initialize the default random engine
104 boost::compute::default_random_engine engine(queue);
105
106 // call default constructor
107 boost::compute::discrete_distribution<uint_> distribution;
108
109 std::vector<double> p = distribution.probabilities();
110 BOOST_CHECK_CLOSE(p[0], double(1), 0.001);
111
112 // generate the random values and store them to 'vec'
113 distribution.generate(vec.begin(), vec.end(), engine, queue);
114
115 BOOST_CHECK_EQUAL(
116 boost::compute::count_if(
117 vec.begin(), vec.end(), _1 == 0, queue
118 ),
119 size
120 );
121 }
122
BOOST_AUTO_TEST_CASE(discrete_distribution_one_weight)123 BOOST_AUTO_TEST_CASE(discrete_distribution_one_weight)
124 {
125 using boost::compute::uint_;
126 using boost::compute::lambda::_1;
127
128 size_t size = 100;
129 boost::compute::vector<uint_> vec(size, context);
130
131 // initialize the default random engine
132 boost::compute::default_random_engine engine(queue);
133
134 std::vector<int> weights(1, 1);
135 // call default constructor
136 boost::compute::discrete_distribution<uint_> distribution(
137 weights.begin(), weights.end()
138 );
139
140 std::vector<double> p = distribution.probabilities();
141 BOOST_CHECK_CLOSE(p[0], double(1), 0.001);
142
143 BOOST_CHECK_EQUAL((distribution.min)(), uint_(0));
144 BOOST_CHECK_EQUAL((distribution.max)(), uint_(0));
145
146 // generate the random values and store them to 'vec'
147 distribution.generate(vec.begin(), vec.end(), engine, queue);
148
149 BOOST_CHECK_EQUAL(
150 boost::compute::count_if(
151 vec.begin(), vec.end(), _1 == 0, queue
152 ),
153 size
154 );
155 }
156
BOOST_AUTO_TEST_CASE(discrete_distribution_empty_weights)157 BOOST_AUTO_TEST_CASE(discrete_distribution_empty_weights)
158 {
159 using boost::compute::uint_;
160 using boost::compute::lambda::_1;
161
162 size_t size = 100;
163 boost::compute::vector<uint_> vec(size, context);
164
165 // initialize the default random engine
166 boost::compute::default_random_engine engine(queue);
167
168 std::vector<int> weights;
169 // weights.begin() == weights.end()
170 boost::compute::discrete_distribution<uint_> distribution(
171 weights.begin(), weights.end()
172 );
173
174 std::vector<double> p = distribution.probabilities();
175 BOOST_CHECK_CLOSE(p[0], double(1), 0.001);
176
177 BOOST_CHECK_EQUAL((distribution.min)(), uint_(0));
178 BOOST_CHECK_EQUAL((distribution.max)(), uint_(0));
179
180 // generate the random values and store them to 'vec'
181 distribution.generate(vec.begin(), vec.end(), engine, queue);
182
183 BOOST_CHECK_EQUAL(
184 boost::compute::count_if(
185 vec.begin(), vec.end(), _1 == 0, queue
186 ),
187 size
188 );
189 }
190
BOOST_AUTO_TEST_CASE(discrete_distribution_uchar)191 BOOST_AUTO_TEST_CASE(discrete_distribution_uchar)
192 {
193 using boost::compute::uchar_;
194 using boost::compute::uint_;
195 using boost::compute::lambda::_1;
196
197 size_t size = 100;
198 boost::compute::vector<uchar_> uchar_vec(size, context);
199 boost::compute::vector<uint_> uint_vec(size, context);
200
201 // initialize the default random engine
202 boost::compute::default_random_engine engine(queue);
203
204 // initialize weights
205 std::vector<int> weights(258, 0);
206 weights[257] = 1;
207
208 // setup the discrete distribution
209 boost::compute::discrete_distribution<uchar_> distribution(
210 weights.begin(), weights.end()
211 );
212
213 BOOST_CHECK_EQUAL((distribution.min)(), uchar_(0));
214 BOOST_CHECK_EQUAL((distribution.max)(), uchar_(255));
215
216 // generate the random uchar_ values to the uchar_ vector
217 distribution.generate(uchar_vec.begin(), uchar_vec.end(), engine, queue);
218
219 BOOST_CHECK_EQUAL(
220 boost::compute::count_if(
221 uchar_vec.begin(), uchar_vec.end(), _1 == uchar_(1), queue
222 ),
223 size
224 );
225
226 // generate the random uchar_ values to the uint_ vector
227 distribution.generate(uint_vec.begin(), uint_vec.end(), engine, queue);
228
229 BOOST_CHECK_EQUAL(
230 boost::compute::count_if(
231 uint_vec.begin(), uint_vec.end(), _1 == uint_(1), queue
232 ),
233 size
234 );
235 }
236
237 BOOST_AUTO_TEST_SUITE_END()
238