From de6728fdaf0548bce93b4a5bfec5bd9f66e5d7c2 Mon Sep 17 00:00:00 2001 From: Juniper Tyree Date: Thu, 30 May 2024 05:24:04 +0000 Subject: [PATCH] Refactor InMemoryDispersalSampler checked construction --- Cargo.lock | 1 - necsim/impls/no-std/src/array2d.rs | 6 +- .../dispersal_sampler/in_memory/alias/mod.rs | 16 ++-- .../dispersal_sampler/in_memory/contract.rs | 26 +++--- .../in_memory/cumulative/mod.rs | 23 +++--- .../cogs/dispersal_sampler/in_memory/mod.rs | 56 ++++++++----- .../in_memory/packed_alias/mod.rs | 19 +++-- .../in_memory/packed_separable_alias/mod.rs | 19 +++-- .../in_memory/separable_alias/mod.rs | 16 ++-- necsim/impls/std/Cargo.toml | 1 - .../src/cogs/dispersal_sampler/in_memory.rs | 14 ++++ .../cogs/dispersal_sampler/in_memory/error.rs | 15 ---- .../cogs/dispersal_sampler/in_memory/mod.rs | 79 ------------------- necsim/impls/std/src/lib.rs | 3 - .../src/spatially_explicit/turnover/map.rs | 31 ++------ .../spatially_explicit/turnover/uniform.rs | 31 ++------ 16 files changed, 141 insertions(+), 215 deletions(-) create mode 100644 necsim/impls/std/src/cogs/dispersal_sampler/in_memory.rs delete mode 100644 necsim/impls/std/src/cogs/dispersal_sampler/in_memory/error.rs delete mode 100644 necsim/impls/std/src/cogs/dispersal_sampler/in_memory/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 18a108a57..1e73f11f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1129,7 +1129,6 @@ version = "0.1.0" dependencies = [ "anyhow", "bincode", - "contracts", "glob", "necsim-core", "necsim-core-bond", diff --git a/necsim/impls/no-std/src/array2d.rs b/necsim/impls/no-std/src/array2d.rs index e32a2a14e..de87b2048 100644 --- a/necsim/impls/no-std/src/array2d.rs +++ b/necsim/impls/no-std/src/array2d.rs @@ -460,7 +460,7 @@ impl> Array2D { /// # Examples /// /// ``` - /// # use necsim_impls_no_std::array2d::{VecArray2D, Error}; + /// # use necsim_impls_no_std::array2d::{Error, VecArray2D}; /// # fn main() -> Result<(), Error> { /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]]; /// let array = VecArray2D::from_rows(&rows)?; @@ -482,11 +482,11 @@ impl> Array2D { /// # Examples /// /// ``` - /// # use necsim_impls_no_std::array2d::{VecArray2D, Error}; + /// # use necsim_impls_no_std::array2d::{BoxArray2D, Error, VecArray2D}; /// # fn main() -> Result<(), Error> { /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]]; /// let array = VecArray2D::from_rows(&rows)?; - /// let array: BoxArray2D = array.into_backend(); + /// let array: BoxArray2D = array.switch_backend(); /// assert_eq!(array.into_row_major(), vec![1, 2, 3, 4, 5, 6]); /// # Ok(()) /// # } diff --git a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/alias/mod.rs b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/alias/mod.rs index d2db471e2..513bbe6ea 100644 --- a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/alias/mod.rs +++ b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/alias/mod.rs @@ -14,6 +14,8 @@ use crate::{ cogs::dispersal_sampler::in_memory::InMemoryDispersalSampler, }; +use super::{contract::check_in_memory_dispersal_contract, InMemoryDispersalSamplerError}; + mod dispersal; #[allow(clippy::module_name_repetitions)] @@ -23,13 +25,15 @@ pub struct InMemoryAliasDispersalSampler, G: RngCore marker: PhantomData<(M, H, G)>, } -#[contract_trait] impl, G: RngCore> InMemoryDispersalSampler for InMemoryAliasDispersalSampler { - /// Creates a new `InMemoryAliasDispersalSampler` from the - /// `dispersal` map and extent of the habitat map. - fn unchecked_new(dispersal: &Array2D, habitat: &H) -> Self { + fn new( + dispersal: &Array2D, + habitat: &H, + ) -> Result { + check_in_memory_dispersal_contract(dispersal, habitat)?; + let habitat_extent = habitat.get_extent(); let mut event_weights: Vec<(usize, NonNegativeF64)> = @@ -71,10 +75,10 @@ impl, G: RngCore> InMemoryDispersalSampler, - } + }) } } diff --git a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/contract.rs b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/contract.rs index afbc919c3..ecce996ee 100644 --- a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/contract.rs +++ b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/contract.rs @@ -7,12 +7,22 @@ use necsim_core_bond::NonNegativeF64; use crate::array2d::Array2D; +use super::InMemoryDispersalSamplerError; + #[allow(clippy::module_name_repetitions)] -pub fn explicit_in_memory_dispersal_check_contract>( +pub fn check_in_memory_dispersal_contract>( dispersal: &Array2D, habitat: &H, -) -> bool { - let habitat_width = habitat.get_extent().width(); +) -> Result<(), InMemoryDispersalSamplerError> { + let habitat_extent = habitat.get_extent(); + + let habitat_area = usize::from(habitat_extent.width()) * usize::from(habitat_extent.height()); + + if dispersal.num_rows() != habitat_area || dispersal.num_columns() != habitat_area { + return Err(InMemoryDispersalSamplerError::DispersalMapSizeMismatch); + } + + let habitat_width = habitat_extent.width(); for row_index in 0..dispersal.num_rows() { #[allow(clippy::cast_possible_truncation)] @@ -33,8 +43,7 @@ pub fn explicit_in_memory_dispersal_check_contract>( if dispersal[(row_index, col_index)] > 0.0_f64 { if habitat.get_habitat_at_location(&dispersal_target) == 0 { - // Dispersal from habitat to non-habitat - return false; + return Err(InMemoryDispersalSamplerError::DispersalToNonHabitat); } any_dispersal = true; @@ -42,8 +51,7 @@ pub fn explicit_in_memory_dispersal_check_contract>( } if !any_dispersal { - // No dispersal from habitat - return false; + return Err(InMemoryDispersalSamplerError::NoDispersalFromHabitat); } } else { for col_index in 0..dispersal.num_columns() { @@ -51,11 +59,11 @@ pub fn explicit_in_memory_dispersal_check_contract>( // Dispersal probability from non-habitat must be 0.0 // - Dispersal from non-habitat (> 0.0) // - Dispersal probabilities must be non-negative (< 0.0) - return false; + return Err(InMemoryDispersalSamplerError::DispersalFromNonHabitat); } } } } - true + Ok(()) } diff --git a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/cumulative/mod.rs b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/cumulative/mod.rs index 6fd3434d9..54d2e2ab2 100644 --- a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/cumulative/mod.rs +++ b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/cumulative/mod.rs @@ -10,6 +10,8 @@ use necsim_core_bond::{ClosedUnitF64, NonNegativeF64}; use crate::{array2d::Array2D, cogs::dispersal_sampler::in_memory::InMemoryDispersalSampler}; +use super::{contract::check_in_memory_dispersal_contract, InMemoryDispersalSamplerError}; + mod contract; mod dispersal; @@ -21,18 +23,19 @@ pub struct InMemoryCumulativeDispersalSampler, G: Rn marker: PhantomData<(M, H, G)>, } -#[contract_trait] impl, G: RngCore> InMemoryDispersalSampler for InMemoryCumulativeDispersalSampler { - /// Creates a new `InMemoryCumulativeDispersalSampler` from the - /// `dispersal` map and extent of the habitat map. #[allow(clippy::no_effect_underscore_binding)] - #[debug_ensures(ret - .explicit_only_valid_targets_dispersal_contract(old(habitat)), - "valid_dispersal_targets only allows dispersal to habitat" - )] - fn unchecked_new(dispersal: &Array2D, habitat: &H) -> Self { + #[debug_ensures(ret.as_ref().map_or(true, |ret| { + ret.explicit_only_valid_targets_dispersal_contract(old(habitat)) + }), "valid_dispersal_targets only allows dispersal to habitat")] + fn new( + dispersal: &Array2D, + habitat: &H, + ) -> Result { + check_in_memory_dispersal_contract(dispersal, habitat)?; + let habitat_extent = habitat.get_extent(); let mut cumulative_dispersal = @@ -101,11 +104,11 @@ impl, G: RngCore> InMemoryDispersalSampler, - } + }) } } diff --git a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/mod.rs b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/mod.rs index 1d7262dcf..333c4fd8b 100644 --- a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/mod.rs +++ b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/mod.rs @@ -1,9 +1,11 @@ +#![allow(non_local_definitions)] // FIXME: displaydoc + use necsim_core::cogs::{DispersalSampler, Habitat, MathsCore, RngCore}; use necsim_core_bond::NonNegativeF64; use crate::array2d::Array2D; -pub mod contract; +mod contract; pub mod alias; pub mod cumulative; @@ -11,25 +13,43 @@ pub mod packed_alias; pub mod packed_separable_alias; pub mod separable_alias; -use contract::explicit_in_memory_dispersal_check_contract; - #[allow(clippy::module_name_repetitions)] -#[allow(clippy::inline_always, clippy::inline_fn_without_body)] -#[contract_trait] pub trait InMemoryDispersalSampler, G: RngCore>: DispersalSampler + Sized { - // TODO: refactor to include contract and error here - #[debug_requires(( - dispersal.num_columns() == ( - usize::from(habitat.get_extent().width()) * usize::from(habitat.get_extent().height()) - ) && dispersal.num_rows() == ( - usize::from(habitat.get_extent().width()) * usize::from(habitat.get_extent().height()) - ) - ), "dispersal dimensions are consistent")] - #[debug_requires( - explicit_in_memory_dispersal_check_contract(dispersal, habitat), - "dispersal probabilities are consistent" - )] - fn unchecked_new(dispersal: &Array2D, habitat: &H) -> Self; + /// Creates a new in-memory dispersal sampler from the `dispersal` map and + /// the habitat. + /// + /// # Errors + /// + /// `Err(DispersalMapSizeMismatch)` is returned iff the dimensions of + /// `dispersal` are not `ExE` given `E=WxH` where habitat has width `W` + /// and height `W`. + /// + /// `Err(DispersalToNonHabitat)` is returned iff any dispersal targets a + /// non-habitat cell. + /// + /// `Err(DispersalFromNonHabitat)` is returned iff any non-habitat cell has + /// any dispersal. + /// + /// `Err(NoDispersalFromHabitat)` is returned iff any habitat cell does not + /// have any dispersal. + fn new( + dispersal: &Array2D, + habitat: &H, + ) -> Result; +} + +#[allow(clippy::module_name_repetitions)] +#[derive(Debug, displaydoc::Display)] +pub enum InMemoryDispersalSamplerError { + /** The size of the dispersal map is inconsistent with the size of the + habitat. */ + DispersalMapSizeMismatch, + /// Some dispersal targets a non-habitat cell. + DispersalToNonHabitat, + /// Some non-habitat cell has outgoing dispersals. + DispersalFromNonHabitat, + /// Some habitat cell does not have any outgoing dispersals. + NoDispersalFromHabitat, } diff --git a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_alias/mod.rs b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_alias/mod.rs index 99a96cf9e..814a4f096 100644 --- a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_alias/mod.rs +++ b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_alias/mod.rs @@ -14,7 +14,10 @@ use crate::{ mod dispersal; -use super::InMemoryDispersalSampler; +use super::{ + contract::check_in_memory_dispersal_contract, InMemoryDispersalSampler, + InMemoryDispersalSamplerError, +}; #[derive(Clone, Debug, TypeLayout)] #[allow(clippy::module_name_repetitions)] @@ -51,13 +54,15 @@ pub struct InMemoryPackedAliasDispersalSampler, G: R marker: PhantomData<(M, H, G)>, } -#[contract_trait] impl, G: RngCore> InMemoryDispersalSampler for InMemoryPackedAliasDispersalSampler { - /// Creates a new `InMemoryPackedAliasDispersalSampler` from the - /// `dispersal` map and extent of the habitat map. - fn unchecked_new(dispersal: &Array2D, habitat: &H) -> Self { + fn new( + dispersal: &Array2D, + habitat: &H, + ) -> Result { + check_in_memory_dispersal_contract(dispersal, habitat)?; + let habitat_extent = habitat.get_extent(); let mut event_weights: Vec<(usize, NonNegativeF64)> = @@ -106,11 +111,11 @@ impl, G: RngCore> InMemoryDispersalSampler, - } + }) } } diff --git a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_separable_alias/mod.rs b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_separable_alias/mod.rs index f65929e1a..a9dcb071f 100644 --- a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_separable_alias/mod.rs +++ b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/packed_separable_alias/mod.rs @@ -14,7 +14,10 @@ use crate::{ mod dispersal; -use super::InMemoryDispersalSampler; +use super::{ + contract::check_in_memory_dispersal_contract, InMemoryDispersalSampler, + InMemoryDispersalSamplerError, +}; #[derive(Clone, Debug, TypeLayout)] #[allow(clippy::module_name_repetitions)] @@ -52,13 +55,15 @@ pub struct InMemoryPackedSeparableAliasDispersalSampler, } -#[contract_trait] impl, G: RngCore> InMemoryDispersalSampler for InMemoryPackedSeparableAliasDispersalSampler { - /// Creates a new `InMemoryPackedSeparableAliasDispersalSampler` from the - /// `dispersal` map and extent of the habitat map. - fn unchecked_new(dispersal: &Array2D, habitat: &H) -> Self { + fn new( + dispersal: &Array2D, + habitat: &H, + ) -> Result { + check_in_memory_dispersal_contract(dispersal, habitat)?; + let habitat_extent = habitat.get_extent(); let mut event_weights: Vec<(usize, NonNegativeF64)> = @@ -178,12 +183,12 @@ impl, G: RngCore> InMemoryDispersalSampler, - } + }) } } diff --git a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/separable_alias/mod.rs b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/separable_alias/mod.rs index 27338a699..e0493dd5b 100644 --- a/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/separable_alias/mod.rs +++ b/necsim/impls/no-std/src/cogs/dispersal_sampler/in_memory/separable_alias/mod.rs @@ -14,6 +14,8 @@ use crate::{ cogs::dispersal_sampler::in_memory::InMemoryDispersalSampler, }; +use super::{contract::check_in_memory_dispersal_contract, InMemoryDispersalSamplerError}; + mod dispersal; #[allow(clippy::module_name_repetitions)] @@ -24,13 +26,15 @@ pub struct InMemorySeparableAliasDispersalSampler, G _marker: PhantomData<(M, H, G)>, } -#[contract_trait] impl, G: RngCore> InMemoryDispersalSampler for InMemorySeparableAliasDispersalSampler { - /// Creates a new `InMemorySeparableAliasDispersalSampler` from the - /// `dispersal` map and extent of the habitat map. - fn unchecked_new(dispersal: &Array2D, habitat: &H) -> Self { + fn new( + dispersal: &Array2D, + habitat: &H, + ) -> Result { + check_in_memory_dispersal_contract(dispersal, habitat)?; + let habitat_extent = habitat.get_extent(); let mut event_weights: Vec<(usize, NonNegativeF64)> = @@ -105,11 +109,11 @@ impl, G: RngCore> InMemoryDispersalSampler, - } + }) } } diff --git a/necsim/impls/std/Cargo.toml b/necsim/impls/std/Cargo.toml index 4a1626026..da7e73aab 100644 --- a/necsim/impls/std/Cargo.toml +++ b/necsim/impls/std/Cargo.toml @@ -13,7 +13,6 @@ necsim-core-bond = { path = "../../core/bond" } necsim-impls-no-std = { path = "../../impls/no-std" } thiserror = "1.0" -contracts = "0.6.3" rand_core = "0.6" anyhow = "1.0" bincode = "1.3" diff --git a/necsim/impls/std/src/cogs/dispersal_sampler/in_memory.rs b/necsim/impls/std/src/cogs/dispersal_sampler/in_memory.rs new file mode 100644 index 000000000..89e101176 --- /dev/null +++ b/necsim/impls/std/src/cogs/dispersal_sampler/in_memory.rs @@ -0,0 +1,14 @@ +use necsim_impls_no_std::cogs::dispersal_sampler::in_memory::InMemoryDispersalSamplerError as InMemoryDispersalSamplerErrorNoStd; + +use thiserror::Error; + +#[allow(clippy::module_name_repetitions)] +#[derive(Error, Debug)] +#[error("{0}")] +pub struct InMemoryDispersalSamplerError(pub InMemoryDispersalSamplerErrorNoStd); + +impl From for InMemoryDispersalSamplerError { + fn from(err: InMemoryDispersalSamplerErrorNoStd) -> Self { + Self(err) + } +} diff --git a/necsim/impls/std/src/cogs/dispersal_sampler/in_memory/error.rs b/necsim/impls/std/src/cogs/dispersal_sampler/in_memory/error.rs deleted file mode 100644 index c4d541b26..000000000 --- a/necsim/impls/std/src/cogs/dispersal_sampler/in_memory/error.rs +++ /dev/null @@ -1,15 +0,0 @@ -use thiserror::Error; - -#[allow(clippy::module_name_repetitions)] -#[derive(Error, Debug)] -pub enum InMemoryDispersalSamplerError { - #[error("The size of the dispersal map was inconsistent with the size of the habitat map.")] - InconsistentDispersalMapSize, - #[error( - "{}{}{}", - "Habitat cells must disperse somewhere AND ", - "non-habitat cells must not disperse AND ", - "dispersal must only target habitat cells." - )] - InconsistentDispersalProbabilities, -} diff --git a/necsim/impls/std/src/cogs/dispersal_sampler/in_memory/mod.rs b/necsim/impls/std/src/cogs/dispersal_sampler/in_memory/mod.rs deleted file mode 100644 index e58acd679..000000000 --- a/necsim/impls/std/src/cogs/dispersal_sampler/in_memory/mod.rs +++ /dev/null @@ -1,79 +0,0 @@ -use necsim_core::cogs::{Habitat, MathsCore, RngCore}; -use necsim_impls_no_std::array2d::Array2D; - -pub mod error; - -use error::InMemoryDispersalSamplerError; -use necsim_core_bond::NonNegativeF64; -use necsim_impls_no_std::cogs::dispersal_sampler::in_memory::{ - contract::explicit_in_memory_dispersal_check_contract, - InMemoryDispersalSampler as InMemoryDispersalSamplerNoError, -}; - -#[allow(clippy::module_name_repetitions)] -#[allow(clippy::inline_always, clippy::inline_fn_without_body)] -#[contract_trait] -pub trait InMemoryDispersalSampler, G: RngCore>: - InMemoryDispersalSamplerNoError + Sized -{ - #[debug_ensures( - matches!(ret, Err(InMemoryDispersalSamplerError::InconsistentDispersalMapSize)) != ( - dispersal.num_columns() == old( - usize::from(habitat.get_extent().width()) * usize::from(habitat.get_extent().height()) - ) && dispersal.num_rows() == old( - usize::from(habitat.get_extent().width()) * usize::from(habitat.get_extent().height()) - ) - ), - "returns Err(InconsistentDispersalMapSize) iff the dispersal dimensions are inconsistent" - )] - #[debug_ensures( - matches!(ret, Err( - InMemoryDispersalSamplerError::InconsistentDispersalProbabilities - )) != old( - explicit_in_memory_dispersal_check_contract(dispersal, habitat) - ), "returns Err(InconsistentDispersalProbabilities) iff the dispersal probabilities are inconsistent" - )] - fn new( - dispersal: &Array2D, - habitat: &H, - ) -> Result; -} - -#[contract_trait] -impl, G: RngCore, T: InMemoryDispersalSamplerNoError> - InMemoryDispersalSampler for T -{ - /// Creates a new `T` from the `dispersal` map and extent of the habitat - /// map. - /// - /// # Errors - /// - /// `Err(InconsistentDispersalMapSize)` is returned iff the dimensions of - /// `dispersal` are not `ExE` given `E=WxH` where habitat has width `W` - /// and height `W`. - /// - /// `Err(InconsistentDispersalProbabilities)` is returned iff any of the - /// following conditions is violated: - /// - habitat cells must disperse somewhere - /// - non-habitat cells must not disperse - /// - dispersal must only target habitat cells - fn new( - dispersal: &Array2D, - habitat: &H, - ) -> Result { - let habitat_extent = habitat.get_extent(); - - let habitat_area = - usize::from(habitat_extent.width()) * usize::from(habitat_extent.height()); - - if dispersal.num_rows() != habitat_area || dispersal.num_columns() != habitat_area { - return Err(InMemoryDispersalSamplerError::InconsistentDispersalMapSize); - } - - if !explicit_in_memory_dispersal_check_contract(dispersal, habitat) { - return Err(InMemoryDispersalSamplerError::InconsistentDispersalProbabilities); - } - - Ok(Self::unchecked_new(dispersal, habitat)) - } -} diff --git a/necsim/impls/std/src/lib.rs b/necsim/impls/std/src/lib.rs index 658edfeb4..293330ea2 100644 --- a/necsim/impls/std/src/lib.rs +++ b/necsim/impls/std/src/lib.rs @@ -1,8 +1,5 @@ #![deny(clippy::pedantic)] -#[macro_use] -extern crate contracts; - pub mod cogs; pub mod event_log; pub mod lineage_file; diff --git a/rustcoalescence/scenarios/src/spatially_explicit/turnover/map.rs b/rustcoalescence/scenarios/src/spatially_explicit/turnover/map.rs index 1b3e96782..32a929b7c 100644 --- a/rustcoalescence/scenarios/src/spatially_explicit/turnover/map.rs +++ b/rustcoalescence/scenarios/src/spatially_explicit/turnover/map.rs @@ -12,7 +12,6 @@ use necsim_impls_no_std::{ array2d::Array2D, cogs::{ dispersal_sampler::in_memory::{ - contract::explicit_in_memory_dispersal_check_contract, packed_separable_alias::InMemoryPackedSeparableAliasDispersalSampler, InMemoryDispersalSampler, }, @@ -24,7 +23,7 @@ use necsim_impls_no_std::{ decomposition::equal::EqualDecomposition, }; -use necsim_impls_std::cogs::dispersal_sampler::in_memory::error::InMemoryDispersalSamplerError; +use necsim_impls_std::cogs::dispersal_sampler::in_memory::InMemoryDispersalSamplerError; use crate::{Scenario, ScenarioCogs, ScenarioParameters}; @@ -70,29 +69,11 @@ impl> Scenario for SpatiallyExplicitTurnoverMa .map_err(SpatiallyExplicitTurnoverMapScenarioError::TurnoverMap)?; let speciation_probability = UniformSpeciationProbability::new(speciation_probability_per_generation.into()); - - let habitat_extent = habitat.get_extent(); - let habitat_area = - usize::from(habitat_extent.width()) * usize::from(habitat_extent.height()); - - if args.dispersal_map.num_rows() != habitat_area - || args.dispersal_map.num_columns() != habitat_area - { - return Err(SpatiallyExplicitTurnoverMapScenarioError::DispersalMap( - InMemoryDispersalSamplerError::InconsistentDispersalMapSize, - )); - } - - if !explicit_in_memory_dispersal_check_contract(&args.dispersal_map, &habitat) { - return Err(SpatiallyExplicitTurnoverMapScenarioError::DispersalMap( - InMemoryDispersalSamplerError::InconsistentDispersalProbabilities, - )); - } - - let dispersal_sampler = InMemoryPackedSeparableAliasDispersalSampler::unchecked_new( - &args.dispersal_map, - &habitat, - ); + let dispersal_sampler = + InMemoryPackedSeparableAliasDispersalSampler::new(&args.dispersal_map, &habitat) + .map_err(|err| { + SpatiallyExplicitTurnoverMapScenarioError::DispersalMap(err.into()) + })?; Ok(ScenarioCogs { habitat, diff --git a/rustcoalescence/scenarios/src/spatially_explicit/turnover/uniform.rs b/rustcoalescence/scenarios/src/spatially_explicit/turnover/uniform.rs index fb35a3e2b..1b7538cfb 100644 --- a/rustcoalescence/scenarios/src/spatially_explicit/turnover/uniform.rs +++ b/rustcoalescence/scenarios/src/spatially_explicit/turnover/uniform.rs @@ -12,7 +12,6 @@ use necsim_impls_no_std::{ array2d::Array2D, cogs::{ dispersal_sampler::in_memory::{ - contract::explicit_in_memory_dispersal_check_contract, packed_separable_alias::InMemoryPackedSeparableAliasDispersalSampler, InMemoryDispersalSampler, }, @@ -24,7 +23,7 @@ use necsim_impls_no_std::{ decomposition::equal::EqualDecomposition, }; -use necsim_impls_std::cogs::dispersal_sampler::in_memory::error::InMemoryDispersalSamplerError; +use necsim_impls_std::cogs::dispersal_sampler::in_memory::InMemoryDispersalSamplerError; use crate::{Scenario, ScenarioCogs, ScenarioParameters}; @@ -67,29 +66,11 @@ impl> Scenario for SpatiallyExplicitUniformTur let turnover_rate = UniformTurnoverRate::new(args.turnover_rate); let speciation_probability = UniformSpeciationProbability::new(speciation_probability_per_generation.into()); - - let habitat_extent = habitat.get_extent(); - let habitat_area = - usize::from(habitat_extent.width()) * usize::from(habitat_extent.height()); - - if args.dispersal_map.num_rows() != habitat_area - || args.dispersal_map.num_columns() != habitat_area - { - return Err(SpatiallyExplicitUniformTurnoverScenarioError::DispersalMap( - InMemoryDispersalSamplerError::InconsistentDispersalMapSize, - )); - } - - if !explicit_in_memory_dispersal_check_contract(&args.dispersal_map, &habitat) { - return Err(SpatiallyExplicitUniformTurnoverScenarioError::DispersalMap( - InMemoryDispersalSamplerError::InconsistentDispersalProbabilities, - )); - } - - let dispersal_sampler = InMemoryPackedSeparableAliasDispersalSampler::unchecked_new( - &args.dispersal_map, - &habitat, - ); + let dispersal_sampler = + InMemoryPackedSeparableAliasDispersalSampler::new(&args.dispersal_map, &habitat) + .map_err(|err| { + SpatiallyExplicitUniformTurnoverScenarioError::DispersalMap(err.into()) + })?; Ok(ScenarioCogs { habitat,