#ifndef BOOST_COMPUTE_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#define BOOST_COMPUTE_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#include <boost/assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/function.hpp>
#include <boost/compute/types/fundamental.hpp>
#include <boost/compute/detail/iterator_range_size.hpp>
#include <boost/compute/detail/literal.hpp>
namespace boost {
namespace compute {
template<class RealType = float>
class bernoulli_distribution
{
public:
bernoulli_distribution(RealType p = 0.5f)
: m_p(p)
{
}
~bernoulli_distribution()
{
}
RealType p() const
{
return m_p;
}
template<class OutputIterator, class Generator>
void generate(OutputIterator first,
OutputIterator last,
Generator &generator,
command_queue &queue)
{
size_t count = detail::iterator_range_size(first, last);
vector<uint_> tmp(count, queue.get_context());
generator.generate(tmp.begin(), tmp.end(), queue);
BOOST_COMPUTE_FUNCTION(bool, scale_random, (const uint_ x),
{
return (convert_RealType(x) / MAX_RANDOM) < PARAM;
});
scale_random.define("PARAM", detail::make_literal(m_p));
scale_random.define("MAX_RANDOM", "UINT_MAX");
scale_random.define(
"convert_RealType", std::string("convert_") + type_name<RealType>()
);
transform(
tmp.begin(), tmp.end(), first, scale_random, queue
);
}
private:
RealType m_p;
BOOST_STATIC_ASSERT_MSG(
boost::is_floating_point<RealType>::value,
"Template argument must be a floating point type"
);
};
} }
#endif