Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use num::{Num, Zero};
- #[derive(Clone)]
- pub struct Polynomial<T> {
- degree: usize,
- coefficients: Vec<T>,
- }
- impl<T> Default for Polynomial<T>
- where
- T: Num + Clone,
- {
- fn default() -> Self {
- Self {
- degree: 0,
- coefficients: vec![T::zero(); 1],
- }
- }
- }
- impl<T> Polynomial<T>
- where
- T: Num + Clone,
- {
- pub fn new() -> Self {
- Self::default()
- }
- }
- impl<T> Polynomial<T> {
- pub fn from_coefficients(coefficients: Vec<T>) -> Self {
- let degree: usize = coefficients.len() - 1;
- Self {
- degree,
- coefficients,
- }
- }
- pub fn degree(&self) -> usize {
- self.degree
- }
- pub fn coefficients(&self) -> &Vec<T> {
- &self.coefficients
- }
- }
- impl<T> Polynomial<T>
- where
- T: Num + Clone,
- {
- pub fn get_coefficient(&self, degree: usize) -> Option<T> {
- if degree > self.degree {
- None
- } else {
- Some(self.coefficients[degree].clone())
- }
- }
- pub fn set_degree(&mut self, degree: usize) {
- if degree > self.degree {
- self.degree = degree;
- self.coefficients.resize(degree + 1, T::zero());
- }
- }
- pub fn set_coefficient(&mut self, degree: usize, coefficient: T) {
- self.set_degree(degree);
- self.coefficients[degree] = coefficient;
- }
- }
- impl<T> std::ops::Add for Polynomial<T>
- where
- T: Num + Clone + Default,
- {
- type Output = Self;
- fn add(self, other: Self) -> Self {
- let mut result: Polynomial<T> = Self::new();
- result.set_degree(self.degree.max(other.degree));
- for i in 0..=result.degree {
- let c: T = self.get_coefficient(i).unwrap_or_default()
- + other.get_coefficient(i).unwrap_or_default();
- result.set_coefficient(i, c);
- }
- result
- }
- }
- impl<T> std::ops::Sub for Polynomial<T>
- where
- T: Num + Clone + Default,
- {
- type Output = Self;
- fn sub(self, other: Self) -> Self {
- let mut result: Polynomial<T> = Self::new();
- result.set_degree(self.degree.max(other.degree));
- for i in 0..=result.degree {
- let c: T = self.get_coefficient(i).unwrap_or_default()
- - other.get_coefficient(i).unwrap_or_default();
- result.set_coefficient(i, c);
- }
- result
- }
- }
- impl<T> std::ops::Mul for Polynomial<T>
- where
- T: Num + Clone + Default,
- {
- type Output = Self;
- fn mul(self, other: Self) -> Self {
- let mut result: Polynomial<T> = Self::new();
- result.set_degree(self.degree + other.degree);
- for i in 0..=self.degree {
- for j in 0..=other.degree {
- let c: T = result.get_coefficient(i + j).unwrap_or_default()
- + (self.get_coefficient(i).unwrap_or_default()
- * other.get_coefficient(j).unwrap_or_default());
- result.set_coefficient(i + j, c);
- }
- }
- result
- }
- }
- impl<T> std::fmt::Debug for Polynomial<T>
- where
- T: std::fmt::Debug,
- {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- let mut result: String = String::new();
- for (degree, coefficient) in self.coefficients.iter().enumerate().rev() {
- result.push_str(&format!("({}, {:?})", degree, coefficient));
- if degree > 0 {
- result.push_str(", ");
- }
- }
- write!(f, "[{}]", result)
- }
- }
- // std::cmp::PartialOrd is required for the comparison with T::zero(), but Complex does not implement it
- // so why does the next impl conflicts?
- impl<T> std::fmt::Display for Polynomial<T>
- where
- T: Num + Clone + std::ops::Neg<Output = T> + std::cmp::PartialOrd + std::fmt::Display,
- {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- let mut formatted_string: String = String::new();
- let mut is_first_term: bool = true;
- for (degree, coefficient) in self.coefficients.iter().enumerate().rev() {
- if coefficient != &T::zero() {
- let mut coefficient: T = coefficient.clone();
- let is_neg: bool = coefficient < T::zero();
- let sign: &str = if is_neg {
- coefficient = -coefficient;
- "- "
- } else {
- "+ "
- };
- if is_first_term {
- if is_neg {
- formatted_string.push_str(sign);
- }
- is_first_term = false;
- } else {
- formatted_string.push(' ');
- formatted_string.push_str(sign);
- }
- let formatted: String = match degree {
- 0 => format!("{}", coefficient),
- 1 => format!("{}x", coefficient),
- _ => format!("{}x^{}", coefficient, degree),
- };
- formatted_string.push_str(&formatted);
- }
- }
- write!(f, "{}", formatted_string)
- }
- }
- // Why does this not work?
- impl std::fmt::Display for Polynomial<num::Complex<f64>> {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- // Implement custom formatting for Polynomial<num::Complex<f64>> here
- write!(f, "Your custom formatting for Complex<f64> polynomials")
- }
- }
- fn main() {
- let c1 = num::Complex::new(1.0, 2.0);
- let c2 = num::Complex::new(3.0, 4.0);
- let c3 = c1 + c2;
- let p1: Polynomial<_> = Polynomial::from_coefficients(vec![c1, c2, c3]);
- let p2: Polynomial<_> = Polynomial::from_coefficients(vec![c1, c2, c3]);
- println!("{:?}", p1);
- println!("{:?}", p2);
- let p3: Polynomial<_> = p1.clone() + p2.clone();
- let p4: Polynomial<_> = p1.clone() - p2.clone();
- let p5: Polynomial<_> = p1 * p2;
- println!("{:}", p3);
- println!("{:}", p4);
- println!("{:}", p5);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement