1
1
/*
2
2
* MIT License
3
3
*
4
- * Copyright (c) 2019-2023 Tskit Developers
4
+ * Copyright (c) 2019-2024 Tskit Developers
5
5
*
6
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
* of this software and associated documentation files (the "Software"), to deal
@@ -182,6 +182,8 @@ verify_tree_pos(const tsk_treeseq_t *ts, tsk_size_t num_trees, tsk_id_t *tree_pa
182
182
const tsk_size_t N = tsk_treeseq_get_num_nodes (ts );
183
183
const tsk_id_t * edges_parent = ts -> tables -> edges .parent ;
184
184
const tsk_id_t * edges_child = ts -> tables -> edges .child ;
185
+ const double * restrict edges_left = ts -> tables -> edges .left ;
186
+ const double * restrict edges_right = ts -> tables -> edges .right ;
185
187
tsk_tree_position_t tree_pos ;
186
188
tsk_id_t * known_parent ;
187
189
tsk_id_t * parent = tsk_malloc (N * sizeof (* parent ));
@@ -262,7 +264,62 @@ verify_tree_pos(const tsk_treeseq_t *ts, tsk_size_t num_trees, tsk_id_t *tree_pa
262
264
CU_ASSERT_EQUAL (parent [u ], TSK_NULL );
263
265
}
264
266
265
- tsk_tree_position_free (& tree_pos );
267
+ for (index = 0 ; index < (tsk_id_t ) num_trees ; index ++ ) {
268
+ known_parent = tree_parents + N * (tsk_size_t ) index ;
269
+ ret = tsk_tree_position_init (& tree_pos , ts , 0 );
270
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
271
+
272
+ ret = tsk_tree_position_seek_forward (& tree_pos , index );
273
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
274
+ CU_ASSERT_EQUAL (index , tree_pos .index );
275
+
276
+ for (j = tree_pos .in .start ; j != tree_pos .in .stop ; j ++ ) {
277
+ e = tree_pos .in .order [j ];
278
+ if (edges_left [e ] <= tree_pos .interval .left
279
+ && tree_pos .interval .left < edges_right [e ]) {
280
+ parent [edges_child [e ]] = edges_parent [e ];
281
+ }
282
+ }
283
+ for (u = 0 ; u < (tsk_id_t ) N ; u ++ ) {
284
+ CU_ASSERT_EQUAL (parent [u ], known_parent [u ]);
285
+ }
286
+
287
+ tsk_tree_position_free (& tree_pos );
288
+ for (u = 0 ; u < (tsk_id_t ) N ; u ++ ) {
289
+ parent [u ] = TSK_NULL ;
290
+ }
291
+ }
292
+
293
+ valid = tsk_tree_position_next (& tree_pos );
294
+ CU_ASSERT_FALSE (valid );
295
+
296
+ for (index = (tsk_id_t ) num_trees - 1 ; index >= 0 ; index -- ) {
297
+ known_parent = tree_parents + N * (tsk_size_t ) index ;
298
+ ret = tsk_tree_position_init (& tree_pos , ts , 0 );
299
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
300
+
301
+ ret = tsk_tree_position_seek_backward (& tree_pos , index );
302
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
303
+ CU_ASSERT_EQUAL (index , tree_pos .index );
304
+
305
+ for (j = tree_pos .in .start ; j != tree_pos .in .stop ; j -- ) {
306
+ e = tree_pos .in .order [j ];
307
+ if (edges_right [e ] >= tree_pos .interval .right
308
+ && tree_pos .interval .right > edges_left [e ]) {
309
+ parent [edges_child [e ]] = edges_parent [e ];
310
+ }
311
+ }
312
+
313
+ for (u = 0 ; u < (tsk_id_t ) N ; u ++ ) {
314
+ CU_ASSERT_EQUAL (parent [u ], known_parent [u ]);
315
+ }
316
+
317
+ for (u = 0 ; u < (tsk_id_t ) N ; u ++ ) {
318
+ parent [u ] = TSK_NULL ;
319
+ }
320
+ tsk_tree_position_free (& tree_pos );
321
+ }
322
+
266
323
tsk_safe_free (parent );
267
324
}
268
325
@@ -5350,6 +5407,7 @@ test_single_tree_tree_pos(void)
5350
5407
CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 0 );
5351
5408
CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 0 );
5352
5409
CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order );
5410
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5353
5411
5354
5412
valid = tsk_tree_position_next (& tree_pos );
5355
5413
CU_ASSERT_FATAL (!valid );
@@ -5360,6 +5418,7 @@ test_single_tree_tree_pos(void)
5360
5418
CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 0 );
5361
5419
CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 6 );
5362
5420
CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order );
5421
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5363
5422
5364
5423
valid = tsk_tree_position_prev (& tree_pos );
5365
5424
CU_ASSERT_FATAL (valid );
@@ -5372,6 +5431,7 @@ test_single_tree_tree_pos(void)
5372
5431
CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 5 );
5373
5432
CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 5 );
5374
5433
CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_insertion_order );
5434
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_REVERSE );
5375
5435
5376
5436
valid = tsk_tree_position_prev (& tree_pos );
5377
5437
CU_ASSERT_FATAL (!valid );
@@ -5380,6 +5440,42 @@ test_single_tree_tree_pos(void)
5380
5440
CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 5 );
5381
5441
CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , -1 );
5382
5442
CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_insertion_order );
5443
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_REVERSE );
5444
+
5445
+ ret = tsk_tree_position_seek_forward (& tree_pos , 0 );
5446
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
5447
+
5448
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .left , 0 );
5449
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .right , 1 );
5450
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .start , 0 );
5451
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .stop , 6 );
5452
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .order , ts .tables -> indexes .edge_insertion_order );
5453
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 0 );
5454
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 0 );
5455
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order )
5456
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5457
+
5458
+ valid = tsk_tree_position_next (& tree_pos );
5459
+ CU_ASSERT_FATAL (!valid );
5460
+
5461
+ CU_ASSERT_EQUAL_FATAL (tree_pos .index , -1 );
5462
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 0 );
5463
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 6 );
5464
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order );
5465
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5466
+
5467
+ ret = tsk_tree_position_seek_backward (& tree_pos , 0 );
5468
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
5469
+
5470
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .left , 0 );
5471
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .right , 1 );
5472
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .start , 5 );
5473
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .stop , -1 );
5474
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .order , ts .tables -> indexes .edge_removal_order );
5475
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 5 );
5476
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 5 );
5477
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_insertion_order );
5478
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_REVERSE );
5383
5479
5384
5480
tsk_tree_position_free (& tree_pos );
5385
5481
tsk_treeseq_free (& ts );
@@ -5409,6 +5505,110 @@ test_simple_multi_tree(void)
5409
5505
tsk_treeseq_free (& ts );
5410
5506
}
5411
5507
5508
+ static void
5509
+ test_multi_tree_direction_switching_tree_pos (void )
5510
+ {
5511
+ tsk_treeseq_t ts ;
5512
+ tsk_tree_position_t tree_pos ;
5513
+ bool valid ;
5514
+ int ret = 0 ;
5515
+
5516
+ tsk_treeseq_from_text (& ts , 10 , paper_ex_nodes , paper_ex_edges , NULL , paper_ex_sites ,
5517
+ paper_ex_mutations , paper_ex_individuals , NULL , 0 );
5518
+
5519
+ ret = tsk_tree_position_init (& tree_pos , & ts , 0 );
5520
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
5521
+ valid = tsk_tree_position_next (& tree_pos );
5522
+ CU_ASSERT_FATAL (valid );
5523
+
5524
+ CU_ASSERT_EQUAL_FATAL (tree_pos .index , 0 );
5525
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .left , 0 );
5526
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .right , 2 );
5527
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .start , 0 );
5528
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .stop , 6 );
5529
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .order , ts .tables -> indexes .edge_insertion_order );
5530
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 0 );
5531
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 0 );
5532
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order );
5533
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5534
+
5535
+ valid = tsk_tree_position_prev (& tree_pos );
5536
+ CU_ASSERT_FATAL (!valid );
5537
+
5538
+ CU_ASSERT_EQUAL_FATAL (tree_pos .index , -1 );
5539
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 5 );
5540
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , -1 );
5541
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_insertion_order );
5542
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_REVERSE );
5543
+
5544
+ valid = tsk_tree_position_prev (& tree_pos );
5545
+ CU_ASSERT_FATAL (valid );
5546
+
5547
+ CU_ASSERT_EQUAL_FATAL (tree_pos .index , 2 );
5548
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .left , 7 );
5549
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .right , 10 );
5550
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .start , 10 );
5551
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .stop , 4 );
5552
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .order , ts .tables -> indexes .edge_removal_order );
5553
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 10 );
5554
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 10 );
5555
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_insertion_order );
5556
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_REVERSE );
5557
+
5558
+ valid = tsk_tree_position_next (& tree_pos );
5559
+ CU_ASSERT_FATAL (!valid );
5560
+
5561
+ CU_ASSERT_EQUAL_FATAL (tree_pos .index , -1 );
5562
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 5 );
5563
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 11 );
5564
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order );
5565
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5566
+
5567
+ ret = tsk_tree_position_seek_forward (& tree_pos , 2 );
5568
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
5569
+
5570
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .left , 7 );
5571
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .right , 10 );
5572
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .start , 0 );
5573
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .stop , 11 );
5574
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .order , ts .tables -> indexes .edge_insertion_order );
5575
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 5 );
5576
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 5 );
5577
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order );
5578
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5579
+
5580
+ ret = tsk_tree_position_seek_backward (& tree_pos , 0 );
5581
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
5582
+
5583
+ CU_ASSERT_EQUAL_FATAL (tree_pos .index , 0 );
5584
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .left , 0 );
5585
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .right , 2 );
5586
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .start , 4 );
5587
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .stop , -1 );
5588
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .order , ts .tables -> indexes .edge_removal_order );
5589
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 10 );
5590
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 5 );
5591
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_insertion_order );
5592
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_REVERSE );
5593
+
5594
+ ret = tsk_tree_position_seek_forward (& tree_pos , 2 );
5595
+ CU_ASSERT_EQUAL_FATAL (ret , 0 );
5596
+
5597
+ CU_ASSERT_EQUAL_FATAL (tree_pos .index , 2 );
5598
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .left , 7 );
5599
+ CU_ASSERT_EQUAL_FATAL (tree_pos .interval .right , 10 );
5600
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .start , 6 );
5601
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .stop , 11 );
5602
+ CU_ASSERT_EQUAL_FATAL (tree_pos .in .order , ts .tables -> indexes .edge_insertion_order );
5603
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .start , 0 );
5604
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .stop , 5 );
5605
+ CU_ASSERT_EQUAL_FATAL (tree_pos .out .order , ts .tables -> indexes .edge_removal_order );
5606
+ CU_ASSERT_EQUAL_FATAL (tree_pos .direction , TSK_DIR_FORWARD );
5607
+
5608
+ tsk_tree_position_free (& tree_pos );
5609
+ tsk_treeseq_free (& ts );
5610
+ }
5611
+
5412
5612
static void
5413
5613
test_unary_multi_tree (void )
5414
5614
{
@@ -8501,6 +8701,8 @@ main(int argc, char **argv)
8501
8701
8502
8702
/* Multi tree tests */
8503
8703
{ "test_simple_multi_tree" , test_simple_multi_tree },
8704
+ { "test_multi_tree_direction_switching_tree_pos" ,
8705
+ test_multi_tree_direction_switching_tree_pos },
8504
8706
{ "test_nonbinary_multi_tree" , test_nonbinary_multi_tree },
8505
8707
{ "test_unary_multi_tree" , test_unary_multi_tree },
8506
8708
{ "test_internal_sample_multi_tree" , test_internal_sample_multi_tree },
0 commit comments