Fix Issues™️

This commit is contained in:
Yash Karandikar 2023-02-20 19:47:51 -06:00
parent 30a66610ad
commit d307021e99
2 changed files with 41 additions and 61 deletions

View file

@ -1,52 +1,50 @@
use std::fmt::Display; #![allow(clippy::missing_errors_doc)]
#[derive(Debug, Clone, Default)] use std::fmt::Debug;
pub struct InterpLUT {
#[derive(Clone, Default)]
pub struct InterpLut {
inner: Vec<(f64, f64)>, inner: Vec<(f64, f64)>,
} }
impl InterpLUT { impl InterpLut {
/// Creates a new, empty table. /// Creates a new, empty table.
pub fn new() -> InterpLUT { #[must_use]
pub fn new() -> InterpLut {
Self::default() Self::default()
} }
fn sort(&mut self) { /// Inserts a new point into the table.
for i in 0..self.inner.len() {
for j in 0..i {
if self.inner[j].0 > self.inner[i].0 {
self.inner.swap(i, j);
}
}
}
}
/// Inserts a new point into the table. Worst case is O(n^2) due to needing to sort the table
/// after inserting.
pub fn insert(&mut self, m: f64, n: f64) { pub fn insert(&mut self, m: f64, n: f64) {
self.inner.push((m, n)); match self.binary_search(m) {
self.sort(); Ok(i) => {
} self.inner[i] = (m, n);
}
fn binary_search(&self, n: &f64) -> Result<usize, usize> { Err(i) => {
self.inner self.inner.insert(i, (m, n));
.binary_search_by(|&(x, _)| x.partial_cmp(n).unwrap_or(std::cmp::Ordering::Equal)) }
} }
}
pub fn get(&self, n: f64) -> Option<f64> {
let searched = self.binary_search(&n); fn binary_search(&self, n: f64) -> Result<usize, usize> {
if let Ok(i) = searched { self.inner.binary_search_by(|&(x, _)| x.total_cmp(&n))
return Some(self.inner[i].1); }
} else if let Err(i) = searched {
// value was not found /// Gets an interpolated value from the table. If n is out of bounds, returns an Err containing
if i == 0 || i == self.inner.len() { /// the value at that boundary.
return None; pub fn get(&self, n: f64) -> Result<f64, f64> {
match self.binary_search(n) {
Ok(i) => Ok(self.inner[i].1),
Err(i) => {
// value was not found
if i == 0 || i == self.inner.len() {
return Err(self.inner[i].1);
}
let t = Self::inverse_lerp(self.inner[i - 1].0, self.inner[i].0, n);
let res = Self::lerp(self.inner[i - 1].1, self.inner[i].1, t);
Ok(res)
} }
let t = Self::inverse_lerp(self.inner[i - 1].0, self.inner[i].0, n);
let res = Self::lerp(self.inner[i - 1].1, self.inner[i].1, t);
return Some(res);
} }
None
} }
fn inverse_lerp(low: f64, high: f64, n: f64) -> f64 { fn inverse_lerp(low: f64, high: f64, n: f64) -> f64 {
@ -62,26 +60,8 @@ impl InterpLUT {
} }
} }
impl Display for InterpLUT { impl Debug for InterpLut {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let num_digits_largest = self f.debug_map().entries(self.inner.iter().copied()).finish()
.inner
.last()
.copied()
.unwrap_or_default()
.0
.log10()
.ceil() as usize;
for &(m, n) in &self.inner {
writeln!(
f,
"|{: ^width$}|{: ^width$}|",
m,
n,
width = num_digits_largest + 2
)?;
}
Ok(())
} }
} }

View file

@ -1,7 +1,7 @@
use interplut::InterpLUT; use interplut::InterpLut;
fn main() { fn main() {
let mut lut = InterpLUT::new(); let mut lut = InterpLut::new();
lut.insert(31.0, 5.0); lut.insert(31.0, 5.0);
lut.insert(5.0, 30.2); lut.insert(5.0, 30.2);
@ -10,7 +10,7 @@ fn main() {
lut.insert(2.0, 28.0); lut.insert(2.0, 28.0);
lut.insert(1.0, 27.0); lut.insert(1.0, 27.0);
lut.insert(18.0, 31.0); lut.insert(18.0, 31.0);
println!("{}", lut); println!("{:#?}", lut);
dbg!(lut.get(0.5)); dbg!(lut.get(0.5));
dbg!(lut.get(17.)); dbg!(lut.get(17.));
} }