50 template <
typename Space,
typename Matrix>
class Implementation
53 using coord_type = Space;
55 using matrix_type = Matrix;
61 std::vector<point_ID_type>
const &m_points;
63 std::vector<coord_type>
const &m_coords;
65 using distribution_type = std::discrete_distribution<size_t>;
66 mutable std::vector<distribution_type> m_distributions;
78 template <
typename F> matrix_type make_weight_matrix(std::vector<coord_type>
const &coords, F w)
80 matrix_type A(coords.size(), coords.size());
81 for (
unsigned i = 0; i < A.size1(); ++i)
83 auto x = coords.at(i);
84 for (
unsigned j = 0; j < A.size2(); ++j)
86 auto y = coords.at(j);
97 std::vector<distribution_type> make_distributions()
const
99 std::vector<distribution_type> dists;
100 dists.reserve(m_matrix.size1());
101 for (
unsigned i = 0; i < m_matrix.size1(); ++i)
103 std::vector<double> weights;
104 weights.reserve(m_matrix.size2());
105 for (
unsigned j = 0; j < m_matrix.size2(); ++j)
107 weights.push_back(m_matrix(i, j));
109 dists.emplace_back(weights.cbegin(), weights.cend());
118 Implementation(
const Implementation &) =
delete;
124 template <
typename F>
125 Implementation(std::vector<point_ID_type>
const &points, std::vector<coord_type>
const &coords, F f)
126 : m_matrix(make_weight_matrix(coords, f)), m_points(points), m_coords(coords),
127 m_distributions(make_distributions())
133 template <
typename Generator> coord_type sample_arrival(Generator &gen, coord_type
const &x)
const
142 template <
typename Space,
typename Matrix>
class Interface
145 using impl_type = Implementation<Space, Matrix>;
146 using coord_type = Space;
149 std::shared_ptr<impl_type> m_pimpl;
155 template <
typename F>
156 Interface(std::vector<point_ID_type>
const &points, std::vector<coord_type>
const &coords, F f)
157 : m_pimpl(std::make_shared<impl_type>(points, coords, f))
167 template <
typename Generator> coord_type operator()(Generator &gen, coord_type
const &x)
169 return m_pimpl->sample_arrival(gen, x);
175 using value_type =
unsigned int;
186 using coord_type = T;
188 std::vector<point_ID_type> points;
189 points.reserve(coords.size());
190 const auto &ref = coords;
191 std::transform(coords.begin(), coords.end(), std::back_inserter(points),
192 [ref](coord_type
const &x) { return point_ID_type(ref, x); });
193 using matrix_type = boost::numeric::ublas::symmetric_matrix<double>;
194 return Interface<coord_type, matrix_type>(points, coords, f);
214 template <
typename Space,
typename Matrix>
class Implementation
217 using coord_type = Space;
219 using matrix_type = Matrix;
223 matrix_type m_matrix;
225 std::vector<point_ID_type>
const &m_points;
227 std::vector<coord_type>
const &m_coords;
229 mutable std::map<coord_type, std::vector<coord_type>> m_arrival_space_cash;
240 template <
typename F> matrix_type make_weight_matrix(std::vector<coord_type>
const &coords, F w)
242 matrix_type A(coords.size(), coords.size());
243 for (
unsigned i = 0; i < A.size1(); ++i)
245 for (
unsigned j = 0; j < A.size2(); ++j)
247 auto x = coords.at(i);
248 auto y = coords.at(j);
252 return quetzal::utils::divide_terms_by_row_sum(A);
259 Implementation(
const Implementation &) =
delete;
263 template <
typename F>
264 Implementation(std::vector<point_ID_type>
const &points, std::vector<coord_type>
const &coords, F f)
265 : m_matrix(make_matrix(coords, f)), m_points(points), m_coords(coords)
276 auto arrival_space(coord_type
const &x)
const
278 auto it = m_arrival_space_cash.find(x);
279 if (it != m_arrival_space_cash.end())
285 auto p = m_arrival_space_cash.emplace(x, retrieve_non_zero_arrival_space(x));
286 return p.first->second;
292 auto retrieve_non_zero_arrival_space(coord_type
const &x)
const
294 using it1_t =
typename matrix_type::const_iterator1;
295 using it2_t =
typename matrix_type::const_iterator2;
297 it1_t it1 = m_matrix.begin1();
298 std::advance(it1, i);
299 std::vector<coord_type> v;
300 v.reserve(m_matrix.size2());
301 for (it2_t it2 = it1.begin(); it2 != it1.end(); it2++)
304 v.push_back(m_coords.at(it2.index2()));
311 double migration_rate(coord_type
const &x, coord_type
const &y)
321 template <
typename Space,
typename Matrix>
class Interface
324 using impl_type = Implementation<Space, Matrix>;
325 using coord_type = Space;
327 std::shared_ptr<impl_type> m_pimpl;
334 template <
typename F>
335 Interface(std::vector<point_ID_type>
const &points, std::vector<coord_type>
const &coords, F f)
336 : m_pimpl(std::make_shared<impl_type>(points, coords, f))
342 double operator()(coord_type
const &x, coord_type
const &y)
344 return m_pimpl->migration_rate(x, y);
351 auto arrival_space(coord_type
const &x)
const
353 return m_pimpl->arrival_space(x);
359 using value_type =
unsigned int;
370 using coord_type = T;
372 std::vector<point_ID_type> points;
373 points.reserve(coords.size());
374 const auto &ref = coords;
375 std::transform(coords.begin(), coords.end(), std::back_inserter(points),
376 [ref](coord_type
const &x) { return point_ID_type(ref, x); });
377 using matrix_type = boost::numeric::ublas::symmetric_matrix<double>;
378 return Interface<coord_type, matrix_type>(points, coords, f);
392 template <
typename T,
typename F>
395 using coord_type = T;
397 std::vector<point_ID_type> points;
398 points.reserve(coords.size());
399 const auto &ref = coords;
400 std::transform(coords.begin(), coords.end(), std::back_inserter(points),
401 [ref](coord_type
const &x) { return point_ID_type(ref, x); });
402 using matrix_type = boost::numeric::ublas::compressed_matrix<double>;
403 return Interface<coord_type, matrix_type>(points, coords, f);
426 double m_emigrant_rate;
431 using coord_type = Space;
434 : m_emigrant_rate(emigrant_rate), m_friction(friction), m_get_neighbors(get_neighbors)
444 auto v = m_get_neighbors(x);
452 auto operator()(coord_type
const &from, coord_type
const &to)
456 return 1.0 - m_emigrant_rate;
460 return m_emigrant_rate * friction_weights(from, to);
465 double friction_weights(coord_type
const &x, coord_type
const &y)
const
468 auto neighbors = m_get_neighbors(x);
469 std::vector<double> v(neighbors.size(), 0.0);
470 std::transform(neighbors.begin(), neighbors.end(), v.begin(),
471 [
this](coord_type
const &z) { return 1.0 / (this->m_friction(z)); });
472 double sum = std::accumulate(v.begin(), v.end(), 0.0);
473 return 1.0 / (m_friction(y) * sum);
491 template <
typename T,
typename U,
typename V>
static neighboring_migration< T, U, V > make_neighboring_migration(T, double emigrant_rate, U friction, V get_neighbors)
Helper function to create a dispersal kernel compatible with History specialized for the mass-based p...
Definition demographic_policy.hpp:492
static auto make_distance_based_dispersal(std::vector< T > const &coords, F f)
Build a dispersal kernel usable with class History specialized for mass-based simulation policy.
Definition demographic_policy.hpp:368
size_t getIndexOfPointInVector(Point const &p, std::vector< Point > const &vect)
Find the index of a point in a vector.
Definition PointWithId.hpp:22