random/normal_distribution.hpp 追加

numeric/iota.hpp 追加
algorithm/shuffle.hpp 追加
This commit is contained in:
bolero-MURAKAMI 2011-10-19 22:47:59 +09:00
parent 8ebe6ea878
commit 44b67d28e2
19 changed files with 570 additions and 18 deletions

View file

@ -25,6 +25,7 @@
#include <sprout/algorithm/fit/reverse_copy.hpp>
#include <sprout/algorithm/fit/rotate.hpp>
#include <sprout/algorithm/fit/rotate_copy.hpp>
#include <sprout/algorithm/fit/shuffle.hpp>
#include <sprout/algorithm/fit/partition.hpp>
#include <sprout/algorithm/fit/partition_copy.hpp>
#include <sprout/algorithm/fit/stable_partition.hpp>

View file

@ -0,0 +1,43 @@
#ifndef SPROUT_ALGORITHM_FIT_SHUFFLE_HPP
#define SPROUT_ALGORITHM_FIT_SHUFFLE_HPP
#include <sprout/config.hpp>
#include <sprout/fixed_container/traits.hpp>
#include <sprout/fixed_container/functions.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/algorithm/fixed/shuffle.hpp>
#include <sprout/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp>
namespace sprout {
namespace fit {
namespace detail {
template<typename Container, typename UniformRandomNumberGenerator>
SPROUT_CONSTEXPR inline typename sprout::fit::result_of::algorithm<Container>::type shuffle_impl(
Container const& cont,
UniformRandomNumberGenerator&& g,
typename sprout::fixed_container_traits<Container>::difference_type offset
)
{
return sprout::sub_copy(
sprout::get_fixed(sprout::fixed::shuffle(cont, sprout::forward<UniformRandomNumberGenerator>(g))),
offset,
offset + sprout::size(cont)
);
}
} // namespace detail
//
// shuffle
//
template<typename Container, typename UniformRandomNumberGenerator>
SPROUT_CONSTEXPR inline typename sprout::fit::result_of::algorithm<Container>::type shuffle(
Container const& cont,
UniformRandomNumberGenerator&& g
)
{
return sprout::fit::detail::shuffle_impl(cont, sprout::forward<UniformRandomNumberGenerator>(g), sprout::fixed_begin_offset(cont));
}
} // namespace fit
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_FIT_SHUFFLE_HPP

View file

@ -25,6 +25,7 @@
#include <sprout/algorithm/fixed/reverse_copy.hpp>
#include <sprout/algorithm/fixed/rotate.hpp>
#include <sprout/algorithm/fixed/rotate_copy.hpp>
#include <sprout/algorithm/fixed/shuffle.hpp>
#include <sprout/algorithm/fixed/partition.hpp>
#include <sprout/algorithm/fixed/partition_copy.hpp>
#include <sprout/algorithm/fixed/stable_partition.hpp>

View file

@ -0,0 +1,118 @@
#ifndef SPROUT_ALGORITHM_FIXED_SHUFFLE_HPP
#define SPROUT_ALGORITHM_FIXED_SHUFFLE_HPP
#include <cstddef>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/array.hpp>
#include <sprout/null_array.hpp>
#include <sprout/fixed_container/traits.hpp>
#include <sprout/fixed_container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/swap_element.hpp>
#include <sprout/numeric/fixed/iota.hpp>
#include <sprout/random/uniform_int_distribution.hpp>
namespace sprout {
namespace fixed {
namespace detail {
template<std::size_t N, typename Random>
SPROUT_CONSTEXPR inline sprout::array<std::ptrdiff_t, N> make_shuffle_indexes_1(
std::ptrdiff_t n,
Random const& rnd,
sprout::array<std::ptrdiff_t, N> const& arr,
std::ptrdiff_t i
)
{
return i < n
? sprout::fixed::detail::make_shuffle_indexes_1(
n,
rnd(),
sprout::fixed::swap_element(arr, arr.begin() + i, arr.begin() + rnd.result()),
i + 1
)
: arr
;
}
template<std::size_t N, typename UniformRandomNumberGenerator>
SPROUT_CONSTEXPR inline sprout::array<std::ptrdiff_t, N> make_shuffle_indexes(
std::ptrdiff_t n,
UniformRandomNumberGenerator&& g
)
{
return n > 0
? sprout::fixed::detail::make_shuffle_indexes_1(
n,
sprout::random::uniform_int_distribution<std::ptrdiff_t>(0, n - 1)(sprout::forward<UniformRandomNumberGenerator>(g)),
sprout::fixed::iota(sprout::null_array<sprout::array<std::ptrdiff_t, N> >(), 0),
0
)
: sprout::array<std::ptrdiff_t, N>{{}}
;
}
template<typename Container, typename Shuffled, std::ptrdiff_t... Indexes>
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type shuffle_impl_1(
Container const& cont,
sprout::index_tuple<Indexes...>,
Shuffled const& shuffled,
typename sprout::fixed_container_traits<Container>::difference_type offset,
typename sprout::fixed_container_traits<Container>::size_type size
)
{
return sprout::remake_clone<Container, Container>(
cont,
sprout::size(cont),
(Indexes >= offset && Indexes < offset + size
? *sprout::next(sprout::begin(cont), shuffled[Indexes - offset])
: *sprout::next(sprout::fixed_begin(cont), Indexes)
)...
);
}
template<typename Container, typename UniformRandomNumberGenerator, std::ptrdiff_t... Indexes>
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type shuffle_impl(
Container const& cont,
sprout::index_tuple<Indexes...> indexes,
UniformRandomNumberGenerator&& g,
typename sprout::fixed_container_traits<Container>::difference_type offset,
typename sprout::fixed_container_traits<Container>::size_type size
)
{
return sprout::fixed::detail::shuffle_impl_1(
cont,
indexes,
sprout::fixed::detail::make_shuffle_indexes<sprout::fixed_container_traits<Container>::fixed_size>(
size,
sprout::forward<UniformRandomNumberGenerator>(g)
),
offset,
size
);
}
} // namespace detail
//
// shuffle
//
template<typename Container, typename UniformRandomNumberGenerator>
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type shuffle(
Container const& cont,
UniformRandomNumberGenerator&& g
)
{
return sprout::fixed::detail::shuffle_impl(
cont,
typename sprout::index_range<0, sprout::fixed_container_traits<Container>::fixed_size>::type(),
sprout::forward<UniformRandomNumberGenerator>(g),
sprout::fixed_begin_offset(cont),
sprout::size(cont)
);
}
} // namespace fixed
using sprout::fixed::shuffle;
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_FIXED_SHUFFLE_HPP

View file

@ -0,0 +1,8 @@
#ifndef SPROUT_ALGORITHM_SHUFFLE_HPP
#define SPROUT_ALGORITHM_SHUFFLE_HPP
#include <sprout/config.hpp>
#include <sprout/algorithm/fixed/shuffle.hpp>
#include <sprout/algorithm/fit/shuffle.hpp>
#endif // #ifndef SPROUT_ALGORITHM_SHUFFLE_HPP

8
sprout/numeric.hpp Normal file
View file

@ -0,0 +1,8 @@
#ifndef SPROUT_NUMERIC_HPP
#define SPROUT_NUMERIC_HPP
#include <sprout/config.hpp>
#include <sprout/numeric/fixed.hpp>
#include <sprout/numeric/fit.hpp>
#endif // #ifndef SPROUT_NUMERIC_HPP

7
sprout/numeric/fit.hpp Normal file
View file

@ -0,0 +1,7 @@
#ifndef SPROUT_NUMERIC_FIT_HPP
#define SPROUT_NUMERIC_FIT_HPP
#include <sprout/config.hpp>
#include <sprout/numeric/fit/iota.hpp>
#endif // #ifndef SPROUT_NUMERIC_FIT_HPP

View file

@ -0,0 +1,42 @@
#ifndef SPROUT_NUMERIC_FIT_IOTA_HPP
#define SPROUT_NUMERIC_FIT_IOTA_HPP
#include <sprout/config.hpp>
#include <sprout/fixed_container/traits.hpp>
#include <sprout/fixed_container/functions.hpp>
#include <sprout/numeric/fixed/iota.hpp>
#include <sprout/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp>
namespace sprout {
namespace fit {
namespace detail {
template<typename Container, typename T>
SPROUT_CONSTEXPR inline typename sprout::fit::result_of::algorithm<Container>::type iota_impl(
Container const& cont,
T const& value,
typename sprout::fixed_container_traits<Container>::difference_type offset
)
{
return sprout::sub_copy(
sprout::get_fixed(sprout::fixed::iota(cont, value)),
offset,
offset + sprout::size(cont)
);
}
} // namespace detail
//
// iota
//
template<typename Container, typename T>
SPROUT_CONSTEXPR inline typename sprout::fit::result_of::algorithm<Container>::type iota(
Container const& cont,
T const& value
)
{
return sprout::fit::detail::iota_impl(cont, value, sprout::fixed_begin_offset(cont));
}
} // namespace fit
} // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FIT_IOTA_HPP

7
sprout/numeric/fixed.hpp Normal file
View file

@ -0,0 +1,7 @@
#ifndef SPROUT_NUMERIC_FIXED_HPP
#define SPROUT_NUMERIC_FIXED_HPP
#include <sprout/config.hpp>
#include <sprout/numeric/fixed/iota.hpp>
#endif // #ifndef SPROUT_NUMERIC_FIXED_HPP

View file

@ -0,0 +1,56 @@
#ifndef SPROUT_NUMERIC_FIXED_IOTA_HPP
#define SPROUT_NUMERIC_FIXED_IOTA_HPP
#include <cstddef>
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/fixed_container/traits.hpp>
#include <sprout/fixed_container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
namespace sprout {
namespace fixed {
namespace detail {
template<typename Container, typename T, std::ptrdiff_t... Indexes>
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type iota_impl(
Container const& cont,
sprout::index_tuple<Indexes...>,
T value,
typename sprout::fixed_container_traits<Container>::difference_type offset,
typename sprout::fixed_container_traits<Container>::size_type size
)
{
return sprout::remake_clone<Container, Container>(
cont,
sprout::size(cont),
(Indexes >= offset && Indexes < offset + size
? value + (Indexes - offset)
: *sprout::next(sprout::fixed_begin(cont), Indexes)
)...
);
}
} // namespace detail
//
// iota
//
template<typename Container, typename T>
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type iota(
Container const& cont,
T value
)
{
return sprout::fixed::detail::iota_impl(
cont,
typename sprout::index_range<0, sprout::fixed_container_traits<Container>::fixed_size>::type(),
value,
sprout::fixed_begin_offset(cont),
sprout::size(cont)
);
}
} // namespace fixed
using sprout::fixed::iota;
} // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FIXED_IOTA_HPP

8
sprout/numeric/iota.hpp Normal file
View file

@ -0,0 +1,8 @@
#ifndef SPROUT_NUMERIC_IOTA_HPP
#define SPROUT_NUMERIC_IOTA_HPP
#include <sprout/config.hpp>
#include <sprout/numeric/fixed/iota.hpp>
#include <sprout/numeric/fit/iota.hpp>
#endif // #ifndef SPROUT_NUMERIC_IOTA_HPP

View file

@ -17,6 +17,7 @@
#include <sprout/random/bernoulli_distribution.hpp>
#include <sprout/random/binomial_distribution.hpp>
#include <sprout/random/geometric_distribution.hpp>
#include <sprout/random/normal_distribution.hpp>
#include <sprout/random/variate_generator.hpp>
#include <sprout/random/random_result.hpp>
#include <sprout/random/random_iterator.hpp>

View file

@ -132,8 +132,9 @@ namespace sprout {
)
{
param_type parm;
return lhs >> parm;
if (lhs >> parm) {
rhs.param(parm);
}
return lhs;
}
template<typename Elem, typename Traits>

View file

@ -415,8 +415,9 @@ namespace sprout {
)
{
param_type parm;
lhs >> parm;
if (lhs >> parm) {
rhs.param(parm);
}
return lhs;
}
template<typename Elem, typename Traits>

View file

@ -157,8 +157,9 @@ namespace sprout {
)
{
param_type parm;
lhs >> parm;
if (lhs >> parm) {
rhs.param(parm);
}
return lhs;
}
template<typename Elem, typename Traits>

View file

@ -0,0 +1,246 @@
#ifndef SPROUT_RANDOM_NORMAL_DISTRIBUTION_HPP
#define SPROUT_RANDOM_NORMAL_DISTRIBUTION_HPP
#include <cmath>
#include <limits>
#include <ios>
#include <istream>
#include <sprout/config.hpp>
#include <sprout/random/uniform_01.hpp>
#include <sprout/random/random_result.hpp>
namespace sprout {
namespace random {
//
// normal_distribution
//
template<typename RealType = double>
class normal_distribution {
public:
typedef RealType input_type;
typedef RealType result_type;
private:
struct private_constructor_tag {};
private:
SPROUT_STATIC_CONSTEXPR result_type pi = result_type(3.14159265358979323846);
private:
static SPROUT_CONSTEXPR bool arg_check_nothrow(RealType mean_arg, RealType sigma_arg) {
return sigma_arg >= RealType(0);
}
static SPROUT_CONSTEXPR RealType arg_check(RealType mean_arg, RealType sigma_arg) {
return arg_check_nothrow(mean_arg, sigma_arg)
? mean_arg
: throw "assert(sigma_arg >= RealType(0))"
;
}
public:
//
// param_type
//
class param_type {
public:
typedef normal_distribution distribution_type;
private:
static SPROUT_CONSTEXPR bool arg_check_nothrow(RealType mean_arg, RealType sigma_arg) {
return distribution_type::arg_check_nothrow(mean_arg, sigma_arg);
}
private:
RealType mean_;
RealType sigma_;
public:
SPROUT_CONSTEXPR param_type()
: mean_(RealType(0.0))
, sigma_(RealType(1.0))
{}
SPROUT_CONSTEXPR explicit param_type(RealType mean_arg, RealType sigma_arg = RealType(1.0))
: mean_(arg_check(mean_arg, sigma_arg))
, sigma_(sigma_arg)
{}
SPROUT_CONSTEXPR RealType mean() const {
return mean_;
}
SPROUT_CONSTEXPR RealType sigma() const {
return sigma_;
}
template<typename Elem, typename Traits>
friend std::basic_istream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs,
param_type& rhs
)
{
RealType mean;
RealType sigma;
if (lhs >> mean >> std::ws >> sigma) {
if (arg_check_nothrow(mean, sigma)) {
rhs.mean_ = mean;
rhs.sigma_ = sigma;
} else {
lhs.setstate(std::ios_base::failbit);
}
}
return lhs;
}
template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs,
param_type const& rhs
)
{
return lhs << rhs.mean_ << " " << rhs.sigma_;
}
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
return lhs.mean_ == rhs.mean_ && lhs.sigma_ == rhs.sigma_;
}
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
return !(lhs == rhs);
}
};
private:
RealType mean_;
RealType sigma_;
RealType r1_;
RealType r2_;
RealType cached_rho_;
bool valid_;
private:
SPROUT_CONSTEXPR normal_distribution(
RealType mean,
RealType sigma,
RealType r1,
RealType r2,
RealType cached_rho,
bool valid,
private_constructor_tag
)
: mean_(mean)
, sigma_(sigma)
, r1_(r1)
, r2_(r2)
, cached_rho_(cached_rho)
, valid_(valid)
{}
template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> generate_2(Engine const& eng, RealType r1, RealType r2, RealType cached_rho, bool valid) const {
using std::sin;
using std::cos;
return sprout::random::random_result<Engine, normal_distribution>(
cached_rho * (valid ? cos(result_type(2) * pi * r1) : sin(result_type(2) * pi * r1)) * sigma_ + mean_,
eng,
normal_distribution(
mean_,
sigma_,
r1,
r2,
cached_rho,
valid,
private_constructor_tag()
)
);
}
template<typename Engine, typename Random>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> generate_1_1(RealType r1, Random const& rnd) const {
using std::sqrt;
using std::log;
return generate_2(rnd.engine(), r1, rnd.result(), sqrt(-result_type(2) * log(result_type(1) - rnd.result())), true);
}
template<typename Engine, typename Random>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> generate_1(Random const& rnd) const {
return generate_1_1<Engine>(rnd.result(), rnd());
}
template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> generate(Engine const& eng) const {
return !valid_
? generate_1<Engine>(sprout::random::uniform_01<RealType>()(eng))
: generate_2(eng, r1_, r2_, cached_rho_, false)
;
}
public:
SPROUT_CONSTEXPR normal_distribution()
: mean_(RealType(0.0))
, sigma_(RealType(1.0))
, r1_(0)
, r2_(0)
, cached_rho_(0)
, valid_(false)
{}
SPROUT_CONSTEXPR explicit normal_distribution(RealType mean_arg, RealType sigma_arg = RealType(1.0))
: mean_(arg_check(mean_arg, sigma_arg))
, sigma_(sigma_arg)
, r1_(0)
, r2_(0)
, cached_rho_(0)
, valid_(false)
{}
SPROUT_CONSTEXPR explicit normal_distribution(param_type const& parm)
: mean_(parm.mean())
, sigma_(parm.sigma())
, r1_(0)
, r2_(0)
, cached_rho_(0)
, valid_(false)
{}
SPROUT_CONSTEXPR result_type mean() const {
return mean_;
}
SPROUT_CONSTEXPR result_type sigma() const {
return sigma_;
}
SPROUT_CONSTEXPR result_type min() const {
return -std::numeric_limits<RealType>::infinity();
}
SPROUT_CONSTEXPR result_type max() const {
return std::numeric_limits<RealType>::infinity();
}
SPROUT_CONSTEXPR param_type param() const {
return param_type(mean_, sigma_);
}
void param(param_type const& parm) {
mean_ = parm.mean();
sigma_ = parm.sigma();
valid_ = false;
}
template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> operator()(Engine const& eng) const {
return generate(eng);
}
template<typename Elem, typename Traits>
friend std::basic_istream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs,
normal_distribution& rhs
)
{
param_type parm;
bool valid;
RealType cached_rho;
RealType r1;
RealType r2;
if (lhs >> parm >> std::ws >> valid >> std::ws >> cached_rho >> std::ws >> r1 >> std::ws >> r2) {
rhs.param(parm);
rhs.valid_ = valid;
rhs.cached_rho_ = cached_rho;
rhs.r1_ = r1;
rhs.r2_ = r2;
}
return lhs;
}
template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs,
normal_distribution const& rhs
)
{
return lhs << rhs.param() << " " << rhs.valid_ << " " << rhs.cached_rho_ << " " << rhs.r1_ << " " << rhs.r2_;
}
SPROUT_CONSTEXPR friend bool operator==(normal_distribution const& lhs, normal_distribution const& rhs) {
return lhs.param() == rhs.param() && lhs.valid_ == rhs.valid_ && lhs.cached_rho_ == rhs.cached_rho_ && lhs.r1_ == rhs.r1_ && lhs.r2_ == rhs.r2_;
}
SPROUT_CONSTEXPR friend bool operator!=(normal_distribution const& lhs, normal_distribution const& rhs) {
return !(lhs == rhs);
}
};
} // namespace random
using sprout::random::normal_distribution;
} // namespace sprout
#endif // #ifndef SPROUT_RANDOM_NORMAL_DISTRIBUTION_HPP

View file

@ -462,8 +462,8 @@ namespace sprout {
}
};
private:
result_type min_;
result_type max_;
IntType min_;
IntType max_;
private:
template<typename Engine, typename Result>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_int_distribution> generate(Result const& rnd) const {
@ -516,8 +516,9 @@ namespace sprout {
)
{
param_type parm;
lhs >> parm;
if (lhs >> parm) {
rhs.param(parm);
}
return lhs;
}
template<typename Elem, typename Traits>

View file

@ -254,8 +254,8 @@ namespace sprout {
}
};
private:
result_type min_;
result_type max_;
RealType min_;
RealType max_;
private:
template<typename Engine, typename Result>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> generate(Result const& rnd) const {
@ -308,8 +308,9 @@ namespace sprout {
)
{
param_type parm;
lhs >> parm;
if (lhs >> parm) {
rhs.param(parm);
}
return lhs;
}
template<typename Elem, typename Traits>

View file

@ -92,8 +92,8 @@ namespace sprout {
}
};
private:
result_type min_;
result_type max_;
IntType min_;
IntType max_;
private:
template<typename Engine, typename RangeType, typename BaseUnsigned>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2(
@ -244,8 +244,9 @@ namespace sprout {
)
{
param_type parm;
lhs >> parm;
if (lhs >> parm) {
rhs.param(parm);
}
return lhs;
}
template<typename Elem, typename Traits>