use std::fmt::Debug;
use super::linear_base;
#[derive(Debug)]
pub struct DiscreteMap {
min: f64,
max: f64,
lin_base: linear_base::Generic,
}
impl DiscreteMap {
pub fn new<T>(min: T, max: T) -> Self
where
T: Into<isize> + Copy + Clone,
{
let min: isize = min.into();
let max: isize = max.into();
let min = min as f64;
let max = max as f64;
let lin_base = linear_base::Generic::new(min, max);
Self { min, max, lin_base }
}
pub fn normalize<T>(&self, value: T) -> f64
where
T: Into<isize> + Copy + Clone,
{
self.normalize_generic(value)
}
#[inline(always)]
fn normalize_generic<T>(&self, value: T) -> f64
where
T: Into<isize> + Copy + Clone,
{
let value: isize = value.into();
let value = value as f64;
if value <= self.min {
return 0.0;
};
if value >= self.max {
return 1.0;
};
self.lin_base.normalize(value)
}
pub fn normalize_float(&self, value: f64) -> f64 {
self.normalize_generic_float(value)
}
#[inline(always)]
fn normalize_generic_float(&self, value: f64) -> f64 {
if value <= self.min {
return 0.0;
};
if value >= self.max {
return 1.0;
};
self.lin_base.normalize(value.round())
}
pub fn normalize_array<T>(&self, in_values: &[T], out_normalized: &mut [f64])
where
T: Into<isize> + Copy + Clone,
{
let min_len = std::cmp::min(in_values.len(), out_normalized.len());
let input = &in_values[..min_len];
let output = &mut out_normalized[..min_len];
for i in 0..min_len {
output[i] = self.normalize_generic(input[i]);
}
}
pub fn normalize_array_float(&self, in_values: &[f64], out_normalized: &mut [f64]) {
let min_len = std::cmp::min(in_values.len(), out_normalized.len());
let input = &in_values[..min_len];
let output = &mut out_normalized[..min_len];
for i in 0..min_len {
output[i] = self.normalize_generic_float(input[i]);
}
}
pub fn denormalize<T>(&self, normalized: f64) -> T
where
T: From<isize> + Copy + Clone,
{
self.denormalize_generic(normalized)
}
#[inline(always)]
fn denormalize_generic<T>(&self, normalized: f64) -> T
where
T: From<isize> + Copy + Clone,
{
if normalized <= 0.0 {
return (self.min as isize).into();
}
if normalized >= 1.0 {
return (self.max as isize).into();
}
(self.lin_base.denormalize(normalized).round() as isize).into()
}
pub fn denormalize_float(&self, normalized: f64) -> f64 {
self.denormalize_generic_float(normalized)
}
#[inline(always)]
fn denormalize_generic_float(&self, normalized: f64) -> f64 {
if normalized <= 0.0 {
return self.min;
}
if normalized >= 1.0 {
return self.max;
}
self.lin_base.denormalize(normalized).round()
}
pub fn denormalize_array<T>(&self, in_normalized: &[f64], out_values: &mut [T])
where
T: From<isize> + Copy + Clone,
{
let min_len = std::cmp::min(in_normalized.len(), out_values.len());
let input = &in_normalized[..min_len];
let output = &mut out_values[..min_len];
for i in 0..min_len {
output[i] = self.denormalize_generic(input[i]);
}
}
pub fn denormalize_array_float(&self, in_normalized: &[f64], out_values: &mut [f64]) {
let min_len = std::cmp::min(in_normalized.len(), out_values.len());
let input = &in_normalized[..min_len];
let output = &mut out_values[..min_len];
for i in 0..min_len {
output[i] = self.denormalize_generic_float(input[i]);
}
}
}