Quetzal-CoaTL
The Coalescence Template Library
Loading...
Searching...
No Matches
dispersal_kernel.hpp
1// Copyright 2021 Arnaud Becheler <abechele@umich.edu>
2
3/*********************************************************************** * This program is free software; you can
4 *redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free
5 *Software Foundation; either version 2 of the License, or * (at your option) any later version. *
6 * *
7 ***************************************************************************/
8
9#pragma once
10
11#include <cassert>
12#include <cmath> // tgamma pow
13#include <numbers> // pi
14
15#include <mp-units/math.h>
16#include <mp-units/systems/si.h>
17
18namespace quetzal
19{
20namespace demography
21{
22namespace dispersal_kernel
23{
24
25using namespace mp_units;
26using namespace mp_units::si::unit_symbols; // shortened units notation: km, m, s
27using std::numbers::pi;
28
33template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>>
35{
37 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
38
41 {
43 Distance a;
44 };
45
50 static constexpr pdf_result_type pdf(Distance r, param_type const &p)
51 {
52 assert(p.a > 0. * m && r >= 0. * m);
53 return (1. / (pi * p.a * p.a)) * exp(-(r * r) / (p.a * p.a));
54 }
55
59 static constexpr Distance mean_dispersal_distance(param_type const &p)
60 {
61 using std::pow;
62 assert(p.a > 0. * m);
63 return (p.a * pow(pi, 0.5)) / 2.;
64 }
65};
66
70template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>> struct logistic
71{
73 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
74
77 {
79 Distance a;
80
82 double b;
83 };
84
90 static constexpr pdf_result_type pdf(Distance r, param_type const &p)
91 {
92 using std::exp;
93 using std::log;
94 using std::pow;
95 using std::tgamma;
96 Distance a = p.a;
97 double b = p.b;
98 assert(a > 0. * m && b > 2. && r >= 0. * m);
99 return (b / (2. * pi * (a * a) * tgamma(2. / b) * tgamma(1. - 2. / b))) *
100 (1. / (1. + (pow(r, b) / (pow(a, b)))));
101 }
102
107 static constexpr Distance mean_dispersal_distance(param_type const &p)
108 {
109 using std::tgamma;
110 Distance a = p.a;
111 double b = p.b;
112 assert(a > 0. * m && b > 2);
113 return (a * tgamma(3. / b) * tgamma(1. - 3. / b)) / (tgamma(2. / b) * tgamma(1. - 2. / b));
114 }
115};
116
122template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>>
124{
126 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
127
130 {
132 Distance a;
133 };
134
139 static constexpr pdf_result_type pdf(Distance r, param_type const &p)
140 {
141 using std::exp;
142 Distance a = p.a;
143 assert(a > 0. * m && r >= 0. * m);
144 return 1. / (2. * pi * a * a) * exp(-r / a);
145 }
146
150 static constexpr Distance mean_dispersal_distance(param_type const &p)
151 {
152 Distance a = p.a;
153 assert(a > 0. * m);
154 return 2. * a;
155 }
156};
157
163template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>> struct exponential_power
164{
166 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
167
170 {
172 Distance a;
173
175 double b;
176 };
177
182 static constexpr pdf_result_type pdf(Distance r, param_type const &p)
183 {
184 //using std::pow;
185 //using std::tgamma;
186 Distance a = p.a;
187 double b = p.b;
188 assert(a > 0. * m && b > 0. && r >= 0. * m);
189 return b / (2. * pi * a * a * tgamma(2. / b)) * exp(- pow(r.numerical_value_in(m), b) / pow(a.numerical_value_in(m),b));
190 }
191
195 static constexpr Distance mean_dispersal_distance(param_type const &p)
196 {
197 using std::tgamma;
198 Distance a = p.a;
199 double b = p.b;
200 assert(a > 0. * m && b > 0.);
201 return a * tgamma(3. / b) / tgamma(2. / b);
202 }
203};
204
209template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>> struct two_dt
210{
212 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
213
216 {
218 Distance a;
219
221 double b;
222 };
223
228 static constexpr pdf_result_type pdf(Distance r, param_type const &p)
229 {
230 using std::pow;
231 Distance a = p.a;
232 double b = p.b;
233 assert(a > 0. * m && b > 1. && r >= 0. * m);
234 return (b - 1.) / (pi * a * a) * pow((1. + (r * r) / (a * a)), -b);
235 }
236
241 static constexpr Distance mean_dispersal_distance(param_type const &p)
242 {
243 using std::pow;
244 using std::tgamma;
245 Distance a = p.a;
246 double b = p.b;
247 assert(a > 0. * m && b > 1.);
248 if (b < 3. / 2.)
249 {
250 return std::numeric_limits<double>::infinity();
251 }
252 return (a * pow(pi, 0.5) * tgamma(b - 3. / 2.)) / (2. * tgamma(b - 1.));
253 }
254};
255
259template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>> struct inverse_power_law
260{
262 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
263
266 {
268 Distance a;
269
271 double b;
272 };
273
278 static constexpr pdf_result_type pdf(Distance r, param_type const &p)
279 {
280 using std::pow;
281 Distance a = p.a;
282 double b = p.b;
283 assert(a > 0. * m && b > 2. && r >= 0. * m);
284 return pow(1. + r / a, -b) * (b - 2.) * (b - 1.) / (2. * pi * a * a);
285 }
286
291 static constexpr Distance mean_dispersal_distance(param_type const &p)
292 {
293 Distance a = p.a;
294 double b = p.b;
295 assert(a > 0. * m && b > 2.);
296 if (b < 3.)
297 {
298 return std::numeric_limits<double>::infinity();
299 }
300 return 2. * a / (b - 3.);
301 }
302};
303
308template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>> struct lognormal
309{
311 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
312
315 {
317 Distance a;
318
320 double b;
321 };
322
327 // static constexpr pdf_result_type pdf(Distance r, param_type const& p)
328 // {
329 // Distance a = p.a;
330 // double b = p.b;
331 // assert(a > 0. * m && b > 0. && r >= 0. * m);
332 // return (1./(pow(2.*pi, 3./.2)*b*r*r)) * exp(- (mp_units::log(r/a)*mp_units::log(r/a) / (2.*b*b) ) );
333 // }
334
338 static constexpr Distance mean_dispersal_distance(param_type const &p)
339 {
340 using std::exp;
341 Distance a = p.a;
342 double b = p.b;
343 assert(a > 0. * m && b > 0.);
344 return a * exp(b * b / 2.);
345 }
346};
347
351template <QuantityOf<isq::length> Distance = mp_units::quantity<mp_units::si::metre>> struct gaussian_mixture
352{
354 using pdf_result_type = quantity<inverse(pow<2>(Distance::reference)), typename Distance::rep>;
355
358 {
360 Distance a1;
362 Distance a2;
364 double p;
365
366 public:
367 };
368
374 static constexpr pdf_result_type pdf(Distance r, param_type const &param)
375 {
376 using std::exp;
377 Distance a1 = param.a1;
378 Distance a2 = param.a2;
379 double p = param.p;
380 assert(a1 > 0. * m && a2 > 0. * m && p > 0. && p < 1. && r >= 0. * m);
381 return p / (pi * a1 * a1) * exp(-(r * r) / (a1 * a1)) +
382 (1. - p) / (pi * a2 * a2) * exp(-(r * r) / (a2 * a2));
383 }
384
388 static constexpr Distance mean_dispersal_distance(param_type const &param)
389 {
390 using std::pow;
391 Distance a1 = param.a1;
392 Distance a2 = param.a2;
393 double p = param.p;
394 assert(a1 > 0. * m && a2 > 0. * m && p > 0. && p < 1.);
395 return pow(pi, 0.5) * (p * a1 + (1. - p) * a2) / 2.;
396 }
397};
398} // namespace dispersal_kernel
399} // namespace demography
400} // namespace quetzal
Simulation of coalescence-based models of molecular evolution.
Definition coalescence.hpp:21
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:170
double b
Shape parameter determining the shape of the curve (weight of long-distance events).
Definition dispersal_kernel.hpp:175
Distance a
Scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:172
Exponential Power dispersal location kernel ( : thin-tailed, : fat-tailed. Always thinner than powe...
Definition dispersal_kernel.hpp:164
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:166
static constexpr Distance mean_dispersal_distance(param_type const &p)
Mean dispersal distance.
Definition dispersal_kernel.hpp:195
static constexpr pdf_result_type pdf(Distance r, param_type const &p)
Probability density function.
Definition dispersal_kernel.hpp:182
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:41
Distance a
Scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:43
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:358
Distance a1
First scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:360
Distance a2
Second scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:362
double p
Shape parameter.
Definition dispersal_kernel.hpp:364
Gaussian Mixture dispersal location kernel (leptokurtic, never fat-tailed)
Definition dispersal_kernel.hpp:352
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:354
static constexpr pdf_result_type pdf(Distance r, param_type const &param)
Probability density function.
Definition dispersal_kernel.hpp:374
static constexpr Distance mean_dispersal_distance(param_type const &param)
Mean dispersal distance.
Definition dispersal_kernel.hpp:388
Gaussian dispersal location kernel (thin-tailed)
Definition dispersal_kernel.hpp:35
static constexpr Distance mean_dispersal_distance(param_type const &p)
Mean dispersal distance.
Definition dispersal_kernel.hpp:59
static constexpr pdf_result_type pdf(Distance r, param_type const &p)
Probability density function.
Definition dispersal_kernel.hpp:50
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:37
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:266
Distance a
Scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:268
double b
Shape parameter determining the shape of the curve (weight of long-distance events).
Definition dispersal_kernel.hpp:271
Inverse Power Law dispersal location kernel (fat-tailed, power-law tail)
Definition dispersal_kernel.hpp:260
static constexpr pdf_result_type pdf(Distance r, param_type const &p)
Probability density function.
Definition dispersal_kernel.hpp:278
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:262
static constexpr Distance mean_dispersal_distance(param_type const &p)
Mean dispersal distance.
Definition dispersal_kernel.hpp:291
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:77
Distance a
Scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:79
double b
Shape parameter determining the shape of the curve (weight of long-distance events).
Definition dispersal_kernel.hpp:82
Logistic dispersal location kernel (fat-tailed, power-law tail)
Definition dispersal_kernel.hpp:71
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:73
static constexpr Distance mean_dispersal_distance(param_type const &p)
Mean dispersal distance.
Definition dispersal_kernel.hpp:107
static constexpr pdf_result_type pdf(Distance r, param_type const &p)
Probability density function.
Definition dispersal_kernel.hpp:90
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:315
Distance a
Scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:317
double b
Shape parameter determining the shape of the curve (weight of long-distance events).
Definition dispersal_kernel.hpp:320
Lognormal dispersal location kernel (fat-tailed)
Definition dispersal_kernel.hpp:309
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:311
static constexpr Distance mean_dispersal_distance(param_type const &p)
Probability density function.
Definition dispersal_kernel.hpp:338
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:130
Distance a
Scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:132
Negative Exponential dispersal location kernel (exponential tail fatness)
Definition dispersal_kernel.hpp:124
static constexpr Distance mean_dispersal_distance(param_type const &p)
Mean dispersal distance.
Definition dispersal_kernel.hpp:150
static constexpr pdf_result_type pdf(Distance r, param_type const &p)
Probability density function.
Definition dispersal_kernel.hpp:139
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:126
Dispersal location kernel parameter.
Definition dispersal_kernel.hpp:216
Distance a
Scale parameter homogeneous to a distance.
Definition dispersal_kernel.hpp:218
double b
Shape parameter determining the shape of the curve (weight of long-distance events).
Definition dispersal_kernel.hpp:221
TwoDt dispersal location kernel (fat-tailed, power-law tail)
Definition dispersal_kernel.hpp:210
static constexpr Distance mean_dispersal_distance(param_type const &p)
Mean dispersal distance.
Definition dispersal_kernel.hpp:241
static constexpr pdf_result_type pdf(Distance r, param_type const &p)
Probability density function.
Definition dispersal_kernel.hpp:228
quantity< inverse(pow< 2 >(Distance::reference)), typename Distance::rep > pdf_result_type
Probability density function value type.
Definition dispersal_kernel.hpp:212