computorv1/src/maths.rs

175 lines
4.2 KiB
Rust
Raw Normal View History

use std::ops;
//TODO slow ? check Stein's algorithm (binaryGCD)
fn gcd(a: i128, b: i128) -> i128 {
if b == 0 {
a
} else {
gcd(b, a % b)
}
}
2023-08-03 10:16:17 +00:00
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Rational {
numerator: i128,
denominator: i128,
}
impl Rational {
pub fn new(numerator: i128, denominator: i128) -> Self {
Self {
numerator,
denominator,
}
}
pub fn reduce(&self) -> Self {
let gcd = gcd(self.numerator, self.denominator);
Rational::new(self.numerator / gcd, self.denominator / gcd)
}
2023-08-03 10:16:17 +00:00
pub fn inverse(&self) -> Self {
Rational::new(self.denominator, self.numerator)
}
}
impl ops::Add<Rational> for Rational {
type Output = Rational;
fn add(self, rhs: Rational) -> Rational {
Rational::new(self.numerator * rhs.denominator + rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce()
}
}
impl ops::Add<i128> for Rational {
type Output = Rational;
fn add(self, rhs: i128) -> Rational {
Rational::new(self.numerator + rhs * self.denominator, self.denominator).reduce()
}
}
impl ops::Add<Rational> for i128 {
type Output = Rational;
fn add(self, rhs: Rational) -> Rational {
Rational::new(self * rhs.denominator + rhs.numerator, rhs.denominator).reduce()
}
}
impl ops::Sub<Rational> for Rational {
type Output = Rational;
fn sub(self, rhs: Rational) -> Rational {
Rational::new(self.numerator * rhs.denominator - rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce()
}
}
2023-08-03 10:16:17 +00:00
impl ops::Sub<i128> for Rational {
type Output = Rational;
fn sub(self, rhs: i128) -> Rational {
Rational::new(self.numerator - rhs * self.denominator, self.denominator).reduce()
}
}
impl ops::Sub<Rational> for i128 {
type Output = Rational;
fn sub(self, rhs: Rational) -> Rational {
Rational::new(self * rhs.denominator - rhs.numerator, rhs.denominator).reduce()
}
}
impl ops::Mul<Rational> for Rational {
type Output = Rational;
fn mul(self, rhs: Rational) -> Rational {
Rational::new(self.numerator * rhs.numerator, self.denominator * rhs.denominator).reduce()
}
}
impl ops::Mul<i128> for Rational {
type Output = Rational;
fn mul(self, rhs: i128) -> Rational {
Rational::new(self.numerator * rhs, self.denominator).reduce()
}
}
impl ops::Mul<Rational> for i128 {
type Output = Rational;
fn mul(self, rhs: Rational) -> Rational {
Rational::new(self * rhs.numerator, rhs.denominator).reduce()
}
}
2023-08-03 10:16:17 +00:00
impl ops::Div<Rational> for Rational {
type Output = Rational;
fn div(self, rhs: Rational) -> Rational {
self * rhs.inverse()
}
}
impl ops::Div<i128> for Rational {
type Output = Rational;
fn div(self, rhs: i128) -> Rational {
let rhs_inverse = Rational::new(1, rhs);
self * rhs_inverse
}
}
impl ops::Div<Rational> 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,
}
impl GaussianRational {
pub fn new(real: Rational, imaginary: Rational) -> Self {
Self {
real,
imaginary,
}
}
2023-08-03 10:16:17 +00:00
pub fn conjugate(&self) -> Self {
GaussianRational::new(self.real, -1 * self.imaginary)
}
}
impl ops::Add<GaussianRational> for GaussianRational {
type Output = GaussianRational;
fn add(self, rhs: GaussianRational) -> GaussianRational {
GaussianRational::new(self.real + rhs.real, self.imaginary + rhs.imaginary)
}
}
impl ops::Sub<GaussianRational> for GaussianRational {
type Output = GaussianRational;
fn sub(self, rhs: GaussianRational) -> GaussianRational {
GaussianRational::new(self.real - rhs.real, self.imaginary - rhs.imaginary)
}
}
impl ops::Mul<GaussianRational> 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)
}
}