//! complex number library use num::{One, Zero}; use std::fmt::{Display, Formatter, Result}; use std::ops::{Add, Mul, Neg, Sub}; /// complex number definition. #[derive(Clone, Copy, Debug, PartialEq)] pub struct Complex(pub i64, pub i64); // According to https://doc.rust-lang.org/std/fmt/trait.Display.html // Display is similar to Debug, but Display is for user-facing output, and so cannot be derived. impl Display for Complex { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "({}, {}i)", self.0, self.1) } } // https://docs.rs/num/latest/num/trait.Zero.html impl Zero for Complex { fn zero() -> Self { ZERO } fn is_zero(&self) -> bool { *self == ZERO } } // https://docs.rs/num/latest/num/trait.One.html impl One for Complex { fn one() -> Self { ONE } } impl Mul for Complex { type Output = Self; fn mul(self, other: Self) -> Self { Self( self.0 * other.0 - self.1 * other.1, self.0 * other.1 + self.1 * other.0, ) } } impl Add for Complex { type Output = Self; fn add(self, other: Self) -> Self { Self(self.0 + other.0, self.1 + other.1) } } impl Sub for Complex { type Output = Self; fn sub(self, other: Self) -> Self { Self(self.0 - other.0, self.1 - other.1) } } impl Neg for Complex { type Output = Self; fn neg(self) -> Self { ZERO - self } } /// the complex one: (1, 0) pub const ONE: Complex = Complex(1, 0); /// the complex zero: (0, 0) pub const ZERO: Complex = Complex(0, 0); /// the conjugate of a+bi is a-bi pub fn conjugate(c: Complex) -> Complex { Complex(c.0, -c.1) } impl From<(i32, i32)> for Complex { fn from(item: (i32, i32)) -> Self { Complex(item.0.into(), item.1.into()) } } impl From<(i64, i64)> for Complex { fn from(item: (i64, i64)) -> Self { Complex(item.0, item.1) } } #[cfg(test)] mod tests { use super::*; #[test] fn it_works() { let result = 2 + 2; assert_eq!(result, 4); } #[test] fn add_works() { assert_eq!(Complex(1, 2) + Complex(3, 4), Complex(4, 6)); } #[test] fn mul_works() { assert_eq!(Complex(3, 4) * Complex(5, 6), Complex(-9, 38)); } #[test] fn sub_works() { assert_eq!(Complex(1, 2) - Complex(3, 4), Complex(-2, -2)); } #[test] fn neg_works() { assert_eq!(-Complex(-1, 1), Complex(1, -1)); } #[test] fn zero_works() { assert_eq!(-ZERO, ZERO); assert_eq!(ZERO + ZERO, ZERO); assert_eq!(ZERO - ZERO, ZERO); } #[test] fn one_works() { assert_eq!(Complex(3, 4) * ONE, Complex(3, 4)); assert_eq!(ONE * Complex(3, 4), Complex(3, 4)); } #[test] fn four_quadrant() { let _ = vec![ Complex(1, 1), Complex(-1, 1), Complex(-1, -1), Complex(1, -1), ]; } }