light_curve_feature/transformers/
mod.rs

1use transformer::*;
2pub use transformer::{Transformer, TransformerPropsTrait, TransformerTrait};
3
4use paste::paste;
5
6pub mod bazin_fit;
7pub mod clipped_lg;
8pub mod composed;
9pub mod linexp_fit;
10pub mod transformer;
11pub mod villar_fit;
12
13macro_rules! transformer {
14    ($module:ident, $structure:ident, $func:expr_2021, $names:expr_2021, $descriptions:expr_2021, $doc:literal $(,)?) => {
15        pub mod $module {
16            use super::*;
17
18            #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
19            pub struct $structure {}
20
21            impl $structure {
22                pub fn new() -> Self {
23                    Self {}
24                }
25
26                pub const fn doc() -> &'static str {
27                    $doc
28                }
29            }
30
31            impl Default for $structure {
32                fn default() -> Self {
33                    Self::new()
34                }
35            }
36
37            impl TransformerPropsTrait for $structure {
38                #[inline]
39                fn is_size_valid(&self, _size: usize) -> bool {
40                    true
41                }
42
43                #[inline]
44                fn size_hint(&self, size: usize) -> usize {
45                    size
46                }
47
48                fn names(&self, names: &[&str]) -> Vec<String> {
49                    let func = $names;
50                    func(names)
51                }
52
53                fn descriptions(&self, desc: &[&str]) -> Vec<String> {
54                    let func = $descriptions;
55                    func(desc)
56                }
57            }
58
59            impl<T: Float> TransformerTrait<T> for $structure {
60                #[inline]
61                fn transform(&self, v: Vec<T>) -> Vec<T> {
62                    let func = $func;
63                    func(v)
64                }
65            }
66
67            #[cfg(test)]
68            mod tests {
69                use super::*;
70
71                check_transformer!($structure);
72            }
73        }
74    };
75}
76
77// into_iter().map().collect() should create no allocations
78macro_rules! transformer_from_per_element_fn {
79    ($module:ident, $func:expr_2021, $prefix_name:literal, $prefix_description:literal, $doc:literal $(,)?) => {
80        paste! {
81            transformer!(
82                $module,
83                [<$module:camel Transformer>],
84                |v: Vec<T>| v.into_iter().map($func).collect::<Vec<T>>(),
85                |names: &[&str]| {
86                    names
87                        .iter()
88                        .map(|name| format!("{}_{}", $prefix_name, name))
89                        .collect::<Vec<_>>()
90                },
91                |desc: &[&str]| {
92                    desc.iter()
93                        .map(|name| format!("{} of {}", $prefix_description, name))
94                        .collect::<Vec<_>>()
95                },
96                $doc
97            );
98        }
99    };
100}
101
102transformer!(
103    identity,
104    IdentityTransformer,
105    |x| x,
106    |names: &[&str]| names.iter().map(|x| x.to_string()).collect(),
107    |desc: &[&str]| desc.iter().map(|x| x.to_string()).collect(),
108    "Identity feature transformer",
109);
110
111transformer_from_per_element_fn!(
112    arcsinh,
113    T::asinh,
114    "arcsinh",
115    "hyperbolic arcsine",
116    "Hyperbolic arcsine feature transformer",
117);
118transformer_from_per_element_fn!(
119    ln1p,
120    T::ln_1p,
121    "ln1p",
122    "natural logarithm of unity plus",
123    "ln(1+x) feature transformer",
124);
125transformer_from_per_element_fn!(
126    lg,
127    T::log10,
128    "lg",
129    "decimal logarithm",
130    "Decimal logarithm feature transformer"
131);
132transformer_from_per_element_fn!(
133    sqrt,
134    T::sqrt,
135    "sqrt",
136    "square root",
137    "Square root feature transformer"
138);