Skip to content

Commit

Permalink
Refactor to address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
juntyr committed Feb 29, 2024
1 parent d79e2d7 commit 3a3db15
Show file tree
Hide file tree
Showing 33 changed files with 287 additions and 369 deletions.
64 changes: 33 additions & 31 deletions docs/simulate.ron
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@

/* selection of the scenario which will be simulated */
scenario: (
/* spatially explicit scenario using habitat (optionally turnover) and dispersal maps */
/* spatially explicit scenario using habitat (and optionally turnover) and dispersal maps */
| SpatiallyExplicit(
/* file path to a (WxH) TIFF file storing grayscale u32 habitat values */
habitat: (PathBuf),
Expand Down Expand Up @@ -237,46 +237,47 @@
sample: (
/* circular sample area */
| Circle(
/* centre (x, y) of the circle
* optional, default = (x: 2147483647, y: 2147483647)
* note that 2147483647 = 2^31 - 1 */
centre: (
x: (u32),
y: (u32),
),
/* radius of the circle */
radius: (u16),
/* centre (x, y) of the circle
* optional, default = (x: 2147483647, y: 2147483647)
* note that 2147483647 = 2^31 - 1 */
centre: (
x: (u32),
y: (u32),
),
/* radius of the circle */
radius: (u16),
)
/* rectangular sample area */
| Rectangle(
/* lower-left origin x of the sample area */
x: (u32),
/* lower-left origin y of the sample area */
y: (u32),
/* width of the sample area */
width: (1 <= u64 <= 2^32),
/* height of the sample area */
height: (1 <= u64 <= 2^32),
/* lower-left origin of the sample area */
origin: (
x: (u32),
y: (u32),
),
/* width of the sample area */
width: (1 <= u64 <= 2^32),
/* height of the sample area */
height: (1 <= u64 <= 2^32),
)
),
/* selection of the dispersal kernel */
dispersal: (
/* Gaussian Normal dispersal kernel N(0, sigma^2)
* requires the `almost-infinite-normal-dispersal-scenario` feature */
| Normal(
/* sigma for the Gaussian dispersal kernel */
sigma: (0.0 <= f64),
/* sigma for the Gaussian dispersal kernel */
sigma: (0.0 <= f64),
)
/* Clark2Dt dispersal kernel
* requires the `almost-infinite-clark2dt-dispersal-scenario` feature */
| Clark2Dt(
/* shape (u) for the Clark 2Dt dispersal kernel */
shape_u: (0.0 < f64),
/* tail (p) for the Clark 2Dt dispersal kernel
* - Clark 2Dt dispersal tends to Gaussian as p becomes large
* - Clark 2Dt dispersal tends to Cauchy as p goes to zero
* optional, default = 1.0 */
tail_p: (0.0 < f64),
/* shape (u) for the Clark 2Dt dispersal kernel */
shape_u: (0.0 < f64),
/* tail (p) for the Clark 2Dt dispersal kernel
* - Clark 2Dt dispersal tends to Gaussian as p becomes large
* - Clark 2Dt dispersal tends to Cauchy as p goes to zero
* optional, default = 1.0 */
tail_p: (0.0 < f64),
)
),
)
Expand Down Expand Up @@ -304,10 +305,11 @@
/* rectangular sample area, individuals living in here are simulated
* the sample area can wrap around the torus */
sample: Rectangle(
/* lower-left origin x of the sample area */
x: (u32),
/* lower-left origin y of the sample area */
y: (u32),
/* lower-left origin of the sample area */
origin: (
x: (u32),
y: (u32),
),
/* width of the sample area */
width: (1 <= u64 <= 2^32),
/* height of the sample area */
Expand Down
109 changes: 43 additions & 66 deletions necsim/core/src/landscape/extent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,24 @@ use super::Location;
#[serde(deny_unknown_fields)]
#[repr(C)]
pub struct LandscapeExtent {
x: u32,
y: u32,
origin: Location,
width: OffByOneU32,
height: OffByOneU32,
}

impl LandscapeExtent {
#[must_use]
pub const fn new(x: u32, y: u32, width: OffByOneU32, height: OffByOneU32) -> Self {
pub const fn new(origin: Location, width: OffByOneU32, height: OffByOneU32) -> Self {
Self {
x,
y,
origin,
width,
height,
}
}

#[must_use]
pub const fn x(&self) -> u32 {
self.x
}

#[must_use]
pub const fn y(&self) -> u32 {
self.y
pub const fn origin(&self) -> &Location {
&self.origin
}

#[must_use]
Expand All @@ -47,17 +40,16 @@ impl LandscapeExtent {

#[must_use]
pub const fn contains(&self, location: &Location) -> bool {
location.x() >= self.x
&& location.x() <= self.width.add_incl(self.x)
&& location.y() >= self.y
&& location.y() <= self.height.add_incl(self.y)
location.x() >= self.origin.x()
&& location.x() <= self.width.add_incl(self.origin.x())
&& location.y() >= self.origin.y()
&& location.y() <= self.height.add_incl(self.origin.y())
}

#[must_use]
pub fn iter(&self) -> LocationIterator {
LocationIterator {
x: self.x,
y: self.y,
location: self.origin.clone(),
extent: self.clone(),
first_y: true,
}
Expand All @@ -75,8 +67,7 @@ impl IntoIterator for &LandscapeExtent {

#[derive(Debug, PartialEq, Eq)]
pub struct LocationIterator {
x: u32,
y: u32,
location: Location,
extent: LandscapeExtent,
first_y: bool,
}
Expand All @@ -85,18 +76,21 @@ impl Iterator for LocationIterator {
type Item = Location;

fn next(&mut self) -> Option<Self::Item> {
if self.y != self.extent.height().add_excl(self.extent.y()) || self.first_y {
let next = Some(Location::new(self.x, self.y));
if self.location.y() != self.extent.height().add_excl(self.extent.origin().y())
|| self.first_y
{
let after =
if self.location.x() == self.extent.width().add_incl(self.extent.origin().x()) {
self.first_y = false;
Location::new(self.extent.origin().x(), self.location.y().wrapping_add(1))
} else {
Location::new(self.location.x().wrapping_add(1), self.location.y())
};

self.x = if self.x == self.extent.width().add_incl(self.extent.x()) {
self.y = self.y.wrapping_add(1);
self.first_y = false;
self.extent.x()
} else {
self.x.wrapping_add(1)
};
let next = self.location.clone();
self.location = after;

next
Some(next)
} else {
None
}
Expand All @@ -115,8 +109,7 @@ mod tests {
#[test]
fn test_single_location() {
let extent = LandscapeExtent::new(
0,
0,
Location::new(0, 0),
OffByOneU32::new(1).unwrap(),
OffByOneU32::new(1).unwrap(),
);
Expand All @@ -127,8 +120,7 @@ mod tests {
#[test]
fn test_simple_extent() {
let extent = LandscapeExtent::new(
42,
24,
Location::new(42, 24),
OffByOneU32::new(4).unwrap(),
OffByOneU32::new(2).unwrap(),
);
Expand All @@ -151,8 +143,7 @@ mod tests {
#[test]
fn test_wrapping_extent() {
let extent = LandscapeExtent::new(
M2,
M1,
Location::new(M2, M1),
OffByOneU32::new(4).unwrap(),
OffByOneU32::new(2).unwrap(),
);
Expand All @@ -175,31 +166,27 @@ mod tests {
#[test]
fn test_full_extent() {
let extent = LandscapeExtent::new(
0,
0,
Location::new(0, 0),
OffByOneU32::new(1 << 32).unwrap(),
OffByOneU32::new(1 << 32).unwrap(),
);
let mut iter = extent.iter();
assert_eq!(
iter,
LocationIterator {
x: 0,
y: 0,
location: Location::new(0, 0),
extent: extent.clone(),
first_y: true,
}
);
assert_eq!(iter.next(), Some(Location::new(0, 0)));

iter.x = M1;
iter.y = M1;
iter.location = Location::new(M1, M1);
assert_eq!(iter.next(), Some(Location::new(M1, M1)));
assert_eq!(
iter,
LocationIterator {
x: 0,
y: 0,
location: Location::new(0, 0),
extent: extent.clone(),
first_y: false,
}
Expand All @@ -208,8 +195,7 @@ mod tests {
assert_eq!(
iter,
LocationIterator {
x: 0,
y: 0,
location: Location::new(0, 0),
extent,
first_y: false,
}
Expand All @@ -219,70 +205,62 @@ mod tests {
#[test]
fn test_full_wrapping_extent() {
let extent = LandscapeExtent::new(
1386,
6812,
Location::new(1386, 6812),
OffByOneU32::new(1 << 32).unwrap(),
OffByOneU32::new(1 << 32).unwrap(),
);
let mut iter = extent.iter();
assert_eq!(
iter,
LocationIterator {
x: 1386,
y: 6812,
location: Location::new(1386, 6812),
extent: extent.clone(),
first_y: true,
}
);

iter.x = M1;
iter.location = Location::new(M1, iter.location.y());
assert_eq!(iter.next(), Some(Location::new(M1, 6812)));
assert_eq!(
iter,
LocationIterator {
x: 0,
y: 6812,
location: Location::new(0, 6812),
extent: extent.clone(),
first_y: true,
}
);
assert_eq!(iter.next(), Some(Location::new(0, 6812)));

iter.x = 1385;
iter.location = Location::new(1385, iter.location.y());
assert_eq!(iter.next(), Some(Location::new(1385, 6812)));
assert_eq!(
iter,
LocationIterator {
x: 1386,
y: 6813,
location: Location::new(1386, 6813),
extent: extent.clone(),
first_y: false,
}
);
assert_eq!(iter.next(), Some(Location::new(1386, 6813)));

iter.x = 1385;
iter.y = M1;
iter.location = Location::new(1385, M1);
assert_eq!(iter.next(), Some(Location::new(1385, M1)));
assert_eq!(
iter,
LocationIterator {
x: 1386,
y: 0,
location: Location::new(1386, 0),
extent: extent.clone(),
first_y: false,
}
);
assert_eq!(iter.next(), Some(Location::new(1386, 0)));

iter.x = 1385;
iter.y = 6811;
iter.location = Location::new(1385, 6811);
assert_eq!(iter.next(), Some(Location::new(1385, 6811)));
assert_eq!(
iter,
LocationIterator {
x: 1386,
y: 6812,
location: Location::new(1386, 6812),
extent: extent.clone(),
first_y: false,
}
Expand All @@ -291,8 +269,7 @@ mod tests {
assert_eq!(
iter,
LocationIterator {
x: 1386,
y: 6812,
location: Location::new(1386, 6812),
extent,
first_y: false,
}
Expand Down
2 changes: 1 addition & 1 deletion necsim/impls/cuda/src/cogs/maths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl MathsCore for NvptxMathsCore {
let log2_x: f32;
core::arch::asm!("lg2.approx.f32 {}, {};", out(reg32) log2_x, in(reg32) x, options(pure, nomem, nostack));

let exp_log2_x = log2_x * exp;
let exp_log2_x = exp * log2_x;

let f: f32;
core::arch::asm!("ex2.approx.f32 {}, {};", out(reg32) f, in(reg32) exp_log2_x, options(pure, nomem, nostack));
Expand Down
Loading

0 comments on commit 3a3db15

Please sign in to comment.