From d307021e9906a9ef2eb42d8c555d4cd12c57ee57 Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Mon, 20 Feb 2023 19:47:51 -0600 Subject: [PATCH] =?UTF-8?q?Fix=20Issues=E2=84=A2=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib.rs | 96 +++++++++++++++++++++-------------------------------- src/main.rs | 6 ++-- 2 files changed, 41 insertions(+), 61 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 36e802a..9d17c4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,52 +1,50 @@ -use std::fmt::Display; +#![allow(clippy::missing_errors_doc)] -#[derive(Debug, Clone, Default)] -pub struct InterpLUT { +use std::fmt::Debug; + +#[derive(Clone, Default)] +pub struct InterpLut { inner: Vec<(f64, f64)>, } -impl InterpLUT { +impl InterpLut { /// Creates a new, empty table. - pub fn new() -> InterpLUT { + #[must_use] + pub fn new() -> InterpLut { Self::default() } - fn sort(&mut self) { - 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. + /// Inserts a new point into the table. pub fn insert(&mut self, m: f64, n: f64) { - self.inner.push((m, n)); - self.sort(); - } - - fn binary_search(&self, n: &f64) -> Result { - self.inner - .binary_search_by(|&(x, _)| x.partial_cmp(n).unwrap_or(std::cmp::Ordering::Equal)) - } - - pub fn get(&self, n: f64) -> Option { - let searched = self.binary_search(&n); - if let Ok(i) = searched { - return Some(self.inner[i].1); - } else if let Err(i) = searched { - // value was not found - if i == 0 || i == self.inner.len() { - return None; + match self.binary_search(m) { + Ok(i) => { + self.inner[i] = (m, n); + } + Err(i) => { + self.inner.insert(i, (m, n)); + } + } + } + + fn binary_search(&self, n: f64) -> Result { + self.inner.binary_search_by(|&(x, _)| x.total_cmp(&n)) + } + + /// Gets an interpolated value from the table. If n is out of bounds, returns an Err containing + /// the value at that boundary. + pub fn get(&self, n: f64) -> Result { + 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 { @@ -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 { - let num_digits_largest = self - .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(()) + f.debug_map().entries(self.inner.iter().copied()).finish() } } diff --git a/src/main.rs b/src/main.rs index 0db5ef6..c5b3fc0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ -use interplut::InterpLUT; +use interplut::InterpLut; fn main() { - let mut lut = InterpLUT::new(); + let mut lut = InterpLut::new(); lut.insert(31.0, 5.0); lut.insert(5.0, 30.2); @@ -10,7 +10,7 @@ fn main() { lut.insert(2.0, 28.0); lut.insert(1.0, 27.0); lut.insert(18.0, 31.0); - println!("{}", lut); + println!("{:#?}", lut); dbg!(lut.get(0.5)); dbg!(lut.get(17.)); }