@@ -3509,34 +3509,29 @@ tsk_tree_get_num_samples_by_traversal(
3509
3509
const tsk_tree_t * self , tsk_id_t u , tsk_size_t * num_samples )
3510
3510
{
3511
3511
int ret = 0 ;
3512
- tsk_id_t * stack = NULL ;
3513
- tsk_id_t v ;
3512
+ tsk_size_t num_nodes , j ;
3514
3513
tsk_size_t count = 0 ;
3515
- int stack_top = 0 ;
3514
+ const tsk_flags_t * restrict flags = self -> tree_sequence -> tables -> nodes .flags ;
3515
+ tsk_id_t * nodes = tsk_malloc (tsk_tree_get_size_bound (self ) * sizeof (* nodes ));
3516
+ tsk_id_t v ;
3516
3517
3517
- stack = tsk_malloc (self -> num_nodes * sizeof (* stack ));
3518
- if (stack == NULL ) {
3518
+ if (nodes == NULL ) {
3519
3519
ret = TSK_ERR_NO_MEMORY ;
3520
3520
goto out ;
3521
3521
}
3522
-
3523
- stack [0 ] = u ;
3524
- while (stack_top >= 0 ) {
3525
- v = stack [stack_top ];
3526
- stack_top -- ;
3527
- if (tsk_treeseq_is_sample (self -> tree_sequence , v )) {
3522
+ ret = tsk_tree_preorder (self , u , nodes , & num_nodes );
3523
+ if (ret != 0 ) {
3524
+ goto out ;
3525
+ }
3526
+ for (j = 0 ; j < num_nodes ; j ++ ) {
3527
+ v = nodes [j ];
3528
+ if (flags [v ] & TSK_NODE_IS_SAMPLE ) {
3528
3529
count ++ ;
3529
3530
}
3530
- v = self -> left_child [v ];
3531
- while (v != TSK_NULL ) {
3532
- stack_top ++ ;
3533
- stack [stack_top ] = v ;
3534
- v = self -> right_sib [v ];
3535
- }
3536
3531
}
3537
3532
* num_samples = count ;
3538
3533
out :
3539
- tsk_safe_free (stack );
3534
+ tsk_safe_free (nodes );
3540
3535
return ret ;
3541
3536
}
3542
3537
@@ -3636,6 +3631,40 @@ tsk_tree_get_time(const tsk_tree_t *self, tsk_id_t u, double *t)
3636
3631
return ret ;
3637
3632
}
3638
3633
3634
+ int
3635
+ tsk_tree_get_total_branch_length (const tsk_tree_t * self , tsk_id_t node , double * ret_tbl )
3636
+ {
3637
+ int ret = 0 ;
3638
+ tsk_size_t j , num_nodes ;
3639
+ tsk_id_t u , v ;
3640
+ const tsk_id_t * restrict parent = self -> parent ;
3641
+ const double * restrict time = self -> tree_sequence -> tables -> nodes .time ;
3642
+ tsk_id_t * nodes = tsk_malloc (tsk_tree_get_size_bound (self ) * sizeof (* nodes ));
3643
+ double sum = 0 ;
3644
+
3645
+ if (nodes == NULL ) {
3646
+ ret = TSK_ERR_NO_MEMORY ;
3647
+ goto out ;
3648
+ }
3649
+ ret = tsk_tree_preorder (self , node , nodes , & num_nodes );
3650
+ if (ret != 0 ) {
3651
+ goto out ;
3652
+ }
3653
+ /* We always skip the first node because we don't return the branch length
3654
+ * over the input node. */
3655
+ for (j = 1 ; j < num_nodes ; j ++ ) {
3656
+ u = nodes [j ];
3657
+ v = parent [u ];
3658
+ if (v != TSK_NULL ) {
3659
+ sum += time [v ] - time [u ];
3660
+ }
3661
+ }
3662
+ * ret_tbl = sum ;
3663
+ out :
3664
+ tsk_safe_free (nodes );
3665
+ return ret ;
3666
+ }
3667
+
3639
3668
int TSK_WARN_UNUSED
3640
3669
tsk_tree_get_sites (
3641
3670
const tsk_tree_t * self , const tsk_site_t * * sites , tsk_size_t * sites_length )
@@ -3649,14 +3678,14 @@ tsk_tree_get_sites(
3649
3678
static int
3650
3679
tsk_tree_get_depth_unsafe (const tsk_tree_t * self , tsk_id_t u )
3651
3680
{
3652
-
3653
3681
tsk_id_t v ;
3682
+ const tsk_id_t * restrict parent = self -> parent ;
3654
3683
int depth = 0 ;
3655
3684
3656
3685
if (u == self -> virtual_root ) {
3657
3686
return -1 ;
3658
3687
}
3659
- for (v = self -> parent [u ]; v != TSK_NULL ; v = self -> parent [v ]) {
3688
+ for (v = parent [u ]; v != TSK_NULL ; v = parent [v ]) {
3660
3689
depth ++ ;
3661
3690
}
3662
3691
return depth ;
@@ -4443,6 +4472,9 @@ get_smallest_set_bit(uint64_t v)
4443
4472
* use a general cost matrix, in which case we'll use the Sankoff algorithm. For
4444
4473
* now this is unused.
4445
4474
*
4475
+ * We should also vectorise the function so that several sites can be processed
4476
+ * at once.
4477
+ *
4446
4478
* The algorithm used here is Hartigan parsimony, "Minimum Mutation Fits to a
4447
4479
* Given Tree", Biometrics 1973.
4448
4480
*/
@@ -4458,30 +4490,34 @@ tsk_tree_map_mutations(tsk_tree_t *self, int8_t *genotypes,
4458
4490
int8_t state ;
4459
4491
};
4460
4492
const tsk_size_t num_samples = self -> tree_sequence -> num_samples ;
4461
- const tsk_size_t num_nodes = self -> num_nodes ;
4462
4493
const tsk_id_t * restrict left_child = self -> left_child ;
4463
4494
const tsk_id_t * restrict right_sib = self -> right_sib ;
4464
- const tsk_id_t * restrict parent = self -> parent ;
4495
+ const tsk_size_t N = tsk_treeseq_get_num_nodes ( self -> tree_sequence ) ;
4465
4496
const tsk_flags_t * restrict node_flags = self -> tree_sequence -> tables -> nodes .flags ;
4466
- uint64_t optimal_root_set ;
4467
- uint64_t * restrict optimal_set = tsk_calloc (num_nodes , sizeof (* optimal_set ));
4468
- tsk_id_t * restrict postorder_stack
4469
- = tsk_malloc (num_nodes * sizeof (* postorder_stack ));
4497
+ tsk_id_t * nodes = tsk_malloc (tsk_tree_get_size_bound (self ) * sizeof (* nodes ));
4498
+ /* Note: to use less memory here and to improve cache performance we should
4499
+ * probably change to allocating exactly the number of nodes returned by
4500
+ * a preorder traversal, and then lay the memory out in this order. So, we'd
4501
+ * need a map from node ID to its index in the preorder traversal, but this
4502
+ * is trivial to compute. Probably doesn't matter so much at the moment
4503
+ * when we're doing a single site, but it would make a big difference if
4504
+ * we were vectorising over lots of sites. */
4505
+ uint64_t * restrict optimal_set = tsk_calloc (N + 1 , sizeof (* optimal_set ));
4470
4506
struct stack_elem * restrict preorder_stack
4471
- = tsk_malloc (num_nodes * sizeof (* preorder_stack ));
4472
- tsk_id_t postorder_parent , root , u , v ;
4507
+ = tsk_malloc (tsk_tree_get_size_bound ( self ) * sizeof (* preorder_stack ));
4508
+ tsk_id_t root , u , v ;
4473
4509
/* The largest possible number of transitions is one over every sample */
4474
4510
tsk_state_transition_t * transitions = tsk_malloc (num_samples * sizeof (* transitions ));
4475
4511
int8_t allele , ancestral_state ;
4476
4512
int stack_top ;
4477
4513
struct stack_elem s ;
4478
- tsk_size_t j , num_transitions , max_allele_count ;
4514
+ tsk_size_t j , num_transitions , max_allele_count , num_nodes ;
4479
4515
tsk_size_t allele_count [HARTIGAN_MAX_ALLELES ];
4480
4516
tsk_size_t non_missing = 0 ;
4481
4517
int8_t num_alleles = 0 ;
4482
4518
4483
- if (optimal_set == NULL || preorder_stack == NULL || postorder_stack == NULL
4484
- || transitions == NULL ) {
4519
+ if (optimal_set == NULL || preorder_stack == NULL || transitions == NULL
4520
+ || nodes == NULL ) {
4485
4521
ret = TSK_ERR_NO_MEMORY ;
4486
4522
goto out ;
4487
4523
}
@@ -4518,68 +4554,33 @@ tsk_tree_map_mutations(tsk_tree_t *self, int8_t *genotypes,
4518
4554
}
4519
4555
}
4520
4556
4521
- for (root = self -> left_root ; root != TSK_NULL ; root = self -> right_sib [root ]) {
4522
- /* Do a post order traversal */
4523
- postorder_stack [0 ] = root ;
4524
- stack_top = 0 ;
4525
- postorder_parent = TSK_NULL ;
4526
- while (stack_top >= 0 ) {
4527
- u = postorder_stack [stack_top ];
4528
- if (left_child [u ] != TSK_NULL && u != postorder_parent ) {
4529
- for (v = left_child [u ]; v != TSK_NULL ; v = right_sib [v ]) {
4530
- stack_top ++ ;
4531
- postorder_stack [stack_top ] = v ;
4532
- }
4533
- } else {
4534
- stack_top -- ;
4535
- postorder_parent = parent [u ];
4536
-
4537
- /* Visit u */
4538
- tsk_memset (
4539
- allele_count , 0 , ((size_t ) num_alleles ) * sizeof (* allele_count ));
4540
- for (v = left_child [u ]; v != TSK_NULL ; v = right_sib [v ]) {
4541
- for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4542
- allele_count [allele ] += bit_is_set (optimal_set [v ], allele );
4543
- }
4544
- }
4545
- if (!(node_flags [u ] & TSK_NODE_IS_SAMPLE )) {
4546
- max_allele_count = 0 ;
4547
- for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4548
- max_allele_count
4549
- = TSK_MAX (max_allele_count , allele_count [allele ]);
4550
- }
4551
- for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4552
- if (allele_count [allele ] == max_allele_count ) {
4553
- optimal_set [u ] = set_bit (optimal_set [u ], allele );
4554
- }
4555
- }
4556
- }
4557
- }
4558
- }
4557
+ ret = tsk_tree_postorder (self , self -> virtual_root , nodes , & num_nodes );
4558
+ if (ret != 0 ) {
4559
+ goto out ;
4559
4560
}
4560
-
4561
- if (!(options & TSK_MM_FIXED_ANCESTRAL_STATE )) {
4562
- optimal_root_set = 0 ;
4563
- /* TODO it's annoying that this is essentially the same as the
4564
- * visit function above. It would be nice if we had an extra
4565
- * node that was the parent of all roots, then the algorithm
4566
- * would work as-is */
4561
+ for (j = 0 ; j < num_nodes ; j ++ ) {
4562
+ u = nodes [j ];
4567
4563
tsk_memset (allele_count , 0 , ((size_t ) num_alleles ) * sizeof (* allele_count ));
4568
- for (root = self -> left_root ; root != TSK_NULL ; root = right_sib [root ]) {
4564
+ for (v = left_child [ u ]; v != TSK_NULL ; v = right_sib [v ]) {
4569
4565
for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4570
- allele_count [allele ] += bit_is_set (optimal_set [root ], allele );
4566
+ allele_count [allele ] += bit_is_set (optimal_set [v ], allele );
4571
4567
}
4572
4568
}
4573
- max_allele_count = 0 ;
4574
- for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4575
- max_allele_count = TSK_MAX (max_allele_count , allele_count [allele ]);
4576
- }
4577
- for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4578
- if (allele_count [allele ] == max_allele_count ) {
4579
- optimal_root_set = set_bit (optimal_root_set , allele );
4569
+ /* the virtual root has no flags defined */
4570
+ if (u == (tsk_id_t ) N || !(node_flags [u ] & TSK_NODE_IS_SAMPLE )) {
4571
+ max_allele_count = 0 ;
4572
+ for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4573
+ max_allele_count = TSK_MAX (max_allele_count , allele_count [allele ]);
4574
+ }
4575
+ for (allele = 0 ; allele < num_alleles ; allele ++ ) {
4576
+ if (allele_count [allele ] == max_allele_count ) {
4577
+ optimal_set [u ] = set_bit (optimal_set [u ], allele );
4578
+ }
4580
4579
}
4581
4580
}
4582
- ancestral_state = get_smallest_set_bit (optimal_root_set );
4581
+ }
4582
+ if (!(options & TSK_MM_FIXED_ANCESTRAL_STATE )) {
4583
+ ancestral_state = get_smallest_set_bit (optimal_set [N ]);
4583
4584
}
4584
4585
4585
4586
num_transitions = 0 ;
@@ -4622,8 +4623,8 @@ tsk_tree_map_mutations(tsk_tree_t *self, int8_t *genotypes,
4622
4623
if (preorder_stack != NULL ) {
4623
4624
free (preorder_stack );
4624
4625
}
4625
- if (postorder_stack != NULL ) {
4626
- free (postorder_stack );
4626
+ if (nodes != NULL ) {
4627
+ free (nodes );
4627
4628
}
4628
4629
return ret ;
4629
4630
}
@@ -4888,7 +4889,7 @@ fill_kc_vectors(const tsk_tree_t *t, kc_vectors *kc_vecs)
4888
4889
int ret = 0 ;
4889
4890
const tsk_treeseq_t * ts = t -> tree_sequence ;
4890
4891
4891
- stack = tsk_malloc (t -> num_nodes * sizeof (* stack ));
4892
+ stack = tsk_malloc (tsk_tree_get_size_bound ( t ) * sizeof (* stack ));
4892
4893
if (stack == NULL ) {
4893
4894
ret = TSK_ERR_NO_MEMORY ;
4894
4895
goto out ;
@@ -5094,7 +5095,7 @@ update_kc_subtree_state(
5094
5095
tsk_id_t * stack = NULL ;
5095
5096
int ret = 0 ;
5096
5097
5097
- stack = tsk_malloc (t -> num_nodes * sizeof (* stack ));
5098
+ stack = tsk_malloc (tsk_tree_get_size_bound ( t ) * sizeof (* stack ));
5098
5099
if (stack == NULL ) {
5099
5100
ret = TSK_ERR_NO_MEMORY ;
5100
5101
goto out ;
0 commit comments