Quetzal-CoaTL
The Coalescence Template Library
Loading...
Searching...
No Matches
ProbabilityDistribution.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#ifndef __OCCUPANCY_SPECTRUM_DISTRIBUTION_H_INCLUDED__
10#define __OCCUPANCY_SPECTRUM_DISTRIBUTION_H_INCLUDED__
11
12#include "Support.hpp"
13#include "editor_policy.hpp"
14#include "filter_policy.hpp"
15
16#include <assert.h>
17#include <cmath> // std::pow
18#include <iostream> // << operator implementation
19#include <random> // discrete_distribution
20#include <utility> // std::forward, std::move
21#include <vector>
22
23#include <boost/multiprecision/cpp_dec_float.hpp>
24#include <boost/multiprecision/cpp_int.hpp>
25#include <boost/random.hpp> // boost::multiprecision::pow
26
27namespace quetzal
28{
29namespace coalescence
30{
31namespace occupancy_spectrum
32{
69template <class FilterPolicy = filter_policy::return_always_true, class EditorPolicy = editor_policy::identity>
71{
72 private:
74 using BigInt = boost::multiprecision::cpp_int;
76 using BigFloat = boost::multiprecision::cpp_dec_float_50;
82 using support_type = std::vector<spectrum_type>;
84 using probabilities_type = std::vector<double>;
86 int m_k;
88 int m_N;
90 FilterPolicy m_pred;
92 support_type m_support;
94 probabilities_type m_probas;
96 mutable std::discrete_distribution<size_t> m_distribution;
97
98 public:
112 ProbabilityDistribution(int n, int m, FilterPolicy pred = FilterPolicy()) : m_k(n), m_N(m), m_pred(pred)
113 {
114 auto callback = make_callback(m_k, m_N);
115 Support s(m_k, m_N);
116 s.generate(callback);
117 m_distribution = std::discrete_distribution<size_t>(m_probas.cbegin(), m_probas.cend());
118 assert(m_support.size() == m_probas.size());
119 }
137 self_type &operator=(const self_type &) = delete;
146 template <typename Generator> const spectrum_type &operator()(Generator &g) const
147 {
148 return m_support[m_distribution(g)];
149 }
153 int n() const
154 {
155 return m_k;
156 }
160 int m() const
161 {
162 return m_N;
163 }
167 const support_type &support() const
168 {
169 return m_support;
170 }
176 const probabilities_type &weights() const
177 {
178 return m_probas;
179 }
183 static double compute_probability(int n, int m, spectrum_type const &m_js)
184 {
185 BigFloat numerator(Factorial(m) * Factorial(n));
186 BigFloat denominator(1.0);
187 int j = 0;
188 for (auto m_j : m_js)
189 {
190 denominator *= boost::multiprecision::pow(BigFloat(Factorial(j)), BigFloat(m_j)) * BigFloat(Factorial(m_j));
191 ++j;
192 }
193 denominator *= BigFloat(std::pow(m, n));
194 BigFloat result = numerator / denominator;
195 return static_cast<double>(result);
196 }
202 friend std::ostream &operator<<(std::ostream &os, self_type const &dist)
203 {
204 for (int i = 0; i < dist.support().size(); ++i)
205 {
206 // os << "P( \t" << dist.support()[i] << "\t) = " << dist.weights()[i] << "\n";
207 auto v = dist.support()[i];
208 os << "P( \t";
209 if (!v.empty())
210 {
211 os << '[';
212 std::copy(v.begin(), v.end(), std::ostream_iterator<int>(os, ", "));
213 os << "\b\b]";
214 }
215 os << "\t) = " << dist.weights()[i] << "\n";
216 }
217 return os;
218 }
219
220 private:
224 auto make_callback(int k, int N)
225 {
226 return [this, k, N](spectrum_type &&M_j) {
227 auto p = compute_probability(k, N, M_j);
228 if (this->m_pred(p))
229 {
230 this->m_support.push_back(EditorPolicy::edit(std::move(M_j)));
231 this->m_probas.push_back(p);
232 }
233 };
234 }
238 static BigInt Factorial(int num)
239 {
240 BigInt fact = 1;
241 for (int i = num; i > 1; --i)
242 {
243 fact *= i;
244 }
245 return fact;
246 }
247};
248} // namespace occupancy_spectrum
249} // namespace coalescence
250} // namespace quetzal
251
252#endif
An occupancy spectrum as defined in Becheler & Knowles, 2020.
Definition OccupancySpectrum.hpp:42
Occupancy spectrum distributed according to the probability function given by von Mises (1939).
Definition ProbabilityDistribution.hpp:71
int m() const
The number of urns (parents) used in the random experience.
Definition ProbabilityDistribution.hpp:160
const support_type & support() const
Get a constant reference on the support of occupancy spectrum distribution.
Definition ProbabilityDistribution.hpp:167
int n() const
The number of balls (coalescing lineages) that are thrown in the random experience.
Definition ProbabilityDistribution.hpp:153
ProbabilityDistribution(int n, int m, FilterPolicy pred=FilterPolicy())
Construct the occupancy spectrum distribution resulting from throwing balls into urns.
Definition ProbabilityDistribution.hpp:112
const spectrum_type & operator()(Generator &g) const
Generates random occupancy spectrum that are distributed according to the associated probability func...
Definition ProbabilityDistribution.hpp:146
static double compute_probability(int n, int m, spectrum_type const &m_js)
Computes the probability of a given spectrum for a given experiment.
Definition ProbabilityDistribution.hpp:183
self_type & operator=(self_type &&)=default
Move assignment operator.
friend std::ostream & operator<<(std::ostream &os, self_type const &dist)
Stream operator to print the distribution support and probabilities.
Definition ProbabilityDistribution.hpp:202
ProbabilityDistribution(self_type &&)=default
Move constructor.
ProbabilityDistribution(const self_type &)=delete
Copy constructor.
self_type & operator=(const self_type &)=delete
Deleted copy assignment operator.
const probabilities_type & weights() const
Get a constant reference the weights associated to each spectrum.
Definition ProbabilityDistribution.hpp:176
Set of occupancy spectrums resulting from throwing balls (the number of coalescing gene copies) into...
Definition Support.hpp:28
void generate(UnaryOperation op) const
Generate all possible configurations.
Definition Support.hpp:52
Simulation of coalescence-based models of molecular evolution.
Definition coalescence.hpp:21