1use ndarray::{Array1, Array2, Array3};
2use crate::array::Aggregate;
3
4#[derive(Copy, Clone)]
5pub enum RescaleRange {
6 Custom(f32, f32),
7 Max,
8}
9
10impl RescaleRange {
11 fn min(self) -> f32 {
12 match self {
13 RescaleRange::Custom(min, _) => min,
14 RescaleRange::Max => 0.
15 }
16 }
17
18 fn max(self) -> f32 {
19 match self {
20 RescaleRange::Custom(_, max) => max,
21 RescaleRange::Max => 1.
22 }
23 }
24}
25
26pub trait Rescale {
27 fn min(&self) -> f32;
28 fn max(&self) -> f32;
29 fn rescale(&mut self, range: RescaleRange);
30 fn rescale_value(min: f32, max: f32, value: f32, range: RescaleRange) -> f32 {
31 let (new_min, new_max) = (range.min(), range.max());
32 let new_range = new_max - new_min;
33
34 new_min + ((value - min) * new_range / (max - min))
35 }
36}
37
38macro_rules! impl_rescale {
39 ($ty:ty) => {
40 impl Rescale for $ty {
41 fn min(&self) -> f32 {
42 Aggregate::min(self)
43 }
44
45 fn max(&self) -> f32 {
46 Aggregate::max(self)
47 }
48
49 fn rescale(&mut self, range: RescaleRange) {
50 let min = Rescale::min(self);
51 let max = Rescale::max(self);
52
53 for item in self.iter_mut() {
54 *item = Self::rescale_value(min, max, *item, range);
55 }
56 }
57 }
58 };
59}
60
61impl_rescale!(Array1<f32>);
62impl_rescale!(Array2<f32>);
63impl_rescale!(Array3<f32>);