1 #ifndef GENESIS_POPULATION_FUNCTION_FST_POOL_FUNCTIONS_H_
2 #define GENESIS_POPULATION_FUNCTION_FST_POOL_FUNCTIONS_H_
58 namespace population {
77 #if __cplusplus >= 201402L
120 template<
class ForwardIterator,
typename FstFunctor>
121 utils::Matrix<double> compute_pairwise_f_st(
122 ForwardIterator begin, ForwardIterator end,
123 FstFunctor fst_functor
133 size_t const size =
static_cast<std::vector<SampleCounts> const&
>( *begin ).size();
134 auto result = utils::Matrix<double>( size, size, 0.0 );
138 auto select_entry = [size]( ForwardIterator begin, ForwardIterator end,
size_t index ){
145 [size, index]( std::vector<SampleCounts>
const& samples ) -> SampleCounts
const& {
146 if( samples.size() != size ) {
147 throw std::runtime_error(
148 "In compute_pairwise_f_st(): The number of SampleCounts in the "
149 "provided range is not consistent throughout the iteration."
152 return samples[index];
161 for(
size_t i = 0; i < size; ++i ) {
162 for(
size_t j = i + 1; j < size; ++j ) {
163 auto range_i = select_entry( begin, end, i );
164 auto range_j = select_entry( begin, end, j );
165 auto const fst = fst_functor(
167 range_i.begin(), range_i.end(),
168 range_j.begin(), range_j.end()
170 result( i, j ) = fst;
171 result( j, i ) = fst;
178 #endif // __cplusplus >= 201402L
187 template<
class ForwardIterator1,
class ForwardIterator2>
189 size_t p1_poolsize,
size_t p2_poolsize,
190 ForwardIterator1 p1_begin, ForwardIterator1 p1_end,
191 ForwardIterator2 p2_begin, ForwardIterator2 p2_end,
192 bool only_passing_samples =
true
195 if( p1_poolsize <= 1 || p2_poolsize <= 1 ) {
196 return std::numeric_limits<double>::quiet_NaN();
205 auto p1_it = p1_begin;
206 auto p2_it = p2_begin;
207 while( p1_it != p1_end && p2_it != p2_end ) {
208 if( only_passing_samples && ( !p1_it->status.passing() || !p2_it->status.passing() )) {
212 calc.
process( *p1_it, *p2_it );
216 if( p1_it != p1_end || p2_it != p2_end ) {
217 throw std::invalid_argument(
218 "In f_st_pool_kofler(): Provided ranges have different length."
223 return calc.get_result();
226 #if __cplusplus >= 201402L
235 template<
class ForwardIterator>
237 std::vector<size_t>
const& poolsizes,
238 ForwardIterator begin, ForwardIterator end
240 return compute_pairwise_f_st(
242 [&](
size_t i,
size_t j,
auto p1_begin,
auto p1_end,
auto p2_begin,
auto p2_end ){
243 if( i >= poolsizes.size() || j >= poolsizes.size() ) {
244 throw std::runtime_error(
245 "In f_st_pool_kofler(): Provided ranges have different lengths that "
246 "are not identical to the number of poolsizes provided."
250 poolsizes[i], poolsizes[j],
251 p1_begin, p1_end, p2_begin, p2_end
257 #endif // __cplusplus >= 201402L
266 template<
class ForwardIterator1,
class ForwardIterator2>
268 ForwardIterator1 p1_begin, ForwardIterator1 p1_end,
269 ForwardIterator2 p2_begin, ForwardIterator2 p2_end,
270 bool only_passing_samples =
true
278 auto p1_it = p1_begin;
279 auto p2_it = p2_begin;
280 while( p1_it != p1_end && p2_it != p2_end ) {
281 if( only_passing_samples && ( !p1_it->status.passing() || !p2_it->status.passing() )) {
285 calc.
process( *p1_it, *p2_it );
289 if( p1_it != p1_end || p2_it != p2_end ) {
290 throw std::invalid_argument(
291 "In f_st_pool_karlsson(): Provided ranges have different length."
295 return calc.get_result();
298 #if __cplusplus >= 201402L
307 template<
class ForwardIterator>
309 ForwardIterator begin, ForwardIterator end
311 return compute_pairwise_f_st(
313 [&](
size_t i,
size_t j,
auto p1_begin,
auto p1_end,
auto p2_begin,
auto p2_end ){
317 p1_begin, p1_end, p2_begin, p2_end
323 #endif // __cplusplus >= 201402L
332 template<
class ForwardIterator1,
class ForwardIterator2>
334 size_t p1_poolsize,
size_t p2_poolsize,
335 ForwardIterator1 p1_begin, ForwardIterator1 p1_end,
336 ForwardIterator2 p2_begin, ForwardIterator2 p2_end,
337 bool only_passing_samples =
true
340 if( p1_poolsize <= 1 || p2_poolsize <= 1 ) {
342 std::numeric_limits<double>::quiet_NaN(),
343 std::numeric_limits<double>::quiet_NaN()
356 auto p1_it = p1_begin;
357 auto p2_it = p2_begin;
358 while( p1_it != p1_end && p2_it != p2_end ) {
359 if( only_passing_samples && ( !p1_it->status.passing() || !p2_it->status.passing() )) {
363 calc.process( *p1_it, *p2_it );
367 if( p1_it != p1_end || p2_it != p2_end ) {
368 throw std::invalid_argument(
369 "In f_st_pool_unbiased(): Provided ranges have different length."
374 return calc.get_result_pair();
377 #if __cplusplus >= 201402L
389 template<
class ForwardIterator>
391 std::vector<size_t>
const& poolsizes,
392 ForwardIterator begin, ForwardIterator end
394 return compute_pairwise_f_st(
396 [&](
size_t i,
size_t j,
auto p1_begin,
auto p1_end,
auto p2_begin,
auto p2_end ){
397 if( i >= poolsizes.size() || j >= poolsizes.size() ) {
398 throw std::runtime_error(
399 "In f_st_pool_unbiased_nei(): Provided ranges have different lengths that "
400 "are not identical to the number of poolsizes provided."
404 poolsizes[i], poolsizes[j],
405 p1_begin, p1_end, p2_begin, p2_end
421 template<
class ForwardIterator>
422 utils::Matrix<double> f_st_pool_unbiased_hudson(
423 std::vector<size_t>
const& poolsizes,
424 ForwardIterator begin, ForwardIterator end
426 return compute_pairwise_f_st(
428 [&](
size_t i,
size_t j,
auto p1_begin,
auto p1_end,
auto p2_begin,
auto p2_end ){
429 if( i >= poolsizes.size() || j >= poolsizes.size() ) {
430 throw std::runtime_error(
431 "In f_st_pool_unbiased_hudson(): Provided ranges have different lengths that "
432 "are not identical to the number of poolsizes provided."
436 poolsizes[i], poolsizes[j],
437 p1_begin, p1_end, p2_begin, p2_end
443 #endif // __cplusplus >= 201402L
448 #endif // include guard