Bläddra i källkod

:sparkles: Numeric trait and Complex struct

Felix Bytow 2 år sedan
förälder
incheckning
44a1b312d8
9 ändrade filer med 182 tillägg och 6 borttagningar
  1. 11 0
      CHANGELOG.md
  2. 1 1
      Cargo.toml
  3. 3 1
      src/lib.rs
  4. 3 1
      src/traits/float.rs
  5. 2 0
      src/traits/mod.rs
  6. 3 3
      src/traits/numeric.rs
  7. 30 0
      src/traits/primitive.rs
  8. 128 0
      src/types/complex.rs
  9. 1 0
      src/types/mod.rs

+ 11 - 0
CHANGELOG.md

@@ -0,0 +1,11 @@
+# Changelog
+
+## Release 0.2.0
+
+ - The `Numeric` trait combining all the traits we need from our numeric values.
+ - `Complex` number type with basic math operations.
+
+## Release 0.1.0
+
+ - Just a first test release to test publishing to Kellnr.
+ - Only feature is the small `Float` trait.

+ 1 - 1
Cargo.toml

@@ -1,7 +1,7 @@
 [package]
 name = "lineal"
 authors = ["Felix Bytow <drako@drako.guru>"]
-version = "0.1.0"
+version = "0.2.0"
 edition = "2021"
 publish = ["crates-drako-guru"]
 

+ 3 - 1
src/lib.rs

@@ -1,3 +1,5 @@
-pub use self::traits::{Float, Numeric};
+//! The crate is a LINEar ALgebra library.
+pub use self::traits::{Float, Numeric, Primitive};
 
 mod traits;
+mod types;

+ 3 - 1
src/traits/float.rs

@@ -1,5 +1,7 @@
+use std::ops::Neg;
+
 /// Marker trait, because certain operations only make sense on floating point types.
-pub trait Float {}
+pub trait Float: Neg<Output=Self> {}
 
 impl Float for f32 {}
 

+ 2 - 0
src/traits/mod.rs

@@ -1,5 +1,7 @@
 pub use self::float::Float;
 pub use self::numeric::Numeric;
+pub use self::primitive::Primitive;
 
 mod float;
 mod numeric;
+mod primitive;

+ 3 - 3
src/traits/numeric.rs

@@ -1,12 +1,12 @@
-use std::fmt::{Debug, Display};
+use std::fmt::Debug;
 use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
 
 /// Trait representing all numeric primitives.
 pub trait Numeric:
-Sized + Copy + Clone + Debug + Display +
+Sized + Copy + Clone + Debug +
 Add<Output=Self> + AddAssign + Sub<Output=Self> + SubAssign +
 Mul<Output=Self> + MulAssign + Div<Output=Self> + DivAssign +
-PartialEq + PartialOrd {
+PartialEq {
     /// Function returning the 0 value for the given type.
     fn zero() -> Self;
 

+ 30 - 0
src/traits/primitive.rs

@@ -0,0 +1,30 @@
+/// Marker trait for primitive types.
+pub trait Primitive {}
+
+impl Primitive for f32 {}
+
+impl Primitive for f64 {}
+
+impl Primitive for i8 {}
+
+impl Primitive for i16 {}
+
+impl Primitive for i32 {}
+
+impl Primitive for i64 {}
+
+impl Primitive for i128 {}
+
+impl Primitive for isize {}
+
+impl Primitive for u8 {}
+
+impl Primitive for u16 {}
+
+impl Primitive for u32 {}
+
+impl Primitive for u64 {}
+
+impl Primitive for u128 {}
+
+impl Primitive for usize {}

+ 128 - 0
src/types/complex.rs

@@ -0,0 +1,128 @@
+use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
+
+use crate::{Float, Numeric, Primitive};
+
+/// Struct representing a complex number.
+#[derive(Debug, Copy, Clone)]
+pub struct Complex<T: Float + Numeric + Primitive> {
+    real: T,
+    imag: T,
+}
+
+impl<T: Float + Numeric + Primitive> Add for Complex<T> {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self::Output {
+        Self {
+            real: self.real + rhs.real,
+            imag: self.imag + rhs.imag,
+        }
+    }
+}
+
+impl<T: Float + Numeric + Primitive> AddAssign for Complex<T> {
+    fn add_assign(&mut self, rhs: Self) {
+        self.real += rhs.real;
+        self.imag += rhs.imag;
+    }
+}
+
+impl<T: Float + Numeric + Primitive> Sub for Complex<T> {
+    type Output = Self;
+
+    fn sub(self, rhs: Self) -> Self::Output {
+        Self {
+            real: self.real - rhs.real,
+            imag: self.imag - rhs.imag,
+        }
+    }
+}
+
+impl<T: Float + Numeric + Primitive> SubAssign for Complex<T> {
+    fn sub_assign(&mut self, rhs: Self) {
+        self.real -= rhs.real;
+        self.imag -= rhs.imag;
+    }
+}
+
+impl<T: Float + Numeric + Primitive> Mul for Complex<T> {
+    type Output = Self;
+
+    fn mul(self, rhs: Self) -> Self::Output {
+        Complex {
+            real: self.real * rhs.real - self.imag * rhs.imag,
+            imag: self.real * rhs.imag + self.imag * rhs.real,
+        }
+    }
+}
+
+impl<T: Float + Numeric + Primitive> MulAssign for Complex<T> {
+    fn mul_assign(&mut self, rhs: Self) {
+        *self = *self * rhs;
+    }
+}
+
+impl<T: Float + Numeric + Primitive> Div for Complex<T> {
+    type Output = Self;
+
+    fn div(self, rhs: Self) -> Self::Output {
+        let divisor = rhs.real * rhs.real + rhs.imag * rhs.imag;
+        let mut result = self * Self { real: rhs.real, imag: -rhs.imag };
+        result.real /= divisor;
+        result.imag /= divisor;
+        return result;
+    }
+}
+
+impl<T: Float + Numeric + Primitive> DivAssign for Complex<T> {
+    fn div_assign(&mut self, rhs: Self) {
+        *self = *self / rhs;
+    }
+}
+
+impl<T: Float + Numeric + Primitive> Neg for Complex<T> {
+    type Output = Self;
+
+    fn neg(self) -> Self::Output {
+        Self {
+            real: -self.real,
+            imag: -self.imag,
+        }
+    }
+}
+
+impl<T: Float + Numeric + Primitive> PartialEq for Complex<T> {
+    fn eq(&self, other: &Self) -> bool {
+        self.real == other.real && self.imag == other.imag
+    }
+
+    fn ne(&self, other: &Self) -> bool {
+        self.real != other.real || self.imag != other.imag
+    }
+}
+
+impl<T: Float + Numeric + Primitive> Float for Complex<T> {}
+
+impl<T: Float + Numeric + Primitive> Numeric for Complex<T> {
+    fn zero() -> Self {
+        Self { real: T::zero(), imag: T::zero() }
+    }
+
+    fn one() -> Self {
+        Self { real: T::one(), imag: T::zero() }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::types::complex::Complex;
+
+    #[test]
+    fn division() {
+        let mut a: Complex<f32> = Complex { real: 3.0, imag: 2.0 };
+        let b: Complex<f32> = Complex { real: 4.0, imag: -5.0 };
+        let expected: Complex<f32> = Complex { real: 2.0 / 41.0, imag: 23.0 / 41.0 };
+        a /= b;
+        assert_eq!(format!("{:?}", a), format!("{:?}", expected));
+    }
+}

+ 1 - 0
src/types/mod.rs

@@ -0,0 +1 @@
+mod complex;