use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
use crate::sparse_mat::SMat;
use num::{complex::ComplexFloat, Complex};
#[derive(Debug, Clone)]
pub struct SQS {
pub mat: SMat,
pub n: u32,
}
impl SQS {
pub fn new(n: u32) -> Self {
let mat = SMat::zeros((1, n));
Self { mat, n }
}
pub fn set(&self, i: u32, v: Complex<f32>) {
if i > self.n {
panic!(
"attempting to set value at index {} but length is {}",
i, self.n
);
}
self.mat.set_unchecked(1, i, v);
}
pub fn get(&self, i: u32) -> Complex<f32> {
if i > self.n {
panic!(
"attempting to get value at index {} but length is {}",
i, self.n
);
}
self.mat.get_unchecked(1, i)
}
pub fn dot(&self, rhs: &SMat) -> Self {
Self {
mat: self.mat.dot(rhs),
n: self.n,
}
}
pub fn to_vec(&self) -> Vec<Complex<f32>> {
(0..self.n).map(|x| self.get(x)).collect()
}
pub fn fill_zero(&mut self) {
*self = Self::new(self.n);
}
pub fn iter(&self) -> SQSIterator {
SQSIterator { sqs: self, n: 0 }
}
}
pub struct SQSIterator<'a> {
sqs: &'a SQS,
n: u32,
}
impl Iterator for SQSIterator<'_> {
type Item = Complex<f32>;
fn next(&mut self) -> Option<Self::Item> {
if self.n >= self.sqs.n {
return None;
}
let r = Some(self.sqs.get(self.n));
self.n += 1;
r
}
}
unsafe impl Send for SQS {}
unsafe impl Sync for SQS {}
impl Add for SQS {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
if self.n != rhs.n {
panic!("SQSs must be of the same length to be added.");
}
let c = self.clone();
for i in 0..rhs.n {
c.set(i, c.get(i) + rhs.get(i));
}
c
}
}
impl Sub for SQS {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
if self.n != rhs.n {
panic!("SQSs must be of the same length to be added.");
}
let c = self.clone();
for i in 0..rhs.n {
c.set(i, c.get(i) - rhs.get(i));
}
c
}
}
impl Mul<Complex<f32>> for SQS {
type Output = Self;
fn mul(self, rhs: Complex<f32>) -> Self::Output {
let c = self.clone();
for i in 0..c.n {
c.set(i, c.get(i) * rhs);
}
c
}
}
impl Div<Complex<f32>> for SQS {
type Output = Self;
fn div(self, rhs: Complex<f32>) -> Self::Output {
let c = self.clone();
let k = rhs.recip();
for i in 0..c.n {
c.set(i, c.get(i) * k);
}
c
}
}
impl AddAssign for SQS {
fn add_assign(&mut self, rhs: Self) {
if self.n != rhs.n {
panic!("SQSs must be of the same length to be added.");
}
for i in 0..self.n {
self.set(i, self.get(i) + rhs.get(i));
}
}
}
impl SubAssign for SQS {
fn sub_assign(&mut self, rhs: Self) {
if self.n != rhs.n {
panic!("SQSs must be of the same length to be added.");
}
for i in 0..self.n {
self.set(i, self.get(i) - rhs.get(i));
}
}
}
impl MulAssign<Complex<f32>> for SQS {
fn mul_assign(&mut self, rhs: Complex<f32>) {
for i in 0..self.n {
self.set(i, self.get(i) * rhs);
}
}
}
impl DivAssign<Complex<f32>> for SQS {
fn div_assign(&mut self, rhs: Complex<f32>) {
let k = rhs.recip();
for i in 0..self.n {
self.set(i, self.get(i) * k);
}
}
}