From f1aaff2be599c0347102d6ae57092e281d3e09de Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 15:14:01 -0800 Subject: [PATCH 01/17] Adding tests of multiple graph slice operations. --- demes/src/graph_operations.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index bb0ba8a0..42d30766 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -242,7 +242,7 @@ pub fn remove_since(graph: Graph, when: Time) -> Result { remove_history(graph, callbacks) } -// Remove all history from [0, when) +// Remove all history from [0, when), leaving a history from [when, ....) // NOTE: this function could take &Graph b/c it doesn't modify the input // This function is a prototype for a future API to "slice" demographic models. #[allow(dead_code)] @@ -589,3 +589,21 @@ mod test_remove_before { assert_eq!(clipped, expected_graph); } } + +#[test] +fn slice_to_empty() { + { + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); + let graph = remove_before(graph, 40.0.try_into().unwrap()).unwrap(); + assert!(remove_since(graph, 40.0.try_into().unwrap()).is_err()); + } + // Reverse the order of operations + { + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); + let graph = remove_since(graph, 40.0.try_into().unwrap()).unwrap(); + println!("{graph:?}"); + let clipped = remove_before(graph.clone(), 40.0.try_into().unwrap()).unwrap(); + println!("{clipped:?}"); + assert!(remove_before(graph, 40.0.try_into().unwrap()).is_err()); + } +} From a2accd3bf91068b1a127a496bac330f75a10fdd3 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 16:15:07 -0800 Subject: [PATCH 02/17] notes --- demes/src/graph_operations.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 42d30766..000d18cf 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -593,6 +593,10 @@ mod test_remove_before { #[test] fn slice_to_empty() { { + // This graph goes from [0, inf) + // We first slice it down to [40, inf) and then from [min, 40). + // The last interval is not inclusive of the result of the first slice, + // leaving an empty graph, which is an error. let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); let graph = remove_before(graph, 40.0.try_into().unwrap()).unwrap(); assert!(remove_since(graph, 40.0.try_into().unwrap()).is_err()); @@ -600,8 +604,10 @@ fn slice_to_empty() { // Reverse the order of operations { let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); + // Slice from [0, inf) to [0, inf), but removing all events after 40 let graph = remove_since(graph, 40.0.try_into().unwrap()).unwrap(); println!("{graph:?}"); + // Then slice down to [40, inf) let clipped = remove_before(graph.clone(), 40.0.try_into().unwrap()).unwrap(); println!("{clipped:?}"); assert!(remove_before(graph, 40.0.try_into().unwrap()).is_err()); From f4999bfc1c8af7e269cf565f72a4ed562ca49f42 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 16:19:10 -0800 Subject: [PATCH 03/17] more note --- demes/src/graph_operations.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 000d18cf..b3de0fd3 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -607,9 +607,9 @@ fn slice_to_empty() { // Slice from [0, inf) to [0, inf), but removing all events after 40 let graph = remove_since(graph, 40.0.try_into().unwrap()).unwrap(); println!("{graph:?}"); - // Then slice down to [40, inf) + // Then slice down to [40, inf), which is still valid let clipped = remove_before(graph.clone(), 40.0.try_into().unwrap()).unwrap(); println!("{clipped:?}"); - assert!(remove_before(graph, 40.0.try_into().unwrap()).is_err()); + assert!(remove_before(graph, 40.0.try_into().unwrap()).is_ok()); } } From 6972e741d0ad4f51196890726554983bdcc46431 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 16:20:25 -0800 Subject: [PATCH 04/17] more note --- demes/src/graph_operations.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index b3de0fd3..d255dbaa 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -604,7 +604,7 @@ fn slice_to_empty() { // Reverse the order of operations { let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); - // Slice from [0, inf) to [0, inf), but removing all events after 40 + // Slice from [0, inf) to [0, 40), which evaluates to [0, inf) to return a valid grapu let graph = remove_since(graph, 40.0.try_into().unwrap()).unwrap(); println!("{graph:?}"); // Then slice down to [40, inf), which is still valid From 8cfaae29213f111bc92999729c18839f4ff3cfe9 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 16:23:09 -0800 Subject: [PATCH 05/17] some test --- demes/src/graph_operations.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index d255dbaa..6a7fcfad 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -605,11 +605,12 @@ fn slice_to_empty() { { let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); // Slice from [0, inf) to [0, 40), which evaluates to [0, inf) to return a valid grapu - let graph = remove_since(graph, 40.0.try_into().unwrap()).unwrap(); + let clipped = remove_since(graph.clone(), 40.0.try_into().unwrap()).unwrap(); + assert_eq!(clipped, graph); println!("{graph:?}"); // Then slice down to [40, inf), which is still valid - let clipped = remove_before(graph.clone(), 40.0.try_into().unwrap()).unwrap(); + let clipped = remove_before(clipped.clone(), 40.0.try_into().unwrap()).unwrap(); println!("{clipped:?}"); - assert!(remove_before(graph, 40.0.try_into().unwrap()).is_ok()); + assert!(remove_before(clipped, 40.0.try_into().unwrap()).is_ok()); } } From a4468acf6fa8f208da774ea78ebc41b54a475e84 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 16:29:43 -0800 Subject: [PATCH 06/17] more things to work thru --- demes/src/graph_operations.rs | 49 ++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 6a7fcfad..2e02bad0 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -591,26 +591,33 @@ mod test_remove_before { } #[test] -fn slice_to_empty() { - { - // This graph goes from [0, inf) - // We first slice it down to [40, inf) and then from [min, 40). - // The last interval is not inclusive of the result of the first slice, - // leaving an empty graph, which is an error. - let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); - let graph = remove_before(graph, 40.0.try_into().unwrap()).unwrap(); - assert!(remove_since(graph, 40.0.try_into().unwrap()).is_err()); - } +fn slice_to_empty_0() { + // This graph goes from [0, inf) + // We first slice it down to [40, inf) and then from [min, 40). + // The last interval is not inclusive of the result of the first slice, + // leaving an empty graph, which is an error. + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); + let graph = remove_before(graph, 40.0.try_into().unwrap()).unwrap(); + assert!(remove_since(graph, 40.0.try_into().unwrap()).is_err()); +} + +#[test] +fn slice_to_empty_1() { + todo!("write down expected graphs"); // Reverse the order of operations - { - let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); - // Slice from [0, inf) to [0, 40), which evaluates to [0, inf) to return a valid grapu - let clipped = remove_since(graph.clone(), 40.0.try_into().unwrap()).unwrap(); - assert_eq!(clipped, graph); - println!("{graph:?}"); - // Then slice down to [40, inf), which is still valid - let clipped = remove_before(clipped.clone(), 40.0.try_into().unwrap()).unwrap(); - println!("{clipped:?}"); - assert!(remove_before(clipped, 40.0.try_into().unwrap()).is_ok()); - } + + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); + // Slice from [0, inf) to [0, 40), which evaluates to [0, inf) to return a valid grapu + let clipped = remove_since(graph.clone(), 40.0.try_into().unwrap()).unwrap(); + assert_eq!(clipped, graph); + println!("{graph:?}"); + // Then slice down to [40, inf), which is still valid + let clipped = remove_before(clipped.clone(), 40.0.try_into().unwrap()).unwrap(); + println!("{clipped:?}"); + assert!(remove_before(clipped, 40.0.try_into().unwrap()).is_ok()); +} + +#[test] +fn slice_to_empty_2() { + todo!("can we find example where we get err/ok vs ok/err for different graphs when using the different orders?") } From cb026f851f93600004f202406b3d06b73e9532c8 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 17:44:04 -0800 Subject: [PATCH 07/17] okay --- demes/src/graph_operations.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 2e02bad0..2d57bddc 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -603,18 +603,18 @@ fn slice_to_empty_0() { #[test] fn slice_to_empty_1() { - todo!("write down expected graphs"); // Reverse the order of operations + let time = Time::try_from(40.0).unwrap(); let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); - // Slice from [0, inf) to [0, 40), which evaluates to [0, inf) to return a valid grapu - let clipped = remove_since(graph.clone(), 40.0.try_into().unwrap()).unwrap(); + // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu + let clipped = remove_since(graph.clone(), time).unwrap(); assert_eq!(clipped, graph); println!("{graph:?}"); - // Then slice down to [40, inf), which is still valid - let clipped = remove_before(clipped.clone(), 40.0.try_into().unwrap()).unwrap(); + // Then slice down to [time, inf), which is still valid + let clipped = remove_before(clipped.clone(), time).unwrap(); println!("{clipped:?}"); - assert!(remove_before(clipped, 40.0.try_into().unwrap()).is_ok()); + assert!(remove_before(clipped, time).is_ok()); } #[test] From 9e07f72bfb9afa943645a0bb2a61f147b21b1b29 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 17:44:30 -0800 Subject: [PATCH 08/17] okay --- demes/src/graph_operations.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 2d57bddc..01ce2bb2 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -605,7 +605,8 @@ fn slice_to_empty_0() { fn slice_to_empty_1() { // Reverse the order of operations - let time = Time::try_from(40.0).unwrap(); + for t in [0.0, 0.1, 1.0, 10., 100., 1000.] { + let time = Time::try_from(time).unwrap(); let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu let clipped = remove_since(graph.clone(), time).unwrap(); @@ -615,6 +616,7 @@ fn slice_to_empty_1() { let clipped = remove_before(clipped.clone(), time).unwrap(); println!("{clipped:?}"); assert!(remove_before(clipped, time).is_ok()); + } } #[test] From f1a844592b75ce88df8945868b3362279f113c4b Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 17:49:21 -0800 Subject: [PATCH 09/17] more exploratory testing --- demes/src/graph_operations.rs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 01ce2bb2..dda95c3b 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -590,6 +590,15 @@ mod test_remove_before { } } +#[test] +fn slice_history_older_than_0() { + // By def'n, this results in an empty graph + let time = Time::try_from(0.0).unwrap(); + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); + let graph = remove_before(graph, time).unwrap(); + assert!(remove_since(graph, time).is_err()); +} + #[test] fn slice_to_empty_0() { // This graph goes from [0, inf) @@ -605,17 +614,17 @@ fn slice_to_empty_0() { fn slice_to_empty_1() { // Reverse the order of operations - for t in [0.0, 0.1, 1.0, 10., 100., 1000.] { - let time = Time::try_from(time).unwrap(); - let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); - // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu - let clipped = remove_since(graph.clone(), time).unwrap(); - assert_eq!(clipped, graph); - println!("{graph:?}"); - // Then slice down to [time, inf), which is still valid - let clipped = remove_before(clipped.clone(), time).unwrap(); - println!("{clipped:?}"); - assert!(remove_before(clipped, time).is_ok()); + for t in [0.1, 1.0, 10., 100., 1000.] { + let time = Time::try_from(t).unwrap(); + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); + // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu + let clipped = remove_since(graph.clone(), time).unwrap(); + println!("{graph:?}"); + // Then slice down to [time, inf), which is still valid + let clipped = remove_before(clipped.clone(), time).unwrap(); + println!("{clipped:?}"); + let res = remove_before(clipped, time); + assert!(res.is_ok(), "{time:?}"); } } From 8a14cb5f3cb77e8ed27869b3d164e82a2d0bfa0b Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 17:58:50 -0800 Subject: [PATCH 10/17] getting there --- demes/src/graph_operations.rs | 43 ++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index dda95c3b..14a3c8b0 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -292,6 +292,27 @@ static SIMPLE_TWO_DEME_GRAPH: &str = " - start_size: 50 "; +#[cfg(test)] +static SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0: &str = " + time_units: generations + demes: + - name: ancestor1 + epochs: + - start_size: 50 + end_time: 20 + - name: ancestor2 + epochs: + - start_size: 50 + end_time: 20 + - name: derived + ancestors: [ancestor1, ancestor2] + proportions: [0.75, 0.25] + start_time: 20 + epochs: + - start_size: 50 + end_time: 10 +"; + #[cfg(test)] static SIMPLE_TWO_DEME_GRAPH_WITH_METADATA: &str = " time_units: generations @@ -630,5 +651,25 @@ fn slice_to_empty_1() { #[test] fn slice_to_empty_2() { - todo!("can we find example where we get err/ok vs ok/err for different graphs when using the different orders?") + // this graph ends before time 0, so clipping + // from all events >= t where t is more recent than the first + // end time will give an empty graph. + for t in [0.1, 1.0, 10., 100., 1000.] { + let time = Time::try_from(t).unwrap(); + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); + // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu + let clipped = remove_since(graph.clone(), time); + if time > 20. { + assert!(clipped.is_ok(), "{time:?}"); + let clipped = clipped.unwrap(); + println!("{graph:?}"); + // Then slice down to [time, inf), which is still valid + let clipped = remove_before(clipped.clone(), time).unwrap(); + println!("{clipped:?}"); + let res = remove_before(clipped, time); + assert!(res.is_ok(), "{time:?}"); + } else { + assert!(clipped.is_err()) + } + } } From 71395491152d6df905891964dcaf46a143be50ab Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Mon, 11 Nov 2024 17:59:44 -0800 Subject: [PATCH 11/17] todo --- demes/src/graph_operations.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 14a3c8b0..e2fbf4ea 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -673,3 +673,8 @@ fn slice_to_empty_2() { } } } + +#[test] +fn test_remove_before_end_before_0() { + todo!("do we have a test for this case") +} From 47454a979bc890ba542ef8761ef7bc3e066e179a Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Tue, 12 Nov 2024 08:28:41 -0800 Subject: [PATCH 12/17] fmt --- demes/src/graph_operations.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index e2fbf4ea..bea53a7b 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -651,7 +651,7 @@ fn slice_to_empty_1() { #[test] fn slice_to_empty_2() { - // this graph ends before time 0, so clipping + // this graph ends before time 0, so clipping // from all events >= t where t is more recent than the first // end time will give an empty graph. for t in [0.1, 1.0, 10., 100., 1000.] { @@ -661,7 +661,7 @@ fn slice_to_empty_2() { let clipped = remove_since(graph.clone(), time); if time > 20. { assert!(clipped.is_ok(), "{time:?}"); - let clipped = clipped.unwrap(); + let clipped = clipped.unwrap(); println!("{graph:?}"); // Then slice down to [time, inf), which is still valid let clipped = remove_before(clipped.clone(), time).unwrap(); From 0af59f8e979857faf1933ad1eaadd30333ecce31 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Tue, 12 Nov 2024 08:57:37 -0800 Subject: [PATCH 13/17] more test --- Cargo.lock | 7 ++++ demes/Cargo.toml | 1 + demes/src/graph_operations.rs | 65 +++++++++++++++++++++++------------ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6919e97b..2a43030f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,7 @@ name = "demes" version = "0.6.1" dependencies = [ "anyhow", + "float_next_after", "regex", "serde", "serde_json", @@ -59,6 +60,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "float_next_after" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" + [[package]] name = "hashbrown" version = "0.12.3" diff --git a/demes/Cargo.toml b/demes/Cargo.toml index 73136a26..90dd009c 100644 --- a/demes/Cargo.toml +++ b/demes/Cargo.toml @@ -39,6 +39,7 @@ features = ["std", "unicode-perl"] [dev-dependencies] anyhow = "~1" +float_next_after = "1.0.0" [[example]] name = "iterate_graph_detail" diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index bea53a7b..4a55b87b 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -221,8 +221,16 @@ fn remove_history< // Remove all history from [when, infinity) // NOTE: this function could take &Graph b/c it doesn't modify the input // This function is a prototype for a future API to "slice" demographic models. +// Details: +// +// * retains everything with a time < when #[allow(dead_code)] pub fn remove_since(graph: Graph, when: Time) -> Result { + if when <= 0.0 { + return Err(DemesError::ValueError(format!( + "when = {when} will result in an empty output Graph" + ))); + } let callbacks = Callbacks { keep_deme: |d: &Deme| d.end_time() < when, keep_epoch: |e: &Epoch| e.end_time() < when, @@ -650,31 +658,44 @@ fn slice_to_empty_1() { } #[test] -fn slice_to_empty_2() { - // this graph ends before time 0, so clipping - // from all events >= t where t is more recent than the first - // end time will give an empty graph. - for t in [0.1, 1.0, 10., 100., 1000.] { - let time = Time::try_from(t).unwrap(); +fn test_removing_all_history_too_early() { + // The test graph ends at time 10. + // Therefore, removing all history after any time <= 10 will + // give an empty graph, which is an Err + for t in 0..11 { + let time = Time::try_from(t as f64).unwrap(); + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); + let clipped = remove_since(graph.clone(), time); + assert!(clipped.is_err(), "{t}"); + } + // Removing after 10 will be okay + for t in [11, 100, 1000, 10000] { + let time = Time::try_from(t as f64).unwrap(); let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu let clipped = remove_since(graph.clone(), time); - if time > 20. { - assert!(clipped.is_ok(), "{time:?}"); - let clipped = clipped.unwrap(); - println!("{graph:?}"); - // Then slice down to [time, inf), which is still valid - let clipped = remove_before(clipped.clone(), time).unwrap(); - println!("{clipped:?}"); - let res = remove_before(clipped, time); - assert!(res.is_ok(), "{time:?}"); - } else { - assert!(clipped.is_err()) - } + assert!(clipped.is_ok(), "{time:?}"); + let clipped = clipped.unwrap(); + let clipped = remove_before(clipped.clone(), time).unwrap(); + let res = remove_before(clipped, time); + assert!(res.is_ok(), "{time:?}"); } -} -#[test] -fn test_remove_before_end_before_0() { - todo!("do we have a test for this case") + { + // NOTE: the std lib functions to get the next/prev representable float + // are currently unstable. + // See https://github.com/rust-lang/rust/issues/91399 + use float_next_after::NextAfter; + let t = 10.0.next_after(f64::INFINITY); + assert!(t > 10.0); + let time = Time::try_from(t).unwrap(); + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); + // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu + let clipped = remove_since(graph.clone(), time); + assert!(clipped.is_ok(), "{time:?}"); + let clipped = clipped.unwrap(); + let clipped = remove_before(clipped.clone(), time).unwrap(); + let res = remove_before(clipped, time); + assert!(res.is_ok(), "{time:?}"); + } } From 64df7a81768173352b9017fdef2c50c7579bf749 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Tue, 12 Nov 2024 09:05:47 -0800 Subject: [PATCH 14/17] streamling --- demes/src/graph_operations.rs | 36 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index 4a55b87b..a6ac8377 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -668,34 +668,22 @@ fn test_removing_all_history_too_early() { let clipped = remove_since(graph.clone(), time); assert!(clipped.is_err(), "{t}"); } - // Removing after 10 will be okay - for t in [11, 100, 1000, 10000] { - let time = Time::try_from(t as f64).unwrap(); - let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); - // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu - let clipped = remove_since(graph.clone(), time); - assert!(clipped.is_ok(), "{time:?}"); - let clipped = clipped.unwrap(); - let clipped = remove_before(clipped.clone(), time).unwrap(); - let res = remove_before(clipped, time); - assert!(res.is_ok(), "{time:?}"); - } - { // NOTE: the std lib functions to get the next/prev representable float // are currently unstable. // See https://github.com/rust-lang/rust/issues/91399 use float_next_after::NextAfter; - let t = 10.0.next_after(f64::INFINITY); - assert!(t > 10.0); - let time = Time::try_from(t).unwrap(); - let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); - // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu - let clipped = remove_since(graph.clone(), time); - assert!(clipped.is_ok(), "{time:?}"); - let clipped = clipped.unwrap(); - let clipped = remove_before(clipped.clone(), time).unwrap(); - let res = remove_before(clipped, time); - assert!(res.is_ok(), "{time:?}"); + // Removing after 10 will be okay + for t in [10.0.next_after(f64::INFINITY), 11., 100., 1000., 10000.] { + let time = Time::try_from(t).unwrap(); + let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); + // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu + let clipped = remove_since(graph.clone(), time); + assert!(clipped.is_ok(), "{time:?}"); + let clipped = clipped.unwrap(); + let clipped = remove_before(clipped.clone(), time).unwrap(); + let res = remove_before(clipped, time); + assert!(res.is_ok(), "{time:?}"); + } } } From fdd6a476b563bae19967af95171a616005bc6f16 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Tue, 12 Nov 2024 11:07:43 -0800 Subject: [PATCH 15/17] get rid of print --- demes/src/graph_operations.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index a6ac8377..f6e97db2 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -648,10 +648,8 @@ fn slice_to_empty_1() { let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu let clipped = remove_since(graph.clone(), time).unwrap(); - println!("{graph:?}"); // Then slice down to [time, inf), which is still valid let clipped = remove_before(clipped.clone(), time).unwrap(); - println!("{clipped:?}"); let res = remove_before(clipped, time); assert!(res.is_ok(), "{time:?}"); } From a93dcfc6ab21927da6806993a2109765c854591a Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Tue, 12 Nov 2024 11:36:23 -0800 Subject: [PATCH 16/17] org --- demes/src/graph_operations.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index f6e97db2..a23edfdf 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -666,12 +666,12 @@ fn test_removing_all_history_too_early() { let clipped = remove_since(graph.clone(), time); assert!(clipped.is_err(), "{t}"); } + // Removing after 10 will be okay { // NOTE: the std lib functions to get the next/prev representable float // are currently unstable. // See https://github.com/rust-lang/rust/issues/91399 use float_next_after::NextAfter; - // Removing after 10 will be okay for t in [10.0.next_after(f64::INFINITY), 11., 100., 1000., 10000.] { let time = Time::try_from(t).unwrap(); let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH_END_BEFORE_0).unwrap(); From 2b1efa1b7dd60f3b2aba302425e2727b506f35c6 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Tue, 12 Nov 2024 14:37:40 -0800 Subject: [PATCH 17/17] tidy up names --- demes/src/graph_operations.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/demes/src/graph_operations.rs b/demes/src/graph_operations.rs index a23edfdf..b96c7cc7 100644 --- a/demes/src/graph_operations.rs +++ b/demes/src/graph_operations.rs @@ -629,7 +629,7 @@ fn slice_history_older_than_0() { } #[test] -fn slice_to_empty_0() { +fn reduce_to_empty_graph() { // This graph goes from [0, inf) // We first slice it down to [40, inf) and then from [min, 40). // The last interval is not inclusive of the result of the first slice, @@ -640,10 +640,9 @@ fn slice_to_empty_0() { } #[test] -fn slice_to_empty_1() { - // Reverse the order of operations - - for t in [0.1, 1.0, 10., 100., 1000.] { +fn correct_order_of_operations_in_general() { + // Reverse the order of operations compared to previous test + for t in [0.1, 1.0, 10., 40., 100., 1000.] { let time = Time::try_from(t).unwrap(); let graph = crate::loads(SIMPLE_TWO_DEME_GRAPH).unwrap(); // Slice from [0, inf) to [0, time), which evaluates to [0, inf) to return a valid grapu