123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- #ifndef BOOST_COMPUTE_RANDOM_NORMAL_DISTRIBUTION_HPP
- #define BOOST_COMPUTE_RANDOM_NORMAL_DISTRIBUTION_HPP
- #include <limits>
- #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/type_traits/make_vector_type.hpp>
- namespace boost {
- namespace compute {
- template<class RealType = float>
- class normal_distribution
- {
- public:
- typedef RealType result_type;
-
-
- normal_distribution(RealType mean = 0.f, RealType stddev = 1.f)
- : m_mean(mean),
- m_stddev(stddev)
- {
- }
-
- ~normal_distribution()
- {
- }
-
- result_type mean() const
- {
- return m_mean;
- }
-
- result_type stddev() const
- {
- return m_stddev;
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
- {
- return -std::numeric_limits<RealType>::infinity();
- }
-
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
- {
- return std::numeric_limits<RealType>::infinity();
- }
-
-
- template<class OutputIterator, class Generator>
- void generate(OutputIterator first,
- OutputIterator last,
- Generator &generator,
- command_queue &queue)
- {
- typedef typename make_vector_type<RealType, 2>::type RealType2;
- 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(RealType2, box_muller, (const uint2_ x),
- {
- const RealType one = 1;
- const RealType two = 2;
-
-
-
- const RealType x1 = nextafter(x.x / (RealType) UINT_MAX, (RealType) 0);
- const RealType x2 = x.y / (RealType) UINT_MAX;
- const RealType rho = sqrt(-two * log(one-x1));
- const RealType z1 = rho * cos(two * M_PI_F * x2);
- const RealType z2 = rho * sin(two * M_PI_F * x2);
- return (RealType2)(MEAN, MEAN) + (RealType2)(z1, z2) * (RealType2)(STDDEV, STDDEV);
- });
- box_muller.define("MEAN", boost::lexical_cast<std::string>(m_mean));
- box_muller.define("STDDEV", boost::lexical_cast<std::string>(m_stddev));
- box_muller.define("RealType", type_name<RealType>());
- box_muller.define("RealType2", type_name<RealType2>());
- transform(
- make_buffer_iterator<uint2_>(tmp.get_buffer(), 0),
- make_buffer_iterator<uint2_>(tmp.get_buffer(), count / 2),
- make_buffer_iterator<RealType2>(first.get_buffer(), 0),
- box_muller,
- queue
- );
- }
- private:
- RealType m_mean;
- RealType m_stddev;
- BOOST_STATIC_ASSERT_MSG(
- boost::is_floating_point<RealType>::value,
- "Template argument must be a floating point type"
- );
- };
- }
- }
- #endif
|