pops-core  0.9
PoPS (Pest or Pathogen Spread) Model Core C++ library
deterministic_kernel.hpp
Go to the documentation of this file.
1 /*
2  * PoPS model - deterministic 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_DETERMINISTIC_KERNEL_HPP
17 #define POPS_DETERMINISTIC_KERNEL_HPP
18 
19 #include <vector>
20 #include <tuple>
21 
22 #include "raster.hpp"
23 #include "kernel_types.hpp"
24 #include "utils.hpp"
26 #include "logistic_kernel.hpp"
28 #include "exponential_kernel.hpp"
29 #include "cauchy_kernel.hpp"
30 #include "gamma_kernel.hpp"
31 #include "lognormal_kernel.hpp"
32 #include "normal_kernel.hpp"
33 #include "weibull_kernel.hpp"
34 #include "power_law_kernel.hpp"
35 
36 namespace pops {
37 
38 using std::pow;
39 using std::tan;
40 using std::exp;
41 using std::log;
42 using std::ceil;
43 using std::abs;
44 using std::sqrt;
45 
58 template<typename IntegerRaster>
60 {
61 protected:
62  const IntegerRaster& dispersers_;
63  // row/col position of middle cell
64  int mid_row = 0;
65  int mid_col = 0;
66  // position of cell from previous call
67  int prev_row = -1;
68  int prev_col = -1;
69  // number of rows/cols in the probability window
70  int number_of_rows = 0;
72  // maximum distance from center cell to outer cells
73  double max_distance{0};
86 
89  // the west-east resolution of the pixel
91  // the north-south resolution of the pixel
93 
94 public:
115  DispersalKernelType dispersal_kernel,
116  const IntegerRaster& dispersers,
117  double dispersal_percentage,
118  double ew_res,
119  double ns_res,
120  double distance_scale,
121  double shape = 1.0)
122  : dispersers_(dispersers),
123  cauchy(distance_scale),
124  exponential(distance_scale),
125  weibull(distance_scale, shape),
126  log_normal(distance_scale),
127  normal(distance_scale),
128  hyperbolic_secant(distance_scale),
129  power_law(distance_scale, shape),
130  logistic(distance_scale),
131  gamma(distance_scale, shape),
132  exponential_power(distance_scale, shape),
133  kernel_type_(dispersal_kernel),
134  east_west_resolution(ew_res),
135  north_south_resolution(ns_res)
136  {
137  // We initialize max distance only for the supported kernels.
138  // For the others, we report the error only when really called
139  // to allow use of this class in initialization phase.
141  max_distance = cauchy.icdf(dispersal_percentage);
142  }
144  max_distance = exponential.icdf(dispersal_percentage);
145  }
147  max_distance = weibull.icdf(dispersal_percentage);
148  }
150  max_distance = normal.icdf(dispersal_percentage);
151  }
153  max_distance = log_normal.icdf(dispersal_percentage);
154  }
156  max_distance = hyperbolic_secant.icdf(dispersal_percentage);
157  }
159  max_distance = power_law.icdf(dispersal_percentage);
160  }
162  max_distance = logistic.icdf(dispersal_percentage);
163  }
165  max_distance = gamma.icdf(dispersal_percentage);
166  }
168  max_distance = exponential_power.icdf(dispersal_percentage);
169  }
170  else {
171  // We allow a kernel object to be incomplete when it won't be further used.
172  // The invalid state is checked later, in this case using the kernel type.
173  return;
174  }
178  probability = prob_size;
179  probability_copy = prob_size;
180  mid_row = number_of_rows / 2;
182  double sum = 0.0;
183  for (int i = 0; i < number_of_rows; i++) {
184  for (int j = 0; j < number_of_columns; j++) {
185  double distance_to_center = std::sqrt(
186  pow((abs(mid_row - i) * east_west_resolution), 2)
187  + pow((abs(mid_col - j) * north_south_resolution), 2));
188  // determine probability based on distance
190  probability(i, j) = abs(cauchy.pdf(distance_to_center));
191  }
193  probability(i, j) = abs(exponential.pdf(distance_to_center));
194  }
196  probability(i, j) = abs(weibull.pdf(distance_to_center));
197  }
199  probability(i, j) = abs(normal.pdf(distance_to_center));
200  }
202  probability(i, j) = abs(log_normal.pdf(distance_to_center));
203  }
205  probability(i, j) = abs(power_law.pdf(distance_to_center));
206  }
208  probability(i, j) = abs(hyperbolic_secant.pdf(distance_to_center));
209  }
211  probability(i, j) = abs(logistic.pdf(distance_to_center));
212  }
214  probability(i, j) = abs(gamma.pdf(distance_to_center));
215  }
217  probability(i, j) = abs(exponential_power.pdf(distance_to_center));
218  }
219  sum += probability(i, j);
220  }
221  }
222  // normalize based on the sum of all probabilities in the raster
223  probability /= sum;
224  }
225 
236  template<class Generator>
237  std::tuple<int, int> operator()(Generator& generator, int row, int col)
238  {
239  UNUSED(generator); // Deterministic does not need random numbers.
250  throw std::invalid_argument(
251  "DeterministicDispersalKernel: Unsupported dispersal kernel type");
252  }
253  // reset the window if considering a new cell
254  if (row != prev_row || col != prev_col) {
255  proportion_of_dispersers = 1.0 / (double)dispersers_(row, col);
257  }
258 
259  int row_movement = 0;
260  int col_movement = 0;
261 
262  double max = (double)-std::numeric_limits<int>::max();
263  int max_prob_row = 0;
264  int max_prob_col = 0;
265 
266  // find cell with highest probability
267  for (int i = 0; i < number_of_rows; i++) {
268  for (int j = 0; j < number_of_columns; j++) {
269  if (probability_copy(i, j) > max) {
270  max = probability_copy(i, j);
271  max_prob_row = i;
272  max_prob_col = j;
273  row_movement = i - mid_row;
274  col_movement = j - mid_col;
275  }
276  }
277  }
278 
279  // subtracting 1/number of dispersers ensures we always move the same
280  // proportion of the individuals to each cell no matter how many are
281  // dispersing
282  probability_copy(max_prob_row, max_prob_col) -= proportion_of_dispersers;
283  prev_row = row;
284  prev_col = col;
285 
286  // return values in terms of actual location
287  return std::make_tuple(row + row_movement, col + col_movement);
288  }
289 
295  static bool supports_kernel(const DispersalKernelType type)
296  {
297  static const std::array<DispersalKernelType, 10> supports = {
308  auto it = std::find(supports.cbegin(), supports.cend(), type);
309  return it != supports.cend();
310  }
311 };
312 
313 } // namespace pops
314 
315 #endif // POPS_DETERMINISTIC_KERNEL_HPP
pops::DispersalKernelType::HyperbolicSecant
@ HyperbolicSecant
Hyperbolic secant dispersal kernel.
raster.hpp
pops::DeterministicDispersalKernel::kernel_type_
DispersalKernelType kernel_type_
Definition: deterministic_kernel.hpp:87
pops::DispersalKernelType::Gamma
@ Gamma
Gamma dispersal kernel.
pops::DeterministicDispersalKernel::exponential_power
ExponentialPowerKernel exponential_power
Definition: deterministic_kernel.hpp:85
pops::DeterministicDispersalKernel::probability_copy
Raster< double > probability_copy
Definition: deterministic_kernel.hpp:75
pops::DeterministicDispersalKernel::prev_row
int prev_row
Definition: deterministic_kernel.hpp:67
pops::DispersalKernelType::Logistic
@ Logistic
Logistic dispersal kernel.
pops::HyperbolicSecantKernel::icdf
double icdf(double x)
Hyperbolic secant inverse cumulative distribution (quantile) function Used by DeterministicKernel to ...
Definition: hyperbolic_secant_kernel.hpp:80
pops::DeterministicDispersalKernel::cauchy
CauchyKernel cauchy
Definition: deterministic_kernel.hpp:76
pops::WeibullKernel
Dispersal kernel for weibull distribution class utilized by RadialKernel and DeterministicKernel.
Definition: weibull_kernel.hpp:33
pops::DeterministicDispersalKernel::operator()
std::tuple< int, int > operator()(Generator &generator, int row, int col)
Generates a new position for the spread.
Definition: deterministic_kernel.hpp:237
utils.hpp
pops::PowerLawKernel::icdf
double icdf(double x)
Power law inverse cumulative distribution (quantile) function Used by DeterministicKernel to determin...
Definition: power_law_kernel.hpp:90
pops::DeterministicDispersalKernel::DeterministicDispersalKernel
DeterministicDispersalKernel(DispersalKernelType dispersal_kernel, const IntegerRaster &dispersers, double dispersal_percentage, double ew_res, double ns_res, double distance_scale, double shape=1.0)
DeterministicDispersalKernel constructor.
Definition: deterministic_kernel.hpp:114
pops::DispersalKernelType::Exponential
@ Exponential
Exponential dispersal kernel.
hyperbolic_secant_kernel.hpp
pops::ExponentialPowerKernel::pdf
double pdf(double x)
Exponential Power probability density function Used by DeterministicKernel to determine location of s...
Definition: exponential_power_kernel.hpp:69
power_law_kernel.hpp
exponential_kernel.hpp
pops::DeterministicDispersalKernel::log_normal
LogNormalKernel log_normal
Definition: deterministic_kernel.hpp:79
pops::CauchyKernel::pdf
double pdf(double x)
Cauchy probability density function Used by DeterministicKernel to determine location of spread.
Definition: cauchy_kernel.hpp:66
pops::DeterministicDispersalKernel
Dispersal kernel for deterministic spread to cell with highest probability of spread.
Definition: deterministic_kernel.hpp:59
pops::DispersalKernelType::Weibull
@ Weibull
Weibull dispersal kernel.
pops::HyperbolicSecantKernel::pdf
double pdf(double x)
Hyperbolic secant probability density function Used by DeterministicKernel to determine location of s...
Definition: hyperbolic_secant_kernel.hpp:66
pops::DeterministicDispersalKernel::mid_row
int mid_row
Definition: deterministic_kernel.hpp:64
pops::ExponentialPowerKernel
Dispersal kernel for exponential power distribution class utilized by RadialKernel and DeterministicK...
Definition: exponential_power_kernel.hpp:33
pops::ExponentialPowerKernel::icdf
double icdf(double x)
Exponential Power inverse cumulative distribution (quantile) function Used by DeterministicKernel to ...
Definition: exponential_power_kernel.hpp:81
pops::DispersalKernelType::ExponentialPower
@ ExponentialPower
Exponential power dispersal kernel.
pops::DeterministicDispersalKernel::north_south_resolution
double north_south_resolution
Definition: deterministic_kernel.hpp:92
pops::ExponentialKernel::icdf
double icdf(double x)
Exponential inverse cumulative distribution (quantile) function Used by DeterministicKernel to determ...
Definition: exponential_kernel.hpp:79
pops::CauchyKernel
Dispersal kernel for cauchy distribution class utilized by RadialKernel and DeterministicKernel.
Definition: cauchy_kernel.hpp:33
pops::DeterministicDispersalKernel::normal
NormalKernel normal
Definition: deterministic_kernel.hpp:80
pops::LogisticKernel::pdf
double pdf(double x)
Logistic probability density function Used by DeterministicKernel to determine location of spread.
Definition: logistic_kernel.hpp:66
pops::DeterministicDispersalKernel::probability
Raster< double > probability
Definition: deterministic_kernel.hpp:74
pops::DeterministicDispersalKernel::east_west_resolution
double east_west_resolution
Definition: deterministic_kernel.hpp:90
pops::DispersalKernelType::Normal
@ Normal
Normal dispersal kernel.
pops::DeterministicDispersalKernel::gamma
GammaKernel gamma
Definition: deterministic_kernel.hpp:84
pops::GammaKernel::pdf
double pdf(double x)
Gamma probability density function Used by DeterministicKernel to determine location of spread.
Definition: gamma_kernel.hpp:68
pops::DispersalKernelType
DispersalKernelType
Type of dispersal kernel.
Definition: kernel_types.hpp:53
pops::LogisticKernel
Dispersal kernel for logistic distribution class utilized by RadialKernel and DeterministicKernel.
Definition: logistic_kernel.hpp:32
pops::NormalKernel::pdf
double pdf(double x)
Normal probability density function Used by DeterministicKernel to determine location of spread.
Definition: normal_kernel.hpp:66
logistic_kernel.hpp
pops::DeterministicDispersalKernel::power_law
PowerLawKernel power_law
Definition: deterministic_kernel.hpp:82
normal_kernel.hpp
UNUSED
#define UNUSED(expr)
Macro to mark unused variables (including parameters) and silence the warning while documenting that ...
Definition: utils.hpp:33
pops::DispersalKernelType::Cauchy
@ Cauchy
Cauchy dispersal kernel.
pops::DeterministicDispersalKernel::hyperbolic_secant
HyperbolicSecantKernel hyperbolic_secant
Definition: deterministic_kernel.hpp:81
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::DispersalKernelType::PowerLaw
@ PowerLaw
Power law dispersal kernel.
pops::DeterministicDispersalKernel::max_distance
double max_distance
Definition: deterministic_kernel.hpp:73
pops::LogisticKernel::icdf
double icdf(double x)
Logistic inverse cumulative distribution (quantile) function Used by DeterministicKernel to determine...
Definition: logistic_kernel.hpp:80
pops
Definition: cauchy_kernel.hpp:25
pops::DeterministicDispersalKernel::number_of_columns
int number_of_columns
Definition: deterministic_kernel.hpp:71
pops::DeterministicDispersalKernel::exponential
ExponentialKernel exponential
Definition: deterministic_kernel.hpp:77
pops::DeterministicDispersalKernel::prev_col
int prev_col
Definition: deterministic_kernel.hpp:68
pops::Raster< double >
pops::PowerLawKernel
Dispersal kernel for power law distribution class utilized by RadialKernel and DeterministicKernel.
Definition: power_law_kernel.hpp:31
pops::DispersalKernelType::LogNormal
@ LogNormal
Log-normal dispersal kernel.
pops::DeterministicDispersalKernel::proportion_of_dispersers
double proportion_of_dispersers
Definition: deterministic_kernel.hpp:88
exponential_power_kernel.hpp
pops::DeterministicDispersalKernel::supports_kernel
static bool supports_kernel(const DispersalKernelType type)
Returns true if the kernel class support a given kernel type.
Definition: deterministic_kernel.hpp:295
pops::LogNormalKernel::pdf
double pdf(double x)
Log normal probability density function Used by DeterministicKernel to determine location of spread.
Definition: lognormal_kernel.hpp:67
pops::LogNormalKernel
Dispersal kernel for log normal distribution class utilized by RadialKernel and DeterministicKernel.
Definition: lognormal_kernel.hpp:35
pops::DeterministicDispersalKernel::mid_col
int mid_col
Definition: deterministic_kernel.hpp:65
pops::ExponentialKernel
Dispersal kernel for exponential distribution class utilized by RadialKernel and DeterministicKernel.
Definition: exponential_kernel.hpp:33
pops::LogNormalKernel::icdf
double icdf(double x)
Log normal inverse cumulative distribution (quantile) function Used by DeterministicKernel to determi...
Definition: lognormal_kernel.hpp:87
pops::CauchyKernel::icdf
double icdf(double x)
Cauchy inverse cumulative distribution (quantile) function Used by DeterministicKernel to determine m...
Definition: cauchy_kernel.hpp:77
pops::NormalKernel
Dispersal kernel for normal distribution class utilized by RadialKernel and DeterministicKernel.
Definition: normal_kernel.hpp:34
pops::ExponentialKernel::pdf
double pdf(double x)
Exponential probability density function Used by DeterministicKernel to determine location of spread.
Definition: exponential_kernel.hpp:65
pops::WeibullKernel::pdf
double pdf(double x)
Weibull probability density function Used by DeterministicKernel to determine location of spread.
Definition: weibull_kernel.hpp:68
gamma_kernel.hpp
pops::DeterministicDispersalKernel::logistic
LogisticKernel logistic
Definition: deterministic_kernel.hpp:83
pops::HyperbolicSecantKernel
Dispersal kernel for hyperbolic secant class utilized by RadialKernel and DeterministicKernel.
Definition: hyperbolic_secant_kernel.hpp:33
pops::WeibullKernel::icdf
double icdf(double x)
Weibull inverse cumulative distribution (quantile) function Used by DeterministicKernel to determine ...
Definition: weibull_kernel.hpp:84
pops::PowerLawKernel::pdf
double pdf(double x)
Power law probability density function Used by DeterministicKernel to determine location of spread.
Definition: power_law_kernel.hpp:70
pops::DeterministicDispersalKernel::number_of_rows
int number_of_rows
Definition: deterministic_kernel.hpp:70
pops::DeterministicDispersalKernel::weibull
WeibullKernel weibull
Definition: deterministic_kernel.hpp:78
pops::DeterministicDispersalKernel::dispersers_
const IntegerRaster & dispersers_
Definition: deterministic_kernel.hpp:62
lognormal_kernel.hpp
weibull_kernel.hpp
kernel_types.hpp
Kernel types enum and helper functions.
cauchy_kernel.hpp
pops::GammaKernel
Dispersal kernel for gamma distribution class utilized by RadialKernel and DeterministicKernel.
Definition: gamma_kernel.hpp:33
pops::GammaKernel::icdf
double icdf(double x)
Gamma inverse cumulative distribution (quantile) function Used by DeterministicKernel to determine ma...
Definition: gamma_kernel.hpp:104