Quetzal-CoaTL
The Coalescence Template Library
Loading...
Searching...
No Matches
merge.hpp
Go to the documentation of this file.
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 __COALESCENCE_MERGE_ALGORITHM_H_INCLUDED__
10#define __COALESCENCE_MERGE_ALGORITHM_H_INCLUDED__
11
14#include <algorithm> // std::shuffle
15#include <cassert>
16#include <functional> // std::plus
17#include <iostream>
18#include <iterator> // std::advance
19#include <type_traits> // std::is_invocable
20
21namespace quetzal
22{
23namespace coalescence
24{
25namespace algorithm
26{
49template <class BidirectionalIterator, class T, class BinaryOperation, class Generator>
50BidirectionalIterator binary_merge(BidirectionalIterator first, BidirectionalIterator last, T init, BinaryOperation op,
51 Generator &g)
52{
53 assert(std::distance(first, last) > 1 && "Coalescence should operate on a range containing more than one element.");
54 std::shuffle(first, last, g);
55 if constexpr (std::is_invocable<T>::value)
56 {
57 *first = op(init(), *first);
58 }
59 else
60 {
61 *first = op(init, *first);
62 }
63 *first = op(*first, *(--last));
64 return last;
65}
66
85template <class BidirectionalIterator, class Generator>
86BidirectionalIterator binary_merge(BidirectionalIterator first, BidirectionalIterator last, Generator &g)
87{
88 assert(std::distance(first, last) > 1 && "Coalescence should operate on a range containing more than one element.");
89 using T = typename BidirectionalIterator::value_type;
90 return binary_merge(first, last, T(), std::plus<T>(), g);
91}
92
113template <class BidirectionalIterator, class T, class BinaryOperation, class OccupancySpectrum, class Generator>
114BidirectionalIterator simultaneous_multiple_merge(BidirectionalIterator first, BidirectionalIterator last, T init,
115 OccupancySpectrum const &sp, BinaryOperation op, Generator &g)
116{
117 assert(std::distance(first, last) > 1 && "Coalescence should operate on a range containing more than one element.");
118 std::shuffle(first, last, g);
119 // directly go to binary merge.
120 auto m_it = sp.cbegin();
121 std::advance(m_it, 2);
122 int j = 2;
123 while (m_it != sp.cend())
124 {
125 for (unsigned int i = 1; i <= *m_it; ++i)
126 {
127 // loop on the m_j parents
128 if constexpr (std::is_invocable<T>::value)
129 {
130 *first = op(init(), *first);
131 }
132 else
133 {
134 *first = op(init, *first);
135 }
136 for (int k = 1; k < j; ++k)
137 {
138 // loop on the others children
139 *first = op(*first, *(--last));
140 }
141 ++first;
142 }
143 ++j;
144 ++m_it;
145 }
146 return last;
147}
148
166template <class BidirectionalIterator, class OccupancySpectrum, class Generator>
167BidirectionalIterator simultaneous_multiple_merge(BidirectionalIterator first, BidirectionalIterator last,
168 OccupancySpectrum const &sp, Generator &g)
169{
170 assert(std::distance(first, last) > 1 && "Coalescence should operate on a range containing more than one element.");
171 using T = typename BidirectionalIterator::value_type;
172 return simultaneous_multiple_merge(first, last, T(), sp, std::plus<T>(), g);
173}
174} // namespace algorithm
175} // end namespace coalescence
176} // end namespace quetzal
177
178#endif
BidirectionalIterator binary_merge(BidirectionalIterator first, BidirectionalIterator last, T init, BinaryOperation op, Generator &g)
merges 2 randomly selected elements in a range.
Definition merge.hpp:50
BidirectionalIterator simultaneous_multiple_merge(BidirectionalIterator first, BidirectionalIterator last, T init, OccupancySpectrum const &sp, BinaryOperation op, Generator &g)
merges randomly selected elements in a range according to an occupancy spectrum.
Definition merge.hpp:114
Simulation of coalescence-based models of molecular evolution.
Definition coalescence.hpp:21