polynomial_roots/
polynomials.rs

1pub struct Polynomial {
2  coefficients: std::collections::LinkedList<f32>,
3}
4
5impl Polynomial {
6  /// Create a new polynomial.
7  pub const fn new(
8    coefficients: std::collections::LinkedList<f32>,
9  ) -> Polynomial {
10    Polynomial { coefficients }
11  }
12
13  /// Remove the leading zeros of the polynomial, both from
14  /// the right and the left.
15  /// For example: 0 + 0 x¹ + 1 x² + 0 x³ becomes 1.
16  pub fn simplify(&mut self) {
17    while let Some(&coefficient) = self.first() {
18      // If it isn't 0 we shouldn't remove it.
19      if !crate::math::is_zero(coefficient) {
20        break;
21      }
22      self.coefficients.pop_front();
23    }
24    while let Some(&coefficient) = self.last() {
25      if !crate::math::is_zero(coefficient) {
26        break;
27      }
28      self.coefficients.pop_back();
29    }
30  }
31
32  /// Evaluate p(x).
33  pub fn get_value_at(&self, x: f32) -> f32 {
34    self
35      .coefficients
36      .iter()
37      .fold((0.0, 1.0), |acc, e| {
38        (acc.0 + e * acc.1, acc.1 * x)
39      })
40      .1
41  }
42
43  // Expose functions of self.coefficients.
44  pub fn len(&self) -> usize {
45    self.coefficients.len()
46  }
47  pub fn iter(
48    &self,
49  ) -> std::collections::linked_list::Iter<f32> {
50    self.coefficients.iter()
51  }
52  pub fn first(&self) -> Option<&f32> {
53    self.coefficients.front()
54  }
55  pub fn last(&self) -> Option<&f32> {
56    self.coefficients.back()
57  }
58}
59
60#[cfg(test)]
61mod tests {
62  #[test]
63  fn create_polynomial() {
64    let coefficients = std::collections::LinkedList::new();
65
66    let polynomial_1 = crate::polynomials::Polynomial {
67      coefficients: coefficients.clone(),
68    };
69    let polynomial_2 = crate::polynomials::Polynomial::new(
70      coefficients,
71    );
72
73    assert_eq!(
74      polynomial_1.coefficients,
75      polynomial_2.coefficients
76    );
77  }
78
79  #[test]
80  fn evaluate_polynomial() {
81    let coefficients =
82      // c = 1, b = 2, a = -3
83      // a x² + b x + c
84      std::collections::LinkedList::from([1.0, 2.0, -3.0]);
85
86    let polynomial =
87      crate::polynomials::Polynomial { coefficients };
88
89    assert!(crate::math::is_zero(
90      //    p(x) - y = 0
91      // => p(x) = y
92      // We check if this is 0 instead of checking if both
93      // are equal because of floating point errors.
94      polynomial.get_value_at(-1.0) + 4.0
95    ));
96  }
97}