Program Listing for File transpose_window.hpp¶
↰ Return to documentation for file (include/sgpl/algorithm/transpose_window.hpp)
#pragma once
#ifndef SGPL_ALGORITHM_TRANSPOSE_WINDOW_HPP_INCLUDE
#define SGPL_ALGORITHM_TRANSPOSE_WINDOW_HPP_INCLUDE
#include <algorithm>
#include <cassert>
#include <iterator>
#include <tuple>
#include <utility>
#include "../algorithm/next.hpp"
#include "../algorithm/prev.hpp"
#include "../spec/TransposeWindowDisplacementGenerator_Default.hpp"
#include "../spec/TransposeWindowSizeGenerator_Default.hpp"
#include "../utility/random_between.hpp"
#include "../utility/ThreadLocalRandom.hpp"
#include "slide_n.hpp"
namespace sgpl {
namespace impl {
template <
typename RandomIt,
typename WindowDisplacementGenerator
>
std::tuple<RandomIt, RandomIt, RandomIt> transpose_window(
const RandomIt genome_first,
const RandomIt genome_last,
const RandomIt window_first,
const RandomIt window_last,
const WindowDisplacementGenerator& window_displacement_generator
) {
assert(genome_first <= window_first);
assert(window_first <= window_last);
assert(window_last <= genome_last);
const int num_sites_before_window
= std::distance(genome_first, window_first);
const int num_sites_after_window
= std::distance(window_last, genome_last);
const int displacement = window_displacement_generator(
num_sites_before_window,
num_sites_after_window
);
const RandomIt transposed_window_first = sgpl::slide_n(
window_first, window_last,
displacement
);
const size_t window_width = std::distance(window_first, window_last);
const RandomIt transposed_window_last = std::next(
transposed_window_first, window_width
);
return {window_first, transposed_window_first, transposed_window_last};
}
} // namespace impl
template <
typename RandomIt,
typename WindowDisplacementGenerator,
typename WindowSizeGenerator
>
std::tuple<RandomIt, RandomIt, RandomIt> transpose_window(
const RandomIt genome_first,
const RandomIt genome_last,
const RandomIt target_site,
const WindowDisplacementGenerator& window_displacement_generator,
const WindowSizeGenerator& window_size_generator
) {
assert(genome_first <= target_site);
assert(target_site <= genome_last);
const size_t num_genome_sites = std::distance(
genome_first,
genome_last
);
const size_t window_size = window_size_generator(num_genome_sites);
// window must contain target site
const RandomIt leftmost_legal_window_first = sgpl::prev(
target_site, genome_first, window_size
);
const RandomIt rightmost_legal_window_first = std::min(
std::prev(genome_last, window_size),
sgpl::next(target_site, genome_last, window_size)
);
const RandomIt window_first = sgpl::random_between(
leftmost_legal_window_first,
rightmost_legal_window_first
);
const RandomIt window_last = std::next(window_first, window_size);
return sgpl::impl::transpose_window<RandomIt, WindowDisplacementGenerator>(
genome_first,
genome_last,
window_first,
window_last,
window_displacement_generator
);
}
template <
typename RandomIt,
typename WindowDisplacementGenerator
=sgpl::TransposeWindowDisplacementGenerator_Default,
typename WindowSizeGenerator
=sgpl::TransposeWindowSizeGenerator_Default
>
std::tuple<RandomIt, RandomIt, RandomIt> transpose_window(
const RandomIt genome_first,
const RandomIt genome_last,
const WindowDisplacementGenerator window_displacement_generator={},
const WindowSizeGenerator window_size_generator={}
) {
const RandomIt target_site = sgpl::random_between(
genome_first,
genome_last
);
return sgpl::transpose_window<
RandomIt, WindowDisplacementGenerator, WindowSizeGenerator
>(
genome_first,
genome_last,
target_site,
window_displacement_generator,
window_size_generator
);
}
} // namespace sgpl
#endif // #ifndef SGPL_ALGORITHM_TRANSPOSE_WINDOW_HPP_INCLUDE