Program Listing for File table_collection.hpp¶
↰ Return to documentation for file (fwdpp/ts/table_collection.hpp)
#ifndef FWDPP_TS_TABLE_COLLECTION_HPP
#define FWDPP_TS_TABLE_COLLECTION_HPP
#include <vector>
#include <utility>
#include <cstdint>
#include <cmath>
#include <tuple>
#include <algorithm>
#include <numeric>
#include <cassert>
#include <cstddef>
#include <stdexcept>
#include <fwdpp/forward_types.hpp>
#include <fwdpp/ts/exceptions.hpp>
#include "definitions.hpp"
namespace fwdpp
{
namespace ts
{
template <typename NodeTableType, typename EdgeTableType, typename SiteTableType,
typename MutationTableType>
struct table_collection
{
private:
double L;
public:
using node_table = NodeTableType;
using edge_table = EdgeTableType;
using site_table = SiteTableType;
using mutation_table = MutationTableType;
using edge_t = typename EdgeTableType::value_type;
using node_t = typename NodeTableType::value_type;
using site_t = typename SiteTableType::value_type;
using mutation_t = typename MutationTableType::value_type;
node_table nodes;
edge_table edges;
mutation_table mutations;
site_table sites;
std::vector<table_index_t> input_left;
std::vector<table_index_t> output_right;
std::ptrdiff_t edge_offset;
std::vector<table_index_t> preserved_nodes;
explicit table_collection(const double maxpos)
: L{maxpos}, nodes{}, edges{}, mutations{}, sites{}, input_left{},
output_right{}, edge_offset{0}, preserved_nodes{}
{
if (maxpos <= 0 || !std::isfinite(maxpos))
{
throw std::invalid_argument("maxpos must be > 0 and finite");
}
}
table_collection(const table_index_t num_initial_nodes,
const double initial_time, table_index_t pop,
const double maxpos)
: L{maxpos}, nodes{}, edges{}, mutations{}, sites{}, input_left{},
output_right{}, edge_offset{0}, preserved_nodes{}
{
if (maxpos <= 0 || !std::isfinite(maxpos))
{
throw std::invalid_argument("maxpos must be > 0 and finite");
}
for (table_index_t i = 0; i < num_initial_nodes; ++i)
{
nodes.push_back(node_t{pop, initial_time});
}
}
void
clear() noexcept
{
nodes.clear();
edges.clear();
mutations.clear();
preserved_nodes.clear();
sites.clear();
}
void
record_preserved_nodes(const std::vector<table_index_t>& node_ids)
{
for (auto i : node_ids)
{
if (static_cast<std::size_t>(i) >= nodes.size())
{
throw std::invalid_argument(
"node id larger than node table size");
}
if (std::find(preserved_nodes.begin(), preserved_nodes.end(), i)
!= preserved_nodes.end())
{
throw std::invalid_argument("node already recorded as a "
"preserved_node");
}
preserved_nodes.push_back(i);
}
}
table_index_t
push_back_node(double time, std::int32_t pop)
{
nodes.push_back(node_t{pop, time});
return static_cast<table_index_t>(nodes.size() - 1);
}
template <typename... args>
table_index_t
emplace_back_node(args&&... Args)
{
nodes.emplace_back(node_t{std::forward<args>(Args)...});
return static_cast<table_index_t>(nodes.size() - 1);
}
std::size_t
push_back_edge(double l, double r, table_index_t parent, table_index_t child)
{
edges.push_back(edge_t{l, r, parent, child});
return edges.size();
}
template <typename... args>
std::size_t
emplace_back_edge(args&&... Args)
{
edges.emplace_back(edge_t{std::forward<args>(Args)...});
return edges.size();
}
template <typename... args>
std::size_t
push_back_site(args&&... Args)
{
sites.push_back(site_t{std::forward<args>(Args)...});
return sites.size() - 1;
}
template <typename... args>
std::size_t
emplace_back_site(args&&... Args)
{
sites.emplace_back(site_t{std::forward<args>(Args)...});
return sites.size() - 1;
}
template <typename... args>
std::size_t
push_back_mutation(args&&... Args)
{
mutations.push_back(mutation_t{std::forward<args>(Args)...});
return mutations.size() - 1;
}
template <typename... args>
std::size_t
emplace_back_mutation(args&&... Args)
{
mutations.emplace_back(mutation_t{std::forward<args>(Args)...});
return mutations.size() - 1;
}
void
build_indexes()
{
input_left.clear();
output_right.clear();
input_left.resize(edges.size());
output_right.resize(edges.size());
std::iota(begin(input_left), end(input_left), 0);
std::iota(begin(output_right), end(output_right), 0);
std::sort(begin(input_left), end(input_left), [this](auto i, auto j) {
if (edges[i].left == edges[j].left)
{
return nodes[edges[i].parent].time
> nodes[edges[j].parent].time;
}
return edges[i].left < edges[j].left;
});
std::sort(begin(output_right), end(output_right),
[this](auto i, auto j) {
if (edges[i].right == edges[j].right)
{
return nodes[edges[i].parent].time
< nodes[edges[j].parent].time;
}
return edges[i].right < edges[j].right;
});
}
std::size_t
num_nodes() const
{
return nodes.size();
}
std::size_t
num_edges() const
{
return edges.size();
}
double
genome_length() const
{
return L;
}
inline bool
operator==(const table_collection& b) const
{
return genome_length() == b.genome_length() && sites == b.sites
&& edges == b.edges && nodes == b.nodes
&& mutations == b.mutations
&& preserved_nodes == b.preserved_nodes;
}
inline bool
operator!=(const table_collection& b) const
{
return !(*this == b);
}
};
} // namespace ts
} // namespace fwdpp
#endif