• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef BOOST_COMPUTE_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
12 #define BOOST_COMPUTE_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
13 
14 #include <limits>
15 
16 #include <boost/type_traits.hpp>
17 #include <boost/static_assert.hpp>
18 
19 #include <boost/compute/command_queue.hpp>
20 #include <boost/compute/container/vector.hpp>
21 #include <boost/compute/function.hpp>
22 #include <boost/compute/types/fundamental.hpp>
23 #include <boost/compute/algorithm/copy_if.hpp>
24 #include <boost/compute/algorithm/transform.hpp>
25 
26 namespace boost {
27 namespace compute {
28 
29 /// \class uniform_int_distribution
30 /// \brief Produces uniformily distributed random integers
31 ///
32 /// The following example shows how to setup a uniform int distribution to
33 /// produce random integers 0 and 1.
34 ///
35 /// \snippet test/test_uniform_int_distribution.cpp generate
36 ///
37 template<class IntType = uint_>
38 class uniform_int_distribution
39 {
40 public:
41     typedef IntType result_type;
42 
43     /// Creates a new uniform distribution producing numbers in the range
44     /// [\p a, \p b].
uniform_int_distribution(IntType a=0,IntType b=(std::numeric_limits<IntType>::max)())45     explicit uniform_int_distribution(IntType a = 0,
46                                       IntType b = (std::numeric_limits<IntType>::max)())
47         : m_a(a),
48           m_b(b)
49     {
50     }
51 
52     /// Destroys the uniform_int_distribution object.
~uniform_int_distribution()53     ~uniform_int_distribution()
54     {
55     }
56 
57     /// Returns the minimum value of the distribution.
a() const58     result_type a() const
59     {
60         return m_a;
61     }
62 
63     /// Returns the maximum value of the distribution.
b() const64     result_type b() const
65     {
66         return m_b;
67     }
68 
69     /// Generates uniformily distributed integers and stores
70     /// them to the range [\p first, \p last).
71     template<class OutputIterator, class Generator>
generate(OutputIterator first,OutputIterator last,Generator & generator,command_queue & queue)72     void generate(OutputIterator first,
73                   OutputIterator last,
74                   Generator &generator,
75                   command_queue &queue)
76     {
77         size_t size = std::distance(first, last);
78         typedef typename Generator::result_type g_result_type;
79 
80         vector<g_result_type> tmp(size, queue.get_context());
81         vector<g_result_type> tmp2(size, queue.get_context());
82 
83         uint_ bound = ((uint_(-1))/(m_b-m_a+1))*(m_b-m_a+1);
84 
85         buffer_iterator<g_result_type> tmp2_iter;
86 
87         while(size>0)
88         {
89             generator.generate(tmp.begin(), tmp.begin() + size, queue);
90             tmp2_iter = copy_if(tmp.begin(), tmp.begin() + size, tmp2.begin(),
91                                 _1 <= bound, queue);
92             size = std::distance(tmp2_iter, tmp2.end());
93         }
94 
95         BOOST_COMPUTE_FUNCTION(IntType, scale_random, (const g_result_type x),
96         {
97             return LO + (x % (HI-LO+1));
98         });
99 
100         scale_random.define("LO", boost::lexical_cast<std::string>(m_a));
101         scale_random.define("HI", boost::lexical_cast<std::string>(m_b));
102 
103         transform(tmp2.begin(), tmp2.end(), first, scale_random, queue);
104     }
105 
106 private:
107     IntType m_a;
108     IntType m_b;
109 
110     BOOST_STATIC_ASSERT_MSG(
111         boost::is_integral<IntType>::value,
112         "Template argument must be integral"
113     );
114 };
115 
116 } // end compute namespace
117 } // end boost namespace
118 
119 #endif // BOOST_COMPUTE_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
120