21 #ifndef ROCRAND_POISSON_H_ 
   22 #define ROCRAND_POISSON_H_ 
   31 #include "rocrand/rocrand_lfsr113.h" 
   32 #include "rocrand/rocrand_mrg31k3p.h" 
   33 #include "rocrand/rocrand_mrg32k3a.h" 
   34 #include "rocrand/rocrand_mtgp32.h" 
   35 #include "rocrand/rocrand_philox4x32_10.h" 
   36 #include "rocrand/rocrand_scrambled_sobol32.h" 
   37 #include "rocrand/rocrand_scrambled_sobol64.h" 
   38 #include "rocrand/rocrand_sobol32.h" 
   39 #include "rocrand/rocrand_sobol64.h" 
   40 #include "rocrand/rocrand_threefry2x32_20.h" 
   41 #include "rocrand/rocrand_threefry2x64_20.h" 
   42 #include "rocrand/rocrand_threefry4x32_20.h" 
   43 #include "rocrand/rocrand_threefry4x64_20.h" 
   44 #include "rocrand/rocrand_xorwow.h" 
   46 #include "rocrand/rocrand_normal.h" 
   47 #include "rocrand/rocrand_uniform.h" 
   49 namespace rocrand_device {
 
   52 constexpr 
double lambda_threshold_small = 64.0;
 
   53 constexpr 
double lambda_threshold_huge  = 4000.0;
 
   55 template<
class State, 
typename Result_Type = 
unsigned int>
 
   56 __forceinline__ __device__ __host__ Result_Type poisson_distribution_small(State& state,
 
   61     const double limit = exp(-lambda);
 
   70     while (product > limit);
 
   75 __forceinline__ __device__ __host__ 
double lgamma_approx(
const double x)
 
   79     const double z = x - 1.0;
 
   83     const double coefs[n] = {
 
   84         0.99999999999980993227684700473478,
 
   85         676.520368121885098567009190444019,
 
   86         -1259.13921672240287047156078755283,
 
   87         771.3234287776530788486528258894,
 
   88         -176.61502916214059906584551354,
 
   89         12.507343278686904814458936853,
 
   90         -0.13857109526572011689554707,
 
   91         9.984369578019570859563e-6,
 
   92         1.50563273514931155834e-7
 
   96     for (
int i = n - 1; i > 0; i--)
 
   98         sum += coefs[i] / (z + i);
 
  102     const double log_sqrt_2_pi = 0.9189385332046727418;
 
  103     const double e = 2.718281828459045090796;
 
  104     return (log_sqrt_2_pi + log(sum) - g) + (z + 0.5) * log((z + g + 0.5) / e);
 
  107 template<
class State, 
typename Result_Type = 
unsigned int>
 
  108 __forceinline__ __device__ __host__ Result_Type poisson_distribution_large(State& state,
 
  113     const double c = 0.767 - 3.36 / lambda;
 
  114     const double beta = ROCRAND_PI_DOUBLE / sqrt(3.0 * lambda);
 
  115     const double alpha = beta * lambda;
 
  116     const double k = log(c) - lambda - log(beta);
 
  117     const double log_lambda = log(lambda);
 
  122         const double x = (alpha - log((1.0 - u) / u)) / beta;
 
  123         const double n = floor(x + 0.5);
 
  129         const double y = alpha - beta * x;
 
  130         const double t = 1.0 + exp(y);
 
  131         const double lhs = y + log(v / (t * t));
 
  132         const double rhs = k + n * log_lambda - lgamma_approx(n + 1.0);
 
  135             return static_cast<Result_Type
>(n);
 
  140 template<
class State, 
typename Result_Type = 
unsigned int>
 
  141 __forceinline__ __device__ __host__ Result_Type poisson_distribution_huge(State& state,
 
  147     return static_cast<Result_Type
>(round(sqrt(lambda) * n + lambda));
 
  150 template<
class State, 
typename Result_Type = 
unsigned int>
 
  151 __forceinline__ __device__ __host__ Result_Type poisson_distribution(State& state, 
double lambda)
 
  153     if (lambda < lambda_threshold_small)
 
  155         return poisson_distribution_small<State, Result_Type>(state, lambda);
 
  157     else if (lambda <= lambda_threshold_huge)
 
  159         return poisson_distribution_large<State, Result_Type>(state, lambda);
 
  163         return poisson_distribution_huge<State, Result_Type>(state, lambda);
 
  167 template<
class State, 
typename Result_Type = 
unsigned int>
 
  168 __forceinline__ __device__ __host__ Result_Type poisson_distribution_itr(State& state,
 
  184     double upow = pow + 500.0;
 
  185     double ex = exp(-500.0);
 
  190             L = exp((
double)(pow - lambda));
 
  198             x *= ((double)lambda / (
double) k);
 
  201     } 
while((
double)pow < lambda);
 
  205 template<
class State, 
typename Result_Type = 
unsigned int>
 
  206 __forceinline__ __device__ __host__ Result_Type poisson_distribution_inv(State& state,
 
  211         return poisson_distribution_itr<State, Result_Type>(state, lambda);
 
  215         return poisson_distribution_huge<State, Result_Type>(state, lambda);
 
  233 #ifndef ROCRAND_DETAIL_BM_NOT_IN_STATE 
  234 __forceinline__ __device__ __host__ 
unsigned int rocrand_poisson(rocrand_state_philox4x32_10* state,
 
  237     return rocrand_device::detail::poisson_distribution<rocrand_state_philox4x32_10*, unsigned int>(
 
  253 __forceinline__ __device__ __host__ uint4 
rocrand_poisson4(rocrand_state_philox4x32_10* state,
 
  257         rocrand_device::detail::poisson_distribution<rocrand_state_philox4x32_10*, unsigned int>(
 
  260         rocrand_device::detail::poisson_distribution<rocrand_state_philox4x32_10*, unsigned int>(
 
  263         rocrand_device::detail::poisson_distribution<rocrand_state_philox4x32_10*, unsigned int>(
 
  266         rocrand_device::detail::poisson_distribution<rocrand_state_philox4x32_10*, unsigned int>(
 
  283 #ifndef ROCRAND_DETAIL_BM_NOT_IN_STATE 
  284 __forceinline__ __device__ __host__ 
unsigned int rocrand_poisson(rocrand_state_mrg31k3p* state,
 
  287     return rocrand_device::detail::poisson_distribution<rocrand_state_mrg31k3p*, unsigned int>(
 
  304 #ifndef ROCRAND_DETAIL_BM_NOT_IN_STATE 
  305 __forceinline__ __device__ __host__ 
unsigned int rocrand_poisson(rocrand_state_mrg32k3a* state,
 
  308     return rocrand_device::detail::poisson_distribution<rocrand_state_mrg32k3a*, unsigned int>(
 
  325 #ifndef ROCRAND_DETAIL_BM_NOT_IN_STATE 
  326 __forceinline__ __device__ __host__ 
unsigned int rocrand_poisson(rocrand_state_xorwow* state,
 
  329     return rocrand_device::detail::poisson_distribution<rocrand_state_xorwow*, unsigned int>(
 
  346 __forceinline__ __device__ __host__ 
unsigned int rocrand_poisson(rocrand_state_mtgp32* state,
 
  349     return rocrand_device::detail::poisson_distribution_inv<rocrand_state_mtgp32*, unsigned int>(
 
  365 __forceinline__ __device__ __host__ 
unsigned int rocrand_poisson(rocrand_state_sobol32* state,
 
  368     return rocrand_device::detail::poisson_distribution_inv<rocrand_state_sobol32*, unsigned int>(
 
  384 __forceinline__ __device__ __host__ 
unsigned int 
  387     return rocrand_device::detail::poisson_distribution_inv<rocrand_state_scrambled_sobol32*,
 
  388                                                             unsigned int>(state, lambda);
 
  402 __forceinline__ __device__ __host__ 
unsigned long long int 
  405     return rocrand_device::detail::poisson_distribution_inv<rocrand_state_sobol64*,
 
  406                                                             unsigned long long int>(state, lambda);
 
  420 __forceinline__ __device__ __host__ 
unsigned long long int 
  423     return rocrand_device::detail::poisson_distribution_inv<rocrand_state_scrambled_sobol64*,
 
  424                                                             unsigned long long int>(state, lambda);
 
  438 __forceinline__ __device__ __host__ 
unsigned int rocrand_poisson(rocrand_state_lfsr113* state,
 
  441     return rocrand_device::detail::poisson_distribution_inv<rocrand_state_lfsr113*, unsigned int>(
 
  457 __forceinline__ __device__ __host__ 
unsigned int 
  460     return rocrand_device::detail::poisson_distribution_inv(state, lambda);
 
  474 __forceinline__ __device__ __host__ 
unsigned int 
  477     return rocrand_device::detail::poisson_distribution_inv(state, lambda);
 
  491 __forceinline__ __device__ __host__ 
unsigned int 
  494     return rocrand_device::detail::poisson_distribution_inv(state, lambda);
 
  508 __forceinline__ __device__ __host__ 
unsigned int 
  511     return rocrand_device::detail::poisson_distribution_inv(state, lambda);
 
__forceinline__ __device__ __host__ unsigned int rocrand_poisson(rocrand_state_philox4x32_10 *state, double lambda)
Returns a Poisson-distributed unsigned int using Philox generator.
Definition: rocrand_poisson.h:234
 
__forceinline__ __device__ __host__ uint4 rocrand_poisson4(rocrand_state_philox4x32_10 *state, double lambda)
Returns four Poisson-distributed unsigned int values using Philox generator.
Definition: rocrand_poisson.h:253
 
__forceinline__ __device__ __host__ double rocrand_uniform_double(rocrand_state_philox4x32_10 *state)
Returns a uniformly distributed random double value from (0; 1] range.
Definition: rocrand_uniform.h:294
 
__forceinline__ __device__ __host__ double rocrand_normal_double(rocrand_state_philox4x32_10 *state)
Returns a normally distributed double value.
Definition: rocrand_normal.h:438