use crate::units::SrsError;
use petekstatic::uncertainty::Distribution;
pub fn distribution_of(d: petekio::Distribution, value: f64) -> Result<Distribution, SrsError> {
Ok(match d {
petekio::Distribution::Deterministic => Distribution::Constant(value),
petekio::Distribution::Uniform { lo, hi } => Distribution::uniform(lo, hi)?,
petekio::Distribution::Triangular { lo, mode, hi } => {
Distribution::triangular(lo, mode, hi)?
}
petekio::Distribution::Normal { mean, std } => Distribution::normal(mean, std)?,
petekio::Distribution::LogNormal { mu, sigma } => Distribution::lognormal(mu, sigma)?,
})
}
pub fn scale_area_km2_to_m2(d: Distribution) -> Distribution {
let k = petektools::units::M2_PER_KM2;
match d {
Distribution::Constant(v) => Distribution::Constant(v * k),
Distribution::Uniform { min, max } => Distribution::Uniform {
min: min * k,
max: max * k,
},
Distribution::Triangular { min, mode, max } => Distribution::Triangular {
min: min * k,
mode: mode * k,
max: max * k,
},
Distribution::Normal { mean, sd } => Distribution::Normal {
mean: mean * k,
sd: sd * k,
},
Distribution::Lognormal { mu, sigma } => Distribution::Lognormal {
mu: mu + k.ln(),
sigma,
},
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn distribution_variants_map_across() {
assert_eq!(
distribution_of(petekio::Distribution::Deterministic, 7.0).unwrap(),
Distribution::Constant(7.0)
);
assert_eq!(
distribution_of(
petekio::Distribution::Triangular {
lo: 1.0,
mode: 2.0,
hi: 3.0
},
2.0
)
.unwrap(),
Distribution::Triangular {
min: 1.0,
mode: 2.0,
max: 3.0
}
);
assert_eq!(
distribution_of(
petekio::Distribution::Normal {
mean: 0.2,
std: 0.02
},
0.2
)
.unwrap(),
Distribution::Normal {
mean: 0.2,
sd: 0.02
}
);
}
#[test]
fn invalid_distribution_params_surface_an_error() {
assert!(distribution_of(petekio::Distribution::Uniform { lo: 5.0, hi: 5.0 }, 5.0).is_err());
}
}