Advertisement
BilakshanP

Stack Overflow

Mar 10th, 2024
1,037
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 6.07 KB | None | 0 0
  1. use num::{Num, Zero};
  2.  
  3. #[derive(Clone)]
  4. pub struct Polynomial<T> {
  5.     degree: usize,
  6.     coefficients: Vec<T>,
  7. }
  8.  
  9. impl<T> Default for Polynomial<T>
  10. where
  11.     T: Num + Clone,
  12. {
  13.     fn default() -> Self {
  14.         Self {
  15.             degree: 0,
  16.             coefficients: vec![T::zero(); 1],
  17.         }
  18.     }
  19. }
  20.  
  21. impl<T> Polynomial<T>
  22. where
  23.     T: Num + Clone,
  24. {
  25.     pub fn new() -> Self {
  26.         Self::default()
  27.     }
  28. }
  29.  
  30. impl<T> Polynomial<T> {
  31.     pub fn from_coefficients(coefficients: Vec<T>) -> Self {
  32.         let degree: usize = coefficients.len() - 1;
  33.         Self {
  34.             degree,
  35.             coefficients,
  36.         }
  37.     }
  38.  
  39.     pub fn degree(&self) -> usize {
  40.         self.degree
  41.     }
  42.  
  43.     pub fn coefficients(&self) -> &Vec<T> {
  44.         &self.coefficients
  45.     }
  46. }
  47.  
  48. impl<T> Polynomial<T>
  49. where
  50.     T: Num + Clone,
  51. {
  52.     pub fn get_coefficient(&self, degree: usize) -> Option<T> {
  53.         if degree > self.degree {
  54.             None
  55.         } else {
  56.             Some(self.coefficients[degree].clone())
  57.         }
  58.     }
  59.  
  60.     pub fn set_degree(&mut self, degree: usize) {
  61.         if degree > self.degree {
  62.             self.degree = degree;
  63.             self.coefficients.resize(degree + 1, T::zero());
  64.         }
  65.     }
  66.  
  67.     pub fn set_coefficient(&mut self, degree: usize, coefficient: T) {
  68.         self.set_degree(degree);
  69.         self.coefficients[degree] = coefficient;
  70.     }
  71. }
  72.  
  73. impl<T> std::ops::Add for Polynomial<T>
  74. where
  75.     T: Num + Clone + Default,
  76. {
  77.     type Output = Self;
  78.  
  79.     fn add(self, other: Self) -> Self {
  80.         let mut result: Polynomial<T> = Self::new();
  81.         result.set_degree(self.degree.max(other.degree));
  82.  
  83.         for i in 0..=result.degree {
  84.             let c: T = self.get_coefficient(i).unwrap_or_default()
  85.                 + other.get_coefficient(i).unwrap_or_default();
  86.  
  87.             result.set_coefficient(i, c);
  88.         }
  89.  
  90.         result
  91.     }
  92. }
  93.  
  94. impl<T> std::ops::Sub for Polynomial<T>
  95. where
  96.     T: Num + Clone + Default,
  97. {
  98.     type Output = Self;
  99.  
  100.     fn sub(self, other: Self) -> Self {
  101.         let mut result: Polynomial<T> = Self::new();
  102.         result.set_degree(self.degree.max(other.degree));
  103.  
  104.         for i in 0..=result.degree {
  105.             let c: T = self.get_coefficient(i).unwrap_or_default()
  106.                 - other.get_coefficient(i).unwrap_or_default();
  107.  
  108.             result.set_coefficient(i, c);
  109.         }
  110.  
  111.         result
  112.     }
  113. }
  114.  
  115. impl<T> std::ops::Mul for Polynomial<T>
  116. where
  117.     T: Num + Clone + Default,
  118. {
  119.     type Output = Self;
  120.  
  121.     fn mul(self, other: Self) -> Self {
  122.         let mut result: Polynomial<T> = Self::new();
  123.         result.set_degree(self.degree + other.degree);
  124.  
  125.         for i in 0..=self.degree {
  126.             for j in 0..=other.degree {
  127.                 let c: T = result.get_coefficient(i + j).unwrap_or_default()
  128.                     + (self.get_coefficient(i).unwrap_or_default()
  129.                         * other.get_coefficient(j).unwrap_or_default());
  130.  
  131.                 result.set_coefficient(i + j, c);
  132.             }
  133.         }
  134.  
  135.         result
  136.     }
  137. }
  138.  
  139. impl<T> std::fmt::Debug for Polynomial<T>
  140. where
  141.     T: std::fmt::Debug,
  142. {
  143.     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  144.         let mut result: String = String::new();
  145.  
  146.         for (degree, coefficient) in self.coefficients.iter().enumerate().rev() {
  147.             result.push_str(&format!("({}, {:?})", degree, coefficient));
  148.  
  149.             if degree > 0 {
  150.                 result.push_str(", ");
  151.             }
  152.         }
  153.  
  154.         write!(f, "[{}]", result)
  155.     }
  156. }
  157.  
  158. // std::cmp::PartialOrd is required for the comparison with T::zero(), but Complex does not implement it
  159. // so why does the next impl conflicts?
  160. impl<T> std::fmt::Display for Polynomial<T>
  161. where
  162.     T: Num + Clone + std::ops::Neg<Output = T> + std::cmp::PartialOrd + std::fmt::Display,
  163. {
  164.     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  165.         let mut formatted_string: String = String::new();
  166.         let mut is_first_term: bool = true;
  167.  
  168.         for (degree, coefficient) in self.coefficients.iter().enumerate().rev() {
  169.             if coefficient != &T::zero() {
  170.                 let mut coefficient: T = coefficient.clone();
  171.                 let is_neg: bool = coefficient < T::zero();
  172.                 let sign: &str = if is_neg {
  173.                     coefficient = -coefficient;
  174.                     "- "
  175.                 } else {
  176.                     "+ "
  177.                 };
  178.  
  179.                 if is_first_term {
  180.                     if is_neg {
  181.                         formatted_string.push_str(sign);
  182.                     }
  183.                     is_first_term = false;
  184.                 } else {
  185.                     formatted_string.push(' ');
  186.                     formatted_string.push_str(sign);
  187.                 }
  188.  
  189.                 let formatted: String = match degree {
  190.                     0 => format!("{}", coefficient),
  191.                     1 => format!("{}x", coefficient),
  192.                     _ => format!("{}x^{}", coefficient, degree),
  193.                 };
  194.  
  195.                 formatted_string.push_str(&formatted);
  196.             }
  197.         }
  198.  
  199.         write!(f, "{}", formatted_string)
  200.     }
  201. }
  202.  
  203. // Why does this not work?
  204. impl std::fmt::Display for Polynomial<num::Complex<f64>> {
  205.     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  206.         // Implement custom formatting for Polynomial<num::Complex<f64>> here
  207.         write!(f, "Your custom formatting for Complex<f64> polynomials")
  208.     }
  209. }
  210.  
  211. fn main() {
  212.     let c1 = num::Complex::new(1.0, 2.0);
  213.     let c2 = num::Complex::new(3.0, 4.0);
  214.     let c3 = c1 + c2;
  215.  
  216.     let p1: Polynomial<_> = Polynomial::from_coefficients(vec![c1, c2, c3]);
  217.     let p2: Polynomial<_> = Polynomial::from_coefficients(vec![c1, c2, c3]);
  218.  
  219.     println!("{:?}", p1);
  220.     println!("{:?}", p2);
  221.  
  222.     let p3: Polynomial<_> = p1.clone() + p2.clone();
  223.     let p4: Polynomial<_> = p1.clone() - p2.clone();
  224.     let p5: Polynomial<_> = p1 * p2;
  225.  
  226.     println!("{:}", p3);
  227.     println!("{:}", p4);
  228.     println!("{:}", p5);
  229. }
  230.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement