From 22d92252354cde38ac8f50287d3021b91ed917f1 Mon Sep 17 00:00:00 2001 From: gbrochar Date: Thu, 3 Aug 2023 12:16:17 +0200 Subject: [PATCH] feat(maths): basic ops overloading --- src/maths.rs | 77 ++++++++++++++++++++++++++++++++++++++- src/parser/ast_builder.rs | 4 +- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/maths.rs b/src/maths.rs index 9d34d34..2d7aee8 100644 --- a/src/maths.rs +++ b/src/maths.rs @@ -9,7 +9,7 @@ fn gcd(a: i128, b: i128) -> i128 { } } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Copy)] pub struct Rational { numerator: i128, denominator: i128, @@ -27,6 +27,10 @@ impl Rational { let gcd = gcd(self.numerator, self.denominator); Rational::new(self.numerator / gcd, self.denominator / gcd) } + + pub fn inverse(&self) -> Self { + Rational::new(self.denominator, self.numerator) + } } impl ops::Add for Rational { @@ -61,6 +65,22 @@ impl ops::Sub for Rational { } } +impl ops::Sub for Rational { + type Output = Rational; + + fn sub(self, rhs: i128) -> Rational { + Rational::new(self.numerator - rhs * self.denominator, self.denominator).reduce() + } +} + +impl ops::Sub for i128 { + type Output = Rational; + + fn sub(self, rhs: Rational) -> Rational { + Rational::new(self * rhs.denominator - rhs.numerator, rhs.denominator).reduce() + } +} + impl ops::Mul for Rational { type Output = Rational; @@ -85,7 +105,32 @@ impl ops::Mul for i128 { } } -#[derive(Debug, PartialEq, Clone)] +impl ops::Div for Rational { + type Output = Rational; + + fn div(self, rhs: Rational) -> Rational { + self * rhs.inverse() + } +} + +impl ops::Div for Rational { + type Output = Rational; + + fn div(self, rhs: i128) -> Rational { + let rhs_inverse = Rational::new(1, rhs); + self * rhs_inverse + } +} + +impl ops::Div for i128 { + type Output = Rational; + + fn div(self, rhs: Rational) -> Rational { + self * rhs.inverse() + } +} + +#[derive(Debug, PartialEq, Clone, Copy)] pub struct GaussianRational { real: Rational, imaginary: Rational, @@ -98,4 +143,32 @@ impl GaussianRational { imaginary, } } + + pub fn conjugate(&self) -> Self { + GaussianRational::new(self.real, -1 * self.imaginary) + } +} + +impl ops::Add for GaussianRational { + type Output = GaussianRational; + + fn add(self, rhs: GaussianRational) -> GaussianRational { + GaussianRational::new(self.real + rhs.real, self.imaginary + rhs.imaginary) + } +} + +impl ops::Sub for GaussianRational { + type Output = GaussianRational; + + fn sub(self, rhs: GaussianRational) -> GaussianRational { + GaussianRational::new(self.real - rhs.real, self.imaginary - rhs.imaginary) + } +} + +impl ops::Mul for GaussianRational { + type Output = GaussianRational; + + fn mul(self, rhs: GaussianRational) -> GaussianRational { + GaussianRational::new(self.real * rhs.real - self.imaginary * self.imaginary, self.real * rhs.imaginary + self.imaginary * rhs.real) + } } diff --git a/src/parser/ast_builder.rs b/src/parser/ast_builder.rs index 550b86f..cadc4cb 100644 --- a/src/parser/ast_builder.rs +++ b/src/parser/ast_builder.rs @@ -377,8 +377,8 @@ mod tests { let tokens = vec![two_token(), plus(), two_token()]; let results = Node::Internal { operator: plus(), - lhs: Box::new(Node::Leaf(vec![two.clone()])), - rhs: Box::new(Node::Leaf(vec![two.clone()])) + lhs: Box::new(Node::Leaf(vec![two])), + rhs: Box::new(Node::Leaf(vec![two])) }; assert_eq!(build_ast(tokens), results);