use num_complex::Complex64;
use std::ops::{Add, AddAssign};
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[repr(transparent)]
pub struct Phase(u8);
impl Phase {
pub const ONE: Self = Self(0);
pub const I: Self = Self(1);
pub const MINUS_ONE: Self = Self(2);
pub const MINUS_I: Self = Self(3);
#[inline]
pub const fn new(k: u8) -> Self {
Self(k & 3)
}
#[inline]
pub const fn exponent(self) -> u8 {
self.0
}
#[inline]
pub fn to_complex(self) -> Complex64 {
match self.0 {
0 => Complex64::new(1.0, 0.0),
1 => Complex64::new(0.0, 1.0),
2 => Complex64::new(-1.0, 0.0),
3 => Complex64::new(0.0, -1.0),
_ => unreachable!(),
}
}
#[inline]
pub fn apply(self, c: Complex64) -> Complex64 {
match self.0 {
0 => c,
1 => Complex64::new(-c.im, c.re),
2 => Complex64::new(-c.re, -c.im),
3 => Complex64::new(c.im, -c.re),
_ => unreachable!(),
}
}
}
impl Add for Phase {
type Output = Phase;
#[inline]
fn add(self, other: Phase) -> Phase {
Phase((self.0 + other.0) & 3)
}
}
impl AddAssign for Phase {
#[inline]
fn add_assign(&mut self, other: Phase) {
*self = *self + other;
}
}
#[cfg(test)]
mod tests;