gamlss_transform/transforms/
identity_positive.rs1use crate::{TargetTransform, TransformError, map_slice_into, validate_positive};
2
3#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
5pub struct IdentityPositive;
6
7#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
9pub struct IdentityPositiveState;
10
11impl TargetTransform for IdentityPositive {
12 type State = IdentityPositiveState;
13
14 fn fit(y: &[f64]) -> Result<Self::State, TransformError> {
15 validate_positive(y)?;
16 Ok(IdentityPositiveState)
17 }
18
19 fn transform(_: &Self::State, y: f64) -> f64 {
20 y
21 }
22
23 fn inverse(_: &Self::State, value: f64) -> f64 {
24 value
25 }
26
27 fn transform_slice(state: &Self::State, y: &[f64]) -> Result<Vec<f64>, TransformError> {
28 let mut out = vec![0.0; y.len()];
29 Self::transform_into(state, y, &mut out)?;
30 Ok(out)
31 }
32
33 fn transform_into(
34 state: &Self::State,
35 y: &[f64],
36 out: &mut [f64],
37 ) -> Result<(), TransformError> {
38 map_slice_into(y, out, validate_positive, |value| {
39 Self::transform(state, value)
40 })
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use crate::{IdentityPositive, TargetTransform, TransformError};
47
48 #[test]
49 fn rejects_non_positive_values() {
50 assert_eq!(
51 IdentityPositive::fit(&[-1.0]).unwrap_err(),
52 TransformError::NonPositiveValue
53 );
54 }
55
56 #[test]
57 fn leaves_positive_values_unchanged() {
58 let y = [1.0, 2.0];
59 let (state, transformed) = IdentityPositive::fit_transform(&y).unwrap();
60
61 assert_eq!(transformed, y);
62 assert_eq!(
63 IdentityPositive::inverse_slice(&state, &transformed).unwrap(),
64 y
65 );
66 }
67}