reim/
lib.rs

1//! complex number library
2
3use num::{One, Zero};
4use std::fmt::{Display, Formatter, Result};
5use std::ops::{Add, Mul, Neg, Sub};
6
7/// complex number definition.
8#[derive(Clone, Copy, Debug, PartialEq)]
9pub struct Complex(pub i64, pub i64);
10
11// According to https://doc.rust-lang.org/std/fmt/trait.Display.html
12// Display is similar to Debug, but Display is for user-facing output, and so cannot be derived.
13impl Display for Complex {
14    fn fmt(&self, f: &mut Formatter) -> Result {
15        write!(f, "({}, {}i)", self.0, self.1)
16    }
17}
18
19// https://docs.rs/num/latest/num/trait.Zero.html
20impl Zero for Complex {
21    fn zero() -> Self {
22        ZERO
23    }
24    fn is_zero(&self) -> bool {
25        *self == ZERO
26    }
27}
28
29// https://docs.rs/num/latest/num/trait.One.html
30impl One for Complex {
31    fn one() -> Self {
32        ONE
33    }
34}
35
36impl Mul for Complex {
37    type Output = Self;
38
39    fn mul(self, other: Self) -> Self {
40        Self(
41            self.0 * other.0 - self.1 * other.1,
42            self.0 * other.1 + self.1 * other.0,
43        )
44    }
45}
46
47impl Add for Complex {
48    type Output = Self;
49
50    fn add(self, other: Self) -> Self {
51        Self(self.0 + other.0, self.1 + other.1)
52    }
53}
54
55impl Sub for Complex {
56    type Output = Self;
57
58    fn sub(self, other: Self) -> Self {
59        Self(self.0 - other.0, self.1 - other.1)
60    }
61}
62
63impl Neg for Complex {
64    type Output = Self;
65
66    fn neg(self) -> Self {
67        ZERO - self
68    }
69}
70
71/// the complex one: (1, 0)
72pub const ONE: Complex = Complex(1, 0);
73
74/// the complex zero: (0, 0)
75pub const ZERO: Complex = Complex(0, 0);
76
77/// the conjugate of a+bi is a-bi
78pub fn conjugate(c: Complex) -> Complex {
79    Complex(c.0, -c.1)
80}
81
82impl From<(i32, i32)> for Complex {
83    fn from(item: (i32, i32)) -> Self {
84        Complex(item.0.into(), item.1.into())
85    }
86}
87
88impl From<(i64, i64)> for Complex {
89    fn from(item: (i64, i64)) -> Self {
90        Complex(item.0, item.1)
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97
98    #[test]
99    fn it_works() {
100        let result = 2 + 2;
101        assert_eq!(result, 4);
102    }
103
104    #[test]
105    fn add_works() {
106        assert_eq!(Complex(1, 2) + Complex(3, 4), Complex(4, 6));
107    }
108
109    #[test]
110    fn mul_works() {
111        assert_eq!(Complex(3, 4) * Complex(5, 6), Complex(-9, 38));
112    }
113
114    #[test]
115    fn sub_works() {
116        assert_eq!(Complex(1, 2) - Complex(3, 4), Complex(-2, -2));
117    }
118
119    #[test]
120    fn neg_works() {
121        assert_eq!(-Complex(-1, 1), Complex(1, -1));
122    }
123
124    #[test]
125    fn zero_works() {
126        assert_eq!(-ZERO, ZERO);
127        assert_eq!(ZERO + ZERO, ZERO);
128        assert_eq!(ZERO - ZERO, ZERO);
129    }
130
131    #[test]
132    fn one_works() {
133        assert_eq!(Complex(3, 4) * ONE, Complex(3, 4));
134        assert_eq!(ONE * Complex(3, 4), Complex(3, 4));
135    }
136
137    #[test]
138    fn four_quadrant() {
139        let _ = vec![
140            Complex(1, 1),
141            Complex(-1, 1),
142            Complex(-1, -1),
143            Complex(1, -1),
144        ];
145    }
146}