pops-core  0.9
PoPS (Pest or Pathogen Spread) Model Core C++ library
normal_kernel.hpp
Go to the documentation of this file.
1 /*
2  * PoPS model - normal dispersal kernel
3  *
4  * Copyright (C) 2015-2020 by the authors.
5  *
6  * Authors: Margaret Lawrimore malawrim ncsu edu
7  *
8  * The code contained herein is licensed under the GNU General Public
9  * License. You may obtain a copy of the GNU General Public License
10  * Version 2 or later at the following locations:
11  *
12  * http://www.opensource.org/licenses/gpl-license.html
13  * http://www.gnu.org/copyleft/gpl.html
14  */
15 
16 #ifndef POPS_NORMAL_KERNEL_HPP
17 #define POPS_NORMAL_KERNEL_HPP
18 
19 #include "kernel_types.hpp"
20 #include "raster.hpp"
21 
22 #include <random>
23 
24 namespace pops {
25 
26 using std::pow;
27 using std::exp;
28 using std::log;
29 using std::sqrt;
30 
35 {
36 protected:
37  double sigma;
38  std::normal_distribution<double> normal_distribution;
39 
40 public:
42  {
43  if (sigma == 0) {
44  throw std::invalid_argument("sigma cannot be zero");
45  }
46  }
47 
54  template<class Generator>
55  double random(Generator& generator)
56  {
57  return std::abs(normal_distribution(generator));
58  }
59 
66  double pdf(double x)
67  {
68  if (sigma == 1) {
69  return 1.0 / (sqrt(2 * M_PI)) * exp(-0.5 * pow(x, 2));
70  }
71  return 1.0 / (sigma * sqrt(2 * M_PI)) * exp(-0.5 * pow(x / sigma, 2));
72  }
73 
82  double icdf(double x)
83  {
84  if (x <= 0 || x >= 1) {
85  throw std::invalid_argument("icdf: x must be between 0.0 and 1.0");
86  }
87  // approximation for inverse error function
88  double y = (2 * x) - 1;
89  float sign = (y < 0) ? -1.0f : 1.0f;
90  double a = 0.140012;
91  double t = 2.0 / (M_PI * a);
92  double l = log(1 - pow(y, 2));
93  double inverf =
94  sign * sqrt(sqrt(pow(t + (l / 2.0), 2) - (l / a)) - (t + (l / 2.0)));
95  return sigma * std::sqrt(2) * inverf;
96  }
97 };
98 
99 } // namespace pops
100 
101 #endif // POPS_NORMAL_KERNEL_HPP
raster.hpp
M_PI
#define M_PI
Definition: utils.hpp:35
pops::NormalKernel::NormalKernel
NormalKernel(double s)
Definition: normal_kernel.hpp:41
pops::NormalKernel::random
double random(Generator &generator)
Returns random value from normal distribution Used by RadialKernel to determine location of spread.
Definition: normal_kernel.hpp:55
pops::NormalKernel::pdf
double pdf(double x)
Normal probability density function Used by DeterministicKernel to determine location of spread.
Definition: normal_kernel.hpp:66
pops::NormalKernel::icdf
double icdf(double x)
Normal inverse cumulative distribution (quantile) function Used by DeterministicKernel to determine m...
Definition: normal_kernel.hpp:82
pops
Definition: cauchy_kernel.hpp:25
pops::NormalKernel::normal_distribution
std::normal_distribution< double > normal_distribution
Definition: normal_kernel.hpp:38
pops::NormalKernel
Dispersal kernel for normal distribution class utilized by RadialKernel and DeterministicKernel.
Definition: normal_kernel.hpp:34
pops::NormalKernel::sigma
double sigma
Definition: normal_kernel.hpp:37
kernel_types.hpp
Kernel types enum and helper functions.