use super::{Stream, Tag};
use num_complex::Complex;
pub struct Rotate {
rot: Complex<f32>,
mult: Complex<f32>,
}
impl Rotate {
pub fn new(angle: f32) -> Self {
Self {
rot: Complex::new(1.0, 0.0),
mult: Complex::new(angle.cos(), angle.sin()),
}
}
pub fn set_rotation(&mut self, angle: f32) {
self.mult = Complex::new(angle.cos(), angle.sin());
}
pub fn receive_dual(
&mut self,
data: &[Complex<f32>],
_tag: &mut Tag,
) -> (Vec<Complex<f32>>, Vec<Complex<f32>>) {
let mut output_up = Vec::with_capacity(data.len());
let mut output_down = Vec::with_capacity(data.len());
for &sample in data {
let rr = sample.re * self.rot.re;
let ii = sample.im * self.rot.im;
let ri = sample.re * self.rot.im;
let ir = sample.im * self.rot.re;
output_up.push(Complex::new(rr - ii, ir + ri));
output_down.push(Complex::new(rr + ii, ir - ri));
self.rot *= self.mult;
}
let norm = self.rot.norm();
if norm > 0.0 {
self.rot /= norm;
}
(output_up, output_down)
}
}
impl Stream<Complex<f32>, Complex<f32>> for Rotate {
fn receive(&mut self, data: &[Complex<f32>], tag: &mut Tag) -> Vec<Complex<f32>> {
let (up, _down) = self.receive_dual(data, tag);
up
}
fn reset(&mut self) {
self.rot = Complex::new(1.0, 0.0);
}
}