test_discrete_distribution.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. #define BOOST_TEST_MODULE TestDiscreteDistribution
  11. #include <boost/test/unit_test.hpp>
  12. #include <vector>
  13. #include <boost/compute/system.hpp>
  14. #include <boost/compute/command_queue.hpp>
  15. #include <boost/compute/algorithm/count_if.hpp>
  16. #include <boost/compute/container/vector.hpp>
  17. #include <boost/compute/random/default_random_engine.hpp>
  18. #include <boost/compute/random/discrete_distribution.hpp>
  19. #include <boost/compute/lambda.hpp>
  20. #include "context_setup.hpp"
  21. BOOST_AUTO_TEST_CASE(discrete_distribution_doctest)
  22. {
  23. using boost::compute::uint_;
  24. using boost::compute::lambda::_1;
  25. boost::compute::vector<uint_> vec(100, context);
  26. //! [generate]
  27. // initialize the default random engine
  28. boost::compute::default_random_engine engine(queue);
  29. // initialize weights
  30. int weights[] = {2, 2};
  31. // setup the discrete distribution to produce integers 0 and 1
  32. // with equal weights
  33. boost::compute::discrete_distribution<uint_> distribution(weights, weights+2);
  34. // generate the random values and store them to 'vec'
  35. distribution.generate(vec.begin(), vec.end(), engine, queue);
  36. // ! [generate]
  37. BOOST_CHECK_EQUAL(
  38. boost::compute::count_if(
  39. vec.begin(), vec.end(), _1 > 1, queue
  40. ),
  41. size_t(0)
  42. );
  43. }
  44. BOOST_AUTO_TEST_CASE(discrete_distribution)
  45. {
  46. using boost::compute::uint_;
  47. using boost::compute::lambda::_1;
  48. size_t size = 100;
  49. boost::compute::vector<uint_> vec(size, context);
  50. // initialize the default random engine
  51. boost::compute::default_random_engine engine(queue);
  52. // initialize weights
  53. int weights[] = {10, 40, 40, 10};
  54. // setup the discrete distribution
  55. boost::compute::discrete_distribution<uint_> distribution(
  56. weights, weights + 4
  57. );
  58. std::vector<double> p = distribution.probabilities();
  59. BOOST_CHECK_CLOSE(p[0], double(0.1), 0.001);
  60. BOOST_CHECK_CLOSE(p[1], double(0.4), 0.001);
  61. BOOST_CHECK_CLOSE(p[2], double(0.4), 0.001);
  62. BOOST_CHECK_CLOSE(p[3], double(0.1), 0.001);
  63. BOOST_CHECK_EQUAL((distribution.min)(), uint_(0));
  64. BOOST_CHECK_EQUAL((distribution.max)(), uint_(3));
  65. // generate the random values and store them to 'vec'
  66. distribution.generate(vec.begin(), vec.end(), engine, queue);
  67. BOOST_CHECK_EQUAL(
  68. boost::compute::count_if(
  69. vec.begin(), vec.end(), _1 < 4, queue
  70. ),
  71. size
  72. );
  73. }
  74. BOOST_AUTO_TEST_CASE(discrete_distribution_default_ctor)
  75. {
  76. using boost::compute::uint_;
  77. using boost::compute::lambda::_1;
  78. size_t size = 100;
  79. boost::compute::vector<uint_> vec(size, context);
  80. // initialize the default random engine
  81. boost::compute::default_random_engine engine(queue);
  82. // call default constructor
  83. boost::compute::discrete_distribution<uint_> distribution;
  84. std::vector<double> p = distribution.probabilities();
  85. BOOST_CHECK_CLOSE(p[0], double(1), 0.001);
  86. // generate the random values and store them to 'vec'
  87. distribution.generate(vec.begin(), vec.end(), engine, queue);
  88. BOOST_CHECK_EQUAL(
  89. boost::compute::count_if(
  90. vec.begin(), vec.end(), _1 == 0, queue
  91. ),
  92. size
  93. );
  94. }
  95. BOOST_AUTO_TEST_CASE(discrete_distribution_one_weight)
  96. {
  97. using boost::compute::uint_;
  98. using boost::compute::lambda::_1;
  99. size_t size = 100;
  100. boost::compute::vector<uint_> vec(size, context);
  101. // initialize the default random engine
  102. boost::compute::default_random_engine engine(queue);
  103. std::vector<int> weights(1, 1);
  104. // call default constructor
  105. boost::compute::discrete_distribution<uint_> distribution(
  106. weights.begin(), weights.end()
  107. );
  108. std::vector<double> p = distribution.probabilities();
  109. BOOST_CHECK_CLOSE(p[0], double(1), 0.001);
  110. BOOST_CHECK_EQUAL((distribution.min)(), uint_(0));
  111. BOOST_CHECK_EQUAL((distribution.max)(), uint_(0));
  112. // generate the random values and store them to 'vec'
  113. distribution.generate(vec.begin(), vec.end(), engine, queue);
  114. BOOST_CHECK_EQUAL(
  115. boost::compute::count_if(
  116. vec.begin(), vec.end(), _1 == 0, queue
  117. ),
  118. size
  119. );
  120. }
  121. BOOST_AUTO_TEST_CASE(discrete_distribution_empty_weights)
  122. {
  123. using boost::compute::uint_;
  124. using boost::compute::lambda::_1;
  125. size_t size = 100;
  126. boost::compute::vector<uint_> vec(size, context);
  127. // initialize the default random engine
  128. boost::compute::default_random_engine engine(queue);
  129. std::vector<int> weights;
  130. // weights.begin() == weights.end()
  131. boost::compute::discrete_distribution<uint_> distribution(
  132. weights.begin(), weights.end()
  133. );
  134. std::vector<double> p = distribution.probabilities();
  135. BOOST_CHECK_CLOSE(p[0], double(1), 0.001);
  136. BOOST_CHECK_EQUAL((distribution.min)(), uint_(0));
  137. BOOST_CHECK_EQUAL((distribution.max)(), uint_(0));
  138. // generate the random values and store them to 'vec'
  139. distribution.generate(vec.begin(), vec.end(), engine, queue);
  140. BOOST_CHECK_EQUAL(
  141. boost::compute::count_if(
  142. vec.begin(), vec.end(), _1 == 0, queue
  143. ),
  144. size
  145. );
  146. }
  147. BOOST_AUTO_TEST_CASE(discrete_distribution_uchar)
  148. {
  149. using boost::compute::uchar_;
  150. using boost::compute::uint_;
  151. using boost::compute::lambda::_1;
  152. size_t size = 100;
  153. boost::compute::vector<uchar_> uchar_vec(size, context);
  154. boost::compute::vector<uint_> uint_vec(size, context);
  155. // initialize the default random engine
  156. boost::compute::default_random_engine engine(queue);
  157. // initialize weights
  158. std::vector<int> weights(258, 0);
  159. weights[257] = 1;
  160. // setup the discrete distribution
  161. boost::compute::discrete_distribution<uchar_> distribution(
  162. weights.begin(), weights.end()
  163. );
  164. BOOST_CHECK_EQUAL((distribution.min)(), uchar_(0));
  165. BOOST_CHECK_EQUAL((distribution.max)(), uchar_(255));
  166. // generate the random uchar_ values to the uchar_ vector
  167. distribution.generate(uchar_vec.begin(), uchar_vec.end(), engine, queue);
  168. BOOST_CHECK_EQUAL(
  169. boost::compute::count_if(
  170. uchar_vec.begin(), uchar_vec.end(), _1 == uchar_(1), queue
  171. ),
  172. size
  173. );
  174. // generate the random uchar_ values to the uint_ vector
  175. distribution.generate(uint_vec.begin(), uint_vec.end(), engine, queue);
  176. BOOST_CHECK_EQUAL(
  177. boost::compute::count_if(
  178. uint_vec.begin(), uint_vec.end(), _1 == uint_(1), queue
  179. ),
  180. size
  181. );
  182. }
  183. BOOST_AUTO_TEST_SUITE_END()