Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tree_pos to tsk_tree_t struct and change next, prev and seek_from_null to use tree_pos #2874

Merged
merged 5 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 204 additions & 2 deletions c/tests/test_trees.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019-2023 Tskit Developers
* Copyright (c) 2019-2024 Tskit Developers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -182,6 +182,8 @@ verify_tree_pos(const tsk_treeseq_t *ts, tsk_size_t num_trees, tsk_id_t *tree_pa
const tsk_size_t N = tsk_treeseq_get_num_nodes(ts);
const tsk_id_t *edges_parent = ts->tables->edges.parent;
const tsk_id_t *edges_child = ts->tables->edges.child;
const double *restrict edges_left = ts->tables->edges.left;
const double *restrict edges_right = ts->tables->edges.right;
tsk_tree_position_t tree_pos;
tsk_id_t *known_parent;
tsk_id_t *parent = tsk_malloc(N * sizeof(*parent));
Expand Down Expand Up @@ -262,7 +264,62 @@ verify_tree_pos(const tsk_treeseq_t *ts, tsk_size_t num_trees, tsk_id_t *tree_pa
CU_ASSERT_EQUAL(parent[u], TSK_NULL);
}

tsk_tree_position_free(&tree_pos);
for (index = 0; index < (tsk_id_t) num_trees; index++) {
known_parent = tree_parents + N * (tsk_size_t) index;
ret = tsk_tree_position_init(&tree_pos, ts, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);

ret = tsk_tree_position_seek_forward(&tree_pos, index);
CU_ASSERT_EQUAL_FATAL(ret, 0);
CU_ASSERT_EQUAL(index, tree_pos.index);

for (j = tree_pos.in.start; j != tree_pos.in.stop; j++) {
e = tree_pos.in.order[j];
if (edges_left[e] <= tree_pos.interval.left
&& tree_pos.interval.left < edges_right[e]) {
parent[edges_child[e]] = edges_parent[e];
}
}
for (u = 0; u < (tsk_id_t) N; u++) {
CU_ASSERT_EQUAL(parent[u], known_parent[u]);
}

tsk_tree_position_free(&tree_pos);
for (u = 0; u < (tsk_id_t) N; u++) {
parent[u] = TSK_NULL;
}
}

valid = tsk_tree_position_next(&tree_pos);
CU_ASSERT_FALSE(valid);

for (index = (tsk_id_t) num_trees - 1; index >= 0; index--) {
known_parent = tree_parents + N * (tsk_size_t) index;
ret = tsk_tree_position_init(&tree_pos, ts, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);

ret = tsk_tree_position_seek_backward(&tree_pos, index);
CU_ASSERT_EQUAL_FATAL(ret, 0);
CU_ASSERT_EQUAL(index, tree_pos.index);

for (j = tree_pos.in.start; j != tree_pos.in.stop; j--) {
e = tree_pos.in.order[j];
if (edges_right[e] >= tree_pos.interval.right
&& tree_pos.interval.right > edges_left[e]) {
parent[edges_child[e]] = edges_parent[e];
}
}

for (u = 0; u < (tsk_id_t) N; u++) {
CU_ASSERT_EQUAL(parent[u], known_parent[u]);
}

for (u = 0; u < (tsk_id_t) N; u++) {
parent[u] = TSK_NULL;
}
tsk_tree_position_free(&tree_pos);
}

tsk_safe_free(parent);
}

Expand Down Expand Up @@ -5350,6 +5407,7 @@ test_single_tree_tree_pos(void)
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

valid = tsk_tree_position_next(&tree_pos);
CU_ASSERT_FATAL(!valid);
Expand All @@ -5360,6 +5418,7 @@ test_single_tree_tree_pos(void)
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 6);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

valid = tsk_tree_position_prev(&tree_pos);
CU_ASSERT_FATAL(valid);
Expand All @@ -5372,6 +5431,7 @@ test_single_tree_tree_pos(void)
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_REVERSE);

valid = tsk_tree_position_prev(&tree_pos);
CU_ASSERT_FATAL(!valid);
Expand All @@ -5380,6 +5440,42 @@ test_single_tree_tree_pos(void)
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, -1);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_REVERSE);

ret = tsk_tree_position_seek_forward(&tree_pos, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);

CU_ASSERT_EQUAL_FATAL(tree_pos.interval.left, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.right, 1);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.stop, 6);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order)
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

valid = tsk_tree_position_next(&tree_pos);
CU_ASSERT_FATAL(!valid);

CU_ASSERT_EQUAL_FATAL(tree_pos.index, -1);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 6);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

ret = tsk_tree_position_seek_backward(&tree_pos, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);

CU_ASSERT_EQUAL_FATAL(tree_pos.interval.left, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.right, 1);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.start, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.stop, -1);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_REVERSE);

tsk_tree_position_free(&tree_pos);
tsk_treeseq_free(&ts);
Expand Down Expand Up @@ -5409,6 +5505,110 @@ test_simple_multi_tree(void)
tsk_treeseq_free(&ts);
}

static void
test_multi_tree_direction_switching_tree_pos(void)
{
tsk_treeseq_t ts;
tsk_tree_position_t tree_pos;
bool valid;
int ret = 0;

tsk_treeseq_from_text(&ts, 10, paper_ex_nodes, paper_ex_edges, NULL, paper_ex_sites,
paper_ex_mutations, paper_ex_individuals, NULL, 0);

ret = tsk_tree_position_init(&tree_pos, &ts, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
valid = tsk_tree_position_next(&tree_pos);
CU_ASSERT_FATAL(valid);

CU_ASSERT_EQUAL_FATAL(tree_pos.index, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.left, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.right, 2);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.stop, 6);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

valid = tsk_tree_position_prev(&tree_pos);
CU_ASSERT_FATAL(!valid);

CU_ASSERT_EQUAL_FATAL(tree_pos.index, -1);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, -1);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_REVERSE);

valid = tsk_tree_position_prev(&tree_pos);
CU_ASSERT_FATAL(valid);

CU_ASSERT_EQUAL_FATAL(tree_pos.index, 2);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.left, 7);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.right, 10);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.start, 10);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.stop, 4);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 10);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 10);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_REVERSE);

valid = tsk_tree_position_next(&tree_pos);
CU_ASSERT_FATAL(!valid);

CU_ASSERT_EQUAL_FATAL(tree_pos.index, -1);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 11);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

ret = tsk_tree_position_seek_forward(&tree_pos, 2);
CU_ASSERT_EQUAL_FATAL(ret, 0);

CU_ASSERT_EQUAL_FATAL(tree_pos.interval.left, 7);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.right, 10);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.stop, 11);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

ret = tsk_tree_position_seek_backward(&tree_pos, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);

CU_ASSERT_EQUAL_FATAL(tree_pos.index, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.left, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.right, 2);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.start, 4);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.stop, -1);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 10);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_REVERSE);

ret = tsk_tree_position_seek_forward(&tree_pos, 2);
CU_ASSERT_EQUAL_FATAL(ret, 0);

CU_ASSERT_EQUAL_FATAL(tree_pos.index, 2);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.left, 7);
CU_ASSERT_EQUAL_FATAL(tree_pos.interval.right, 10);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.start, 6);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.stop, 11);
CU_ASSERT_EQUAL_FATAL(tree_pos.in.order, ts.tables->indexes.edge_insertion_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.start, 0);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.stop, 5);
CU_ASSERT_EQUAL_FATAL(tree_pos.out.order, ts.tables->indexes.edge_removal_order);
CU_ASSERT_EQUAL_FATAL(tree_pos.direction, TSK_DIR_FORWARD);

tsk_tree_position_free(&tree_pos);
tsk_treeseq_free(&ts);
}

static void
test_unary_multi_tree(void)
{
Expand Down Expand Up @@ -8501,6 +8701,8 @@ main(int argc, char **argv)

/* Multi tree tests */
{ "test_simple_multi_tree", test_simple_multi_tree },
{ "test_multi_tree_direction_switching_tree_pos",
test_multi_tree_direction_switching_tree_pos },
{ "test_nonbinary_multi_tree", test_nonbinary_multi_tree },
{ "test_unary_multi_tree", test_unary_multi_tree },
{ "test_internal_sample_multi_tree", test_internal_sample_multi_tree },
Expand Down
27 changes: 7 additions & 20 deletions c/tskit/haplotype_matching.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019-2023 Tskit Developers
* Copyright (c) 2019-2024 Tskit Developers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -209,7 +209,6 @@ int
tsk_ls_hmm_free(tsk_ls_hmm_t *self)
{
tsk_tree_free(&self->tree);
tsk_tree_position_free(&self->tree_pos);
tsk_safe_free(self->recombination_rate);
tsk_safe_free(self->mutation_rate);
tsk_safe_free(self->recombination_rate);
Expand Down Expand Up @@ -247,11 +246,6 @@ tsk_ls_hmm_reset(tsk_ls_hmm_t *self, double value)
tsk_memset(self->transition_parent, 0xff,
self->max_transitions * sizeof(*self->transition_parent));

tsk_tree_position_free(&self->tree_pos);
ret = tsk_tree_position_init(&self->tree_pos, self->tree_sequence, 0);
if (ret != 0) {
goto out;
}
samples = tsk_treeseq_get_samples(self->tree_sequence);
for (j = 0; j < self->num_samples; j++) {
u = samples[j];
Expand All @@ -260,7 +254,6 @@ tsk_ls_hmm_reset(tsk_ls_hmm_t *self, double value)
self->transition_index[u] = (tsk_id_t) j;
}
self->num_transitions = self->num_samples;
out:
return ret;
}

Expand Down Expand Up @@ -309,17 +302,11 @@ tsk_ls_hmm_update_tree(tsk_ls_hmm_t *self, int direction)
tsk_value_transition_t *restrict T = self->transitions;
tsk_id_t u, c, p, j, e;
tsk_value_transition_t *vt;
tsk_tree_position_t tree_pos;

if (direction == TSK_DIR_FORWARD) {
tsk_tree_position_next(&self->tree_pos);
} else {
tsk_tree_position_prev(&self->tree_pos);
}
tsk_bug_assert(self->tree_pos.index != -1);
tsk_bug_assert(self->tree_pos.index == self->tree.index);

for (j = self->tree_pos.out.start; j != self->tree_pos.out.stop; j += direction) {
e = self->tree_pos.out.order[j];
tree_pos = self->tree.tree_pos;
for (j = tree_pos.out.start; j != tree_pos.out.stop; j += direction) {
e = tree_pos.out.order[j];
c = edges_child[e];
u = c;
if (T_index[u] == TSK_NULL) {
Expand All @@ -337,8 +324,8 @@ tsk_ls_hmm_update_tree(tsk_ls_hmm_t *self, int direction)
parent[c] = TSK_NULL;
}

for (j = self->tree_pos.in.start; j != self->tree_pos.in.stop; j += direction) {
e = self->tree_pos.in.order[j];
for (j = tree_pos.in.start; j != tree_pos.in.stop; j += direction) {
e = tree_pos.in.order[j];
c = edges_child[e];
p = edges_parent[e];
parent[c] = p;
Expand Down
6 changes: 1 addition & 5 deletions c/tskit/haplotype_matching.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019-2023 Tskit Developers
* Copyright (c) 2019-2024 Tskit Developers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -98,10 +98,6 @@ typedef struct _tsk_ls_hmm_t {
tsk_size_t num_nodes;
/* state */
tsk_tree_t tree;
/* NOTE: this tree_position will be redundant once we integrate the top-level
* tree class with this.
*/
tsk_tree_position_t tree_pos;
tsk_id_t *parent;
/* The probability value transitions on the tree */
tsk_value_transition_t *transitions;
Expand Down
Loading
Loading