Skip to content

Commit 63b317c

Browse files
Convert kc_distance to use tree_position_t
1 parent f93e792 commit 63b317c

File tree

1 file changed

+54
-52
lines changed

1 file changed

+54
-52
lines changed

c/tskit/trees.c

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6104,51 +6104,55 @@ update_kc_subtree_state(
61046104
}
61056105

61066106
static int
6107-
update_kc_incremental(tsk_tree_t *self, kc_vectors *kc, tsk_edge_list_t *edges_out,
6108-
tsk_edge_list_t *edges_in, tsk_size_t *depths)
6107+
update_kc_incremental(
6108+
tsk_tree_t *tree, kc_vectors *kc, tsk_tree_position_t *tree_pos, tsk_size_t *depths)
61096109
{
61106110
int ret = 0;
6111-
tsk_edge_list_node_t *record;
6112-
tsk_edge_t *e;
6113-
tsk_id_t u;
6111+
tsk_id_t u, v, e, j;
61146112
double root_time, time;
6115-
const double *times = self->tree_sequence->tables->nodes.time;
6113+
const double *restrict times = tree->tree_sequence->tables->nodes.time;
6114+
const tsk_id_t *restrict edges_child = tree->tree_sequence->tables->edges.child;
6115+
const tsk_id_t *restrict edges_parent = tree->tree_sequence->tables->edges.parent;
6116+
6117+
tsk_bug_assert(tree_pos->index == tree->index);
6118+
tsk_bug_assert(tree_pos->interval.left == tree->interval.left);
6119+
tsk_bug_assert(tree_pos->interval.right == tree->interval.right);
61166120

61176121
/* Update state of detached subtrees */
6118-
for (record = edges_out->tail; record != NULL; record = record->prev) {
6119-
e = &record->edge;
6120-
u = e->child;
6122+
for (j = tree_pos->out.stop - 1; j >= tree_pos->out.start; j--) {
6123+
e = tree_pos->out.order[j];
6124+
u = edges_child[e];
61216125
depths[u] = 0;
61226126

6123-
if (self->parent[u] == TSK_NULL) {
6124-
root_time = times[tsk_tree_node_root(self, u)];
6125-
ret = update_kc_subtree_state(self, kc, u, depths, root_time);
6127+
if (tree->parent[u] == TSK_NULL) {
6128+
root_time = times[tsk_tree_node_root(tree, u)];
6129+
ret = update_kc_subtree_state(tree, kc, u, depths, root_time);
61266130
if (ret != 0) {
61276131
goto out;
61286132
}
61296133
}
61306134
}
61316135

61326136
/* Propagate state change down into reattached subtrees. */
6133-
for (record = edges_in->tail; record != NULL; record = record->prev) {
6134-
e = &record->edge;
6135-
u = e->child;
6137+
for (j = tree_pos->in.stop - 1; j >= tree_pos->in.start; j--) {
6138+
e = tree_pos->in.order[j];
6139+
u = edges_child[e];
6140+
v = edges_parent[e];
61366141

6137-
tsk_bug_assert(depths[e->child] == 0);
6138-
depths[u] = depths[e->parent] + 1;
6142+
tsk_bug_assert(depths[u] == 0);
6143+
depths[u] = depths[v] + 1;
61396144

6140-
root_time = times[tsk_tree_node_root(self, u)];
6141-
ret = update_kc_subtree_state(self, kc, u, depths, root_time);
6145+
root_time = times[tsk_tree_node_root(tree, u)];
6146+
ret = update_kc_subtree_state(tree, kc, u, depths, root_time);
61426147
if (ret != 0) {
61436148
goto out;
61446149
}
61456150

6146-
if (tsk_tree_is_sample(self, u)) {
6147-
time = tsk_tree_get_branch_length_unsafe(self, u);
6148-
update_kc_vectors_single_sample(self->tree_sequence, kc, u, time);
6151+
if (tsk_tree_is_sample(tree, u)) {
6152+
time = tsk_tree_get_branch_length_unsafe(tree, u);
6153+
update_kc_vectors_single_sample(tree->tree_sequence, kc, u, time);
61496154
}
61506155
}
6151-
61526156
out:
61536157
return ret;
61546158
}
@@ -6164,19 +6168,18 @@ tsk_treeseq_kc_distance(const tsk_treeseq_t *self, const tsk_treeseq_t *other,
61646168
const tsk_treeseq_t *treeseqs[2] = { self, other };
61656169
tsk_tree_t trees[2];
61666170
kc_vectors kcs[2];
6167-
tsk_diff_iter_t diff_iters[2];
6168-
tsk_edge_list_t edges_out[2];
6169-
tsk_edge_list_t edges_in[2];
6171+
/* TODO the tree_pos here is redundant because we should be using this interally
6172+
* in the trees to do the advancing. Once we have converted the tree over to using
6173+
* tree_pos internally, we can get rid of these tree_pos variables and use
6174+
* the values stored in the trees themselves */
6175+
tsk_tree_position_t tree_pos[2];
61706176
tsk_size_t *depths[2];
6171-
double t0_left, t0_right, t1_left, t1_right;
61726177
int ret = 0;
61736178

61746179
for (i = 0; i < 2; i++) {
61756180
tsk_memset(&trees[i], 0, sizeof(trees[i]));
6176-
tsk_memset(&diff_iters[i], 0, sizeof(diff_iters[i]));
6181+
tsk_memset(&tree_pos[i], 0, sizeof(tree_pos[i]));
61776182
tsk_memset(&kcs[i], 0, sizeof(kcs[i]));
6178-
tsk_memset(&edges_out[i], 0, sizeof(edges_out[i]));
6179-
tsk_memset(&edges_in[i], 0, sizeof(edges_in[i]));
61806183
depths[i] = NULL;
61816184
}
61826185

@@ -6191,7 +6194,7 @@ tsk_treeseq_kc_distance(const tsk_treeseq_t *self, const tsk_treeseq_t *other,
61916194
if (ret != 0) {
61926195
goto out;
61936196
}
6194-
ret = tsk_diff_iter_init_from_ts(&diff_iters[i], treeseqs[i], false);
6197+
ret = tsk_tree_position_init(&tree_pos[i], treeseqs[i], 0);
61956198
if (ret != 0) {
61966199
goto out;
61976200
}
@@ -6218,11 +6221,10 @@ tsk_treeseq_kc_distance(const tsk_treeseq_t *self, const tsk_treeseq_t *other,
62186221
if (ret != 0) {
62196222
goto out;
62206223
}
6221-
ret = tsk_diff_iter_next(
6222-
&diff_iters[0], &t0_left, &t0_right, &edges_out[0], &edges_in[0]);
6223-
tsk_bug_assert(ret == TSK_TREE_OK);
6224-
ret = update_kc_incremental(
6225-
&trees[0], &kcs[0], &edges_out[0], &edges_in[0], depths[0]);
6224+
tsk_tree_position_next(&tree_pos[0]);
6225+
tsk_bug_assert(tree_pos[0].index == 0);
6226+
6227+
ret = update_kc_incremental(&trees[0], &kcs[0], &tree_pos[0], depths[0]);
62266228
if (ret != 0) {
62276229
goto out;
62286230
}
@@ -6231,37 +6233,37 @@ tsk_treeseq_kc_distance(const tsk_treeseq_t *self, const tsk_treeseq_t *other,
62316233
if (ret != 0) {
62326234
goto out;
62336235
}
6234-
ret = tsk_diff_iter_next(
6235-
&diff_iters[1], &t1_left, &t1_right, &edges_out[1], &edges_in[1]);
6236-
tsk_bug_assert(ret == TSK_TREE_OK);
6236+
tsk_tree_position_next(&tree_pos[1]);
6237+
tsk_bug_assert(tree_pos[1].index != -1);
62376238

6238-
ret = update_kc_incremental(
6239-
&trees[1], &kcs[1], &edges_out[1], &edges_in[1], depths[1]);
6239+
ret = update_kc_incremental(&trees[1], &kcs[1], &tree_pos[1], depths[1]);
62406240
if (ret != 0) {
62416241
goto out;
62426242
}
6243-
while (t0_right < t1_right) {
6244-
span = t0_right - left;
6243+
tsk_bug_assert(trees[0].interval.left == tree_pos[0].interval.left);
6244+
tsk_bug_assert(trees[0].interval.right == tree_pos[0].interval.right);
6245+
tsk_bug_assert(trees[1].interval.left == tree_pos[1].interval.left);
6246+
tsk_bug_assert(trees[1].interval.right == tree_pos[1].interval.right);
6247+
while (trees[0].interval.right < trees[1].interval.right) {
6248+
span = trees[0].interval.right - left;
62456249
total += norm_kc_vectors(&kcs[0], &kcs[1], lambda_) * span;
62466250

6247-
left = t0_right;
6251+
left = trees[0].interval.right;
62486252
ret = tsk_tree_next(&trees[0]);
62496253
tsk_bug_assert(ret == TSK_TREE_OK);
62506254
ret = check_kc_distance_tree_inputs(&trees[0]);
62516255
if (ret != 0) {
62526256
goto out;
62536257
}
6254-
ret = tsk_diff_iter_next(
6255-
&diff_iters[0], &t0_left, &t0_right, &edges_out[0], &edges_in[0]);
6256-
tsk_bug_assert(ret == TSK_TREE_OK);
6257-
ret = update_kc_incremental(
6258-
&trees[0], &kcs[0], &edges_out[0], &edges_in[0], depths[0]);
6258+
tsk_tree_position_next(&tree_pos[0]);
6259+
tsk_bug_assert(tree_pos[0].index != -1);
6260+
ret = update_kc_incremental(&trees[0], &kcs[0], &tree_pos[0], depths[0]);
62596261
if (ret != 0) {
62606262
goto out;
62616263
}
62626264
}
6263-
span = t1_right - left;
6264-
left = t1_right;
6265+
span = trees[1].interval.right - left;
6266+
left = trees[1].interval.right;
62656267
total += norm_kc_vectors(&kcs[0], &kcs[1], lambda_) * span;
62666268
}
62676269
if (ret != 0) {
@@ -6272,7 +6274,7 @@ tsk_treeseq_kc_distance(const tsk_treeseq_t *self, const tsk_treeseq_t *other,
62726274
out:
62736275
for (i = 0; i < 2; i++) {
62746276
tsk_tree_free(&trees[i]);
6275-
tsk_diff_iter_free(&diff_iters[i]);
6277+
tsk_tree_position_free(&tree_pos[i]);
62766278
kc_vectors_free(&kcs[i]);
62776279
tsk_safe_free(depths[i]);
62786280
}

0 commit comments

Comments
 (0)