use super::point::Point;
use super::normalize::{ IntegerDataRange, FloatDataRange };
pub fn make_points_i32<I>(points : &[I], starting_id : usize, range_option : Option<IntegerDataRange>, bits_allocated : Option<usize>) -> (Vec<Point>, usize)
where
for<'a> &'a I: IntoIterator<Item = &'a i32>,
{
let mut next_id = starting_id;
let mut converted_points = Vec::with_capacity(points.len());
let mut coordinates = Vec::new();
let range = match range_option {
Some(given_range) => given_range.clone(),
None => IntegerDataRange::from_i32(points)
};
let bits_used = match bits_allocated {
Some(bits) => bits,
None => range.bits_required
};
for input_point in points {
coordinates.clear();
for coordinate in input_point {
let transformed_coordinate = match bits_allocated {
Some(bits) => range.compress(*coordinate, bits),
None => range.normalize(*coordinate)
};
coordinates.push(transformed_coordinate);
}
converted_points.push(Point::new(next_id, &coordinates));
next_id += 1;
}
(converted_points, bits_used)
}
pub fn make_points_f64<I>(points : &[I], starting_id : usize, range_option : Option<FloatDataRange>, bits_allocated : Option<usize>, scale : f64) -> (Vec<Point>, usize)
where
for<'a> &'a I: IntoIterator<Item = &'a f64>,
{
let mut next_id = starting_id;
let mut converted_points = Vec::with_capacity(points.len());
let mut coordinates = Vec::new();
let range = match range_option {
Some(given_range) => given_range.clone(),
None => FloatDataRange::from_f64(points, scale)
};
let bits_used = match bits_allocated {
Some(bits) => bits,
None => range.bits_required
};
for input_point in points {
coordinates.clear();
for coordinate in input_point {
let transformed_coordinate = match bits_allocated {
Some(bits) => range.compress(*coordinate, bits),
None => range.normalize(*coordinate)
};
coordinates.push(transformed_coordinate);
}
converted_points.push(Point::new(next_id, &coordinates));
next_id += 1;
}
(converted_points, bits_used)
}
#[cfg(test)]
mod tests {
#[allow(unused_imports)]
use spectral::prelude::*;
use crate::point::Point;
#[test]
fn make_points_f64() {
let float_points = test_points_f64();
let (actual_points, bits_used) = super::make_points_f64(&float_points, 0, None, None, 10.0);
asserting("correct bits_used").that(&bits_used).is_equal_to(11);
let expected_points = vec![
Point::new(0, &vec![895, 1053, 1037]),
Point::new(0, &vec![952, 1202, 2002]),
Point::new(0, &vec![1420, 0, 1000])
];
for i in 0..3 {
let expected_point = &expected_points[i];
let actual_point = &actual_points[i];
asserting(&format!("For point {:?}", expected_point)).that(&expected_point.are_coordinates_identical(actual_point)).is_equal_to(true);
}
}
fn test_points_f64() -> Vec<Vec<f64>> {
vec![
vec![-10.5, 5.27, 3.66],
vec![-4.802, 20.2, 100.19],
vec![42.0, -100.0, 0.0]
]
}
}