pops-core  0.9
PoPS (Pest or Pathogen Spread) Model Core C++ library
von_mises_distribution.hpp
Go to the documentation of this file.
1 /*
2  * PoPS model - radial disperal kernel
3  *
4  * Copyright (C) 2015-2020 by the authors.
5  *
6  * Authors: Vaclav Petras (wenzeslaus gmail com)
7  * Chris Jones (cjones1688 gmail com)
8  * Anna Petrasova (kratochanna gmail com)
9  * Zexi Chen (zchen22 ncsu edu)
10  *
11  * The code contained herein is licensed under the GNU General Public
12  * License. You may obtain a copy of the GNU General Public License
13  * Version 2 or later at the following locations:
14  *
15  * http://www.opensource.org/licenses/gpl-license.html
16  * http://www.gnu.org/copyleft/gpl.html
17  */
18 
19 #ifndef POPS_VON_MISES_DISTRIBUTION_HPP
20 #define POPS_VON_MISES_DISTRIBUTION_HPP
21 
22 #include "utils.hpp"
23 
24 #include <cmath>
25 #include <random>
26 
27 namespace pops {
28 
29 // we need to bring sqrt to the namespace
30 // otherwise only candidates are raster-related
31 using std::sqrt;
32 
41 {
42 public:
43  VonMisesDistribution(double mu, double kappa)
44  : mu(mu), kappa(kappa), distribution(0.0, 1.0)
45  {}
46  template<class Generator>
47  double operator()(Generator& generator)
48  {
49  double a, b, c, f, r, theta, u1, u2, u3, z;
50 
51  if (kappa <= 1.e-06)
52  return 2 * PI * distribution(generator);
53 
54  a = 1.0 + sqrt(1.0 + 4.0 * kappa * kappa);
55  b = (a - sqrt(2.0 * a)) / (2.0 * kappa);
56  r = (1.0 + b * b) / (2.0 * b);
57 
58  while (true) {
59  u1 = distribution(generator);
60  z = cos(PI * u1);
61  f = (1.0 + r * z) / (r + z);
62  c = kappa * (r - f);
63  u2 = distribution(generator);
64  if (u2 <= c * (2.0 - c) || u2 < c * exp(1.0 - c))
65  break;
66  }
67 
68  u3 = distribution(generator);
69  if (u3 > 0.5) {
70  theta = fmod(mu + acos(f), 2 * PI);
71  }
72  else {
73  theta = fmod(mu - acos(f), 2 * PI);
74  }
75  return theta;
76  }
77 
78 private:
79  double mu;
80  double kappa;
81  std::uniform_real_distribution<double> distribution;
82 };
83 
84 } // namespace pops
85 
86 #endif // POPS_RADIAL_KERNEL_HPP
pops::VonMisesDistribution::VonMisesDistribution
VonMisesDistribution(double mu, double kappa)
Definition: von_mises_distribution.hpp:43
utils.hpp
PI
#define PI
Definition: utils.hpp:36
pops::VonMisesDistribution
Von Mises Distribution (Circular data distribution)
Definition: von_mises_distribution.hpp:40
pops
Definition: cauchy_kernel.hpp:25
pops::VonMisesDistribution::operator()
double operator()(Generator &generator)
Definition: von_mises_distribution.hpp:47