1use num_complex::Complex64;
4use std::ops::{Add, AddAssign};
5
6#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
10#[repr(transparent)]
11pub struct Phase(u8);
12
13impl Phase {
14 pub const ONE: Self = Self(0);
16 pub const I: Self = Self(1);
18 pub const MINUS_ONE: Self = Self(2);
20 pub const MINUS_I: Self = Self(3);
22
23 #[inline]
25 pub const fn new(k: u8) -> Self {
26 Self(k & 3)
27 }
28
29 #[inline]
31 pub const fn exponent(self) -> u8 {
32 self.0
33 }
34
35 #[inline]
37 pub fn to_complex(self) -> Complex64 {
38 match self.0 {
39 0 => Complex64::new(1.0, 0.0),
40 1 => Complex64::new(0.0, 1.0),
41 2 => Complex64::new(-1.0, 0.0),
42 3 => Complex64::new(0.0, -1.0),
43 _ => unreachable!(),
44 }
45 }
46
47 #[inline]
49 pub fn apply(self, c: Complex64) -> Complex64 {
50 match self.0 {
51 0 => c,
52 1 => Complex64::new(-c.im, c.re),
53 2 => Complex64::new(-c.re, -c.im),
54 3 => Complex64::new(c.im, -c.re),
55 _ => unreachable!(),
56 }
57 }
58}
59
60impl Add for Phase {
61 type Output = Phase;
62 #[inline]
63 fn add(self, other: Phase) -> Phase {
64 Phase((self.0 + other.0) & 3)
65 }
66}
67
68impl AddAssign for Phase {
69 #[inline]
70 fn add_assign(&mut self, other: Phase) {
71 *self = *self + other;
72 }
73}
74
75#[cfg(test)]
76mod tests;