Advertisement
BilakshanP

Error at 2nd last LOC: cannot add `Polynomial<i32>` to `Polynomial<i32>`

Mar 9th, 2024 (edited)
1,527
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 10.43 KB | Source Code | 0 0
  1. pub mod traits {
  2.     //////////////// generated using following macro:
  3.     //
  4.     // #[macro_export]
  5.     // macro_rules! bundle_traits {
  6.     //     ( $trait_name:ident, $($traits:path),+ ) => {
  7.     //         trait $trait_name: $($traits +)+ {}
  8.     //         impl<T: $($traits +)+> $trait_name for T {}
  9.     //     };
  10.     //
  11.     //     ( pub $trait_name:ident, $($traits:path),+ ) => {
  12.     //         pub trait $trait_name: $($traits +)+ {}
  13.     //         impl<T: $($traits +)+> $trait_name for T {}
  14.     //     };
  15.     // }
  16.     //
  17.     //////////////// used as:
  18.     //
  19.     // bundle_traits!(
  20.     //     pub Numeric,
  21.     //     Copy,
  22.     //     Default,
  23.     //     std::ops::Add<Output = Self>,
  24.     //     std::ops::Sub<Output = Self>,
  25.     //     std::ops::Mul<Output = Self>,
  26.     //     std::ops::Div<Output = Self>,
  27.     //     std::ops::Rem<Output = Self>,
  28.     //     std::ops::Neg<Output = Self>,
  29.     //     num::One,
  30.     //     num::Zero,
  31.     //     std::fmt::Debug
  32.     // );
  33.     // bundle_traits!(
  34.     //     pub NumericExtended,
  35.     //     Numeric,
  36.     //     Ord,
  37.     //     PartialEq,
  38.     //     PartialOrd,
  39.     //     std::ops::AddAssign,
  40.     //     std::ops::SubAssign,
  41.     //     std::ops::MulAssign,
  42.     //     std::ops::DivAssign,
  43.     //     std::ops::RemAssign,
  44.     //     std::ops::ShlAssign<u32>,
  45.     //     std::ops::ShrAssign<u32>,
  46.     //     std::ops::BitAndAssign,
  47.     //     std::ops::BitOrAssign,
  48.     //     std::ops::BitXorAssign,
  49.     //     std::ops::Not,
  50.     //     std::ops::Shl<u32, Output = Self>,
  51.     //     std::ops::Shr<u32, Output = Self>,
  52.     //     std::ops::BitAnd<Output = Self>,
  53.     //     std::ops::BitOr<Output = Self>,
  54.     //     std::ops::BitXor<Output = Self>,
  55.     //     num::traits::Pow<u32, Output = Self>,
  56.     //     From<u8>
  57.     // );
  58.     //
  59.     ///////////////// expand code using "cargo expand"
  60.     //
  61.     //////////////// OUTPUT:
  62.  
  63.     pub trait Numeric:
  64.         Copy
  65.         + Default
  66.         + std::ops::Add<Output = Self>
  67.         + std::ops::Sub<Output = Self>
  68.         + std::ops::Mul<Output = Self>
  69.         + std::ops::Div<Output = Self>
  70.         + std::ops::Rem<Output = Self>
  71.         + std::ops::Neg<Output = Self>
  72.         + num::One
  73.         + num::Zero
  74.         + std::fmt::Debug
  75.     {
  76.     }
  77.     impl<
  78.             T: Copy
  79.                 + Default
  80.                 + std::ops::Add<Output = Self>
  81.                 + std::ops::Sub<Output = Self>
  82.                 + std::ops::Mul<Output = Self>
  83.                 + std::ops::Div<Output = Self>
  84.                 + std::ops::Rem<Output = Self>
  85.                 + std::ops::Neg<Output = Self>
  86.                 + num::One
  87.                 + num::Zero
  88.                 + std::fmt::Debug,
  89.         > Numeric for T
  90.     {
  91.     }
  92.     pub trait NumericExtended:
  93.         Numeric
  94.         + Ord
  95.         + PartialEq
  96.         + PartialOrd
  97.         + std::ops::AddAssign
  98.         + std::ops::SubAssign
  99.         + std::ops::MulAssign
  100.         + std::ops::DivAssign
  101.         + std::ops::RemAssign
  102.         + std::ops::ShlAssign<u32>
  103.         + std::ops::ShrAssign<u32>
  104.         + std::ops::BitAndAssign
  105.         + std::ops::BitOrAssign
  106.         + std::ops::BitXorAssign
  107.         + std::ops::Not
  108.         + std::ops::Shl<u32, Output = Self>
  109.         + std::ops::Shr<u32, Output = Self>
  110.         + std::ops::BitAnd<Output = Self>
  111.         + std::ops::BitOr<Output = Self>
  112.         + std::ops::BitXor<Output = Self>
  113.         + num::traits::Pow<u32, Output = Self>
  114.         + From<u8>
  115.     {
  116.     }
  117.     impl<
  118.             T: Numeric
  119.                 + Ord
  120.                 + PartialEq
  121.                 + PartialOrd
  122.                 + std::ops::AddAssign
  123.                 + std::ops::SubAssign
  124.                 + std::ops::MulAssign
  125.                 + std::ops::DivAssign
  126.                 + std::ops::RemAssign
  127.                 + std::ops::ShlAssign<u32>
  128.                 + std::ops::ShrAssign<u32>
  129.                 + std::ops::BitAndAssign
  130.                 + std::ops::BitOrAssign
  131.                 + std::ops::BitXorAssign
  132.                 + std::ops::Not
  133.                 + std::ops::Shl<u32, Output = Self>
  134.                 + std::ops::Shr<u32, Output = Self>
  135.                 + std::ops::BitAnd<Output = Self>
  136.                 + std::ops::BitOr<Output = Self>
  137.                 + std::ops::BitXor<Output = Self>
  138.                 + num::traits::Pow<u32, Output = Self>
  139.                 + From<u8>,
  140.         > NumericExtended for T
  141.     {
  142.     }
  143. }
  144.  
  145. // use vectra::traits::{Numeric, NumericExtended};
  146.  
  147. use traits::{Numeric, NumericExtended};
  148.  
  149. #[derive(Clone, Debug)]
  150. pub struct Polynomial<T: Numeric> {
  151.     degree: usize,
  152.     coefficients: Vec<T>,
  153. }
  154.  
  155. impl<T: Numeric> Default for Polynomial<T> {
  156.     fn default() -> Self {
  157.         Self {
  158.             degree: 0,
  159.             coefficients: vec![T::zero(); 1],
  160.         }
  161.     }
  162. }
  163.  
  164. impl<T: Numeric> Polynomial<T> {
  165.     pub fn new() -> Self {
  166.         Self::default()
  167.     }
  168.  
  169.     pub fn from_coefficients(coefficients: Vec<T>) -> Self {
  170.         let degree: usize = coefficients.len() - 1;
  171.         Self {
  172.             degree,
  173.             coefficients,
  174.         }
  175.     }
  176.  
  177.     pub fn degree(&self) -> usize {
  178.         self.degree
  179.     }
  180.  
  181.     pub fn coefficients(&self) -> &Vec<T> {
  182.         &self.coefficients
  183.     }
  184.  
  185.     pub fn get_degree(&self) -> usize {
  186.         self.degree
  187.     }
  188.  
  189.     pub fn get_coefficient(&self, degree: usize) -> T {
  190.         if degree > self.degree {
  191.             T::zero()
  192.         } else {
  193.             self.coefficients[degree]
  194.         }
  195.     }
  196.  
  197.     pub fn get_coefficients(&self) -> &Vec<T> {
  198.         &self.coefficients
  199.     }
  200.  
  201.     pub fn set_degree(&mut self, degree: usize) {
  202.         if degree > self.degree {
  203.             self.degree = degree;
  204.             self.coefficients.resize(degree + 1, T::zero());
  205.         }
  206.     }
  207.  
  208.     pub fn set_coefficient(&mut self, degree: usize, coefficient: T) {
  209.         self.set_degree(degree);
  210.         self.coefficients[degree] = coefficient;
  211.     }
  212. }
  213.  
  214. impl<T: NumericExtended> Polynomial<T> {
  215.     pub fn evaluate(&self, x: T) -> T {
  216.         let mut result: T = T::zero();
  217.         for (i, coefficient) in self.coefficients.iter().enumerate() {
  218.             result = result + *coefficient * x.pow((self.degree - i) as u32);
  219.         }
  220.         result
  221.     }
  222. }
  223.  
  224. impl<T: std::ops::Add<Output = T> + Numeric> Polynomial<T> {
  225.     pub fn add(&self, other: &Self) -> Self {
  226.         let mut result: Polynomial<T> = Self::new();
  227.         result.set_degree(self.degree.max(other.degree));
  228.  
  229.         for i in 0..=result.degree {
  230.             result.set_coefficient(i, self.get_coefficient(i) + other.get_coefficient(i));
  231.         }
  232.  
  233.         result
  234.     }
  235. }
  236.  
  237. impl<T: std::ops::Sub<Output = T> + Numeric> Polynomial<T> {
  238.     pub fn sub(&self, other: &Self) -> Self {
  239.         let mut result: Polynomial<T> = Self::new();
  240.         result.set_degree(self.degree.max(other.degree));
  241.  
  242.         for i in 0..=result.degree {
  243.             result.set_coefficient(i, self.get_coefficient(i) - other.get_coefficient(i));
  244.         }
  245.  
  246.         result
  247.     }
  248. }
  249.  
  250. impl<T: std::ops::Mul<Output = T> + Numeric> Polynomial<T> {
  251.     pub fn mul(&self, other: &Self) -> Self {
  252.         let mut result: Polynomial<T> = Self::new();
  253.         result.set_degree(self.degree * other.degree);
  254.  
  255.         for i in 0..=self.degree {
  256.             for j in 0..=other.degree {
  257.                 result.set_coefficient(
  258.                     i + j,
  259.                     result.get_coefficient(i + j)
  260.                         + self.get_coefficient(i) * other.get_coefficient(j),
  261.                 );
  262.             }
  263.         }
  264.  
  265.         result
  266.     }
  267. }
  268.  
  269. impl<T: std::fmt::Display + Numeric> Polynomial<T> {
  270.     pub fn display(&self) {
  271.         let mut formatted_string = String::new();
  272.  
  273.         for (i, coefficient) in self.coefficients.iter().enumerate() {
  274.             if i == 0 {
  275.                 formatted_string.push_str(&format!("{}", coefficient));
  276.             } else {
  277.                 formatted_string.push_str(&format!(" + {}x^{}", coefficient, i));
  278.             }
  279.         }
  280.  
  281.         println!("{}", formatted_string);
  282.     }
  283. }
  284.  
  285. impl<T: std::fmt::Display + NumericExtended> std::fmt::Display for Polynomial<T> {
  286.     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  287.         let mut formatted_string = String::new();
  288.  
  289.         let mut is_first_term = true;
  290.  
  291.         for (degree, coefficient) in self.coefficients.iter().enumerate().rev() {
  292.             if coefficient != &T::zero() {
  293.                 let mut coefficient = *coefficient;
  294.                 let is_neg = coefficient < T::zero();
  295.                 let sign = if is_neg {
  296.                     coefficient = -coefficient;
  297.                     "- "
  298.                 } else {
  299.                     "+ "
  300.                 };
  301.  
  302.                 if is_first_term {
  303.                     if is_neg {
  304.                         formatted_string.push_str(sign);
  305.                     }
  306.                     is_first_term = false;
  307.                 } else {
  308.                     formatted_string.push(' ');
  309.                     formatted_string.push_str(sign);
  310.                 }
  311.  
  312.                 if degree == 0 {
  313.                     formatted_string.push_str(&format!("{}", coefficient));
  314.                 } else if degree == 1 {
  315.                     formatted_string.push_str(&format!("{}x", coefficient));
  316.                 } else {
  317.                     formatted_string.push_str(&format!("{}x^{}", coefficient, degree));
  318.                 }
  319.             }
  320.         }
  321.  
  322.         write!(f, "{}", formatted_string)
  323.     }
  324. }
  325.  
  326. fn main() {
  327.     let mut p1: Polynomial<i32> = Polynomial::new();
  328.     let mut p2: Polynomial<i32> = Polynomial::new();
  329.  
  330.     p1.set_coefficient(2, 3);
  331.     p1.set_coefficient(1, 2);
  332.     p1.set_coefficient(0, 1);
  333.  
  334.     p2.set_coefficient(3, 4);
  335.     p2.set_coefficient(2, 3);
  336.     p2.set_coefficient(1, 2);
  337.     p2.set_coefficient(0, 1);
  338.  
  339.     println!("p1: {}", p1);
  340.     println!("p2: {}", p2);
  341.  
  342.     let p3 = p1.add(&p2);
  343.     let p4 = p1.sub(&p2);
  344.     let p5 = p1.mul(&p2);
  345.  
  346.     println!("p1 + p2: {}", p3);
  347.     println!("p1 - p2: {}", p4);
  348.     println!("p1 * p2: {}", p5);
  349.  
  350.     let a = p1 + p1;    // cannot add `Polynomial<i32>` to `Polynomial<i32>`rustc Click for full compiler diagnostic
  351.                         // main.rs(350, 13): Polynomial<i32>
  352.                         // main.rs(350, 18): Polynomial<i32>
  353.                         // main.rs(150, 1): an implementation of `std::ops::Add` might be missing for `Polynomial<i32>`
  354.                         // arith.rs(76, 1): the trait `std::ops::Add` must be implemented
  355. }
  356.  
Tags: maths
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement