From 4998f5936dc7da36aba0cd018de2a1a6127dda08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Tue, 19 Jan 2021 09:06:32 -0300 Subject: Make shader sample intervals uniform --- src/poly.rs | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/poly.rs (limited to 'src/poly.rs') diff --git a/src/poly.rs b/src/poly.rs new file mode 100644 index 0000000..35e85d8 --- /dev/null +++ b/src/poly.rs @@ -0,0 +1,123 @@ +mod iter; + +use iter::Iter; +use std::fmt; +use std::ops::{Add, Sub}; + +#[derive(PartialEq, Debug, Clone)] +pub struct Poly { + data: Vec, + degree: usize, +} + +impl Poly { + pub fn new(data: Vec) -> Poly { + if data.len() > 1 { + let mut i = data.len() - 1; + while data[i] == 0.0 && i > 0 { + i -= 1; + } + Poly { data, degree: i } + } else { + Poly { data, degree: 0 } + } + } + + pub fn degree(&self) -> usize { + self.degree + } + + fn iter(&self) -> Iter { + Iter::new(self.data.clone(), self.degree()) + } + + pub fn shift(self) -> Poly { + let mut r = vec![0.0]; + r.append(&mut self.data.clone()); + Poly::new(r) + } + + pub fn deriv(&self) -> Poly { + let mut data = vec![0.0; self.degree()]; + if self.degree() > 0 { + for i in 0..self.degree() { + data[i] = self.data[i + 1] * (i + 1) as f32; + } + Poly::new(data) + } else { + Poly::new(vec![0.0]) + } + } +} + +impl Add for &Poly { + type Output = Poly; + + fn add(self, other: Self) -> Poly { + Poly::new(self.iter().zip(other.iter()).map(|(x, y)| x + y).collect()) + } +} + +impl Sub for &Poly { + type Output = Poly; + + fn sub(self, other: Self) -> Poly { + Poly::new(self.iter().zip(other.iter()).map(|(x, y)| x - y).collect()) + } +} + +impl fmt::Display for &Poly { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = String::new(); + for i in 0..self.data.len() { + s.push_str(&self.data[i].clone().to_string()); + if i < self.data.len() - 1 { + s.push_str(", "); + } + } + write!(f, "{}", s) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn shift_test() { + let a = Poly::new(vec![1.0, 2.0, 3.0]); + assert_eq!(a.shift(), Poly::new(vec![0.0, 1.0, 2.0, 3.0])); + } + + #[test] + fn add_test() { + let a = Poly::new(vec![1.0]); + let b = Poly::new(vec![0.0, 0.0, 0.0, 1.0]); + assert_eq!(&a + &b, Poly::new(vec![1.0, 0.0, 0.0, 1.0])); + } + + #[test] + fn sub_test() { + let a = Poly::new(vec![1.0, 2.0, 3.0]); + let b = Poly::new(vec![1.0, 1.0, 1.0]); + assert_eq!(&a - &b, Poly::new(vec![0.0, 1.0, 2.0])); + } + + #[test] + fn deriv_test() { + let p = Poly::new(vec![1.0, 2.0, 3.0, 4.0]); + assert_eq!(p.deriv(), Poly::new(vec![2.0, 6.0, 12.0])); + } + + #[test] + fn degree_is_five() { + let p = Poly::new(vec![0.0, 0.0, 0.0, 0.0, 0.0, 2.0]); + assert_eq!(p.degree(), 5); + } + + #[test] + fn degree_is_zero() { + let p = Poly::new(vec![0.0; 6]); + assert_eq!(p.degree(), 0); + } +} -- cgit v1.2.3