#[macro_export]
macro_rules! declare_array_complex{
( $name:ident, $real_name:ident, $N:expr, $T:ty ) => {
integer_array::declare_array_real!($real_name, $N, $T);
#[derive(Copy, Clone, Default, Debug, PartialEq)]
pub struct $name{
pub data: [num::complex::Complex<$T>; $N],
}
impl $name {
#[allow(dead_code)]
fn new( real:$T, imag:$T ) -> Self {
let item = num::complex::Complex::new(real, imag);
$name {
data: [item;$N],
}
}
#[allow(dead_code)]
fn new_from_i32( real:i32, imag:i32 ) -> Self
{
let item = num::complex::Complex::new(<$T>::from_num(real), <$T>::from_num(imag));
$name {
data: [item;$N],
}
}
#[allow(dead_code)]
fn new_from_f32( real:f32, imag:f32 ) -> Self
{
let item = num::complex::Complex::new(<$T>::from_num(real), <$T>::from_num(imag));
$name {
data: [item;$N],
}
}
#[allow(dead_code)]
fn new_from_f64( real:f64, imag:f64 ) -> Self
{
let item = num::complex::Complex::new(<$T>::from_num(real), <$T>::from_num(imag));
$name {
data: [item;$N],
}
}
#[allow(dead_code)]
fn as_array_f32( &self ) -> [num::complex::Complex<f32>; $N]
{
let mut r_array: [num::complex::Complex<f32>; $N] = [num::complex::Complex::<f32>::new(0.0,0.0); $N];
for n in 0..$N {
r_array[n].re = self[n].re.to_num::<f32>();
r_array[n].im = self[n].im.to_num::<f32>();
}
return r_array;
}
#[allow(dead_code)]
fn as_array_i32( &self ) -> [num::complex::Complex<i32>; $N]
{
let mut r_array: [num::complex::Complex<i32>; $N] = [num::complex::Complex::<i32>::new(0,0); $N];
for n in 0..$N {
r_array[n].re = self[n].re.to_num::<i32>();
r_array[n].im = self[n].im.to_num::<i32>();
}
return r_array;
}
}
impl integer_array::trait_definitions::Len for $name {
fn len( &self ) -> usize {
return $N;
}
}
impl $name {
#[allow(dead_code)]
fn at( &self, index:usize) -> num::complex::Complex<$T> {
if( $N <= index)
{
return self.data[$N - 1];
}
return self.data[index];
}
#[allow(dead_code)]
fn front( &self ) -> num::complex::Complex<$T> {
return self.data[0];
}
#[allow(dead_code)]
fn back( &self ) -> num::complex::Complex<$T> {
return self.data[$N-1];
}
}
impl core::ops::Index<usize> for $name {
type Output = num::complex::Complex<$T>;
#[inline]
fn index(&self, index: usize) -> &num::complex::Complex<$T> {
return &self.data[index];
}
}
impl $name {
#[allow(dead_code)]
fn real( &self ) -> $real_name {
let mut r_array = $real_name::new_from_i32(0);
for n in 0..$N {
r_array[n] = self[n].re;
}
return r_array;
}
#[allow(dead_code)]
fn imag( &self ) -> $real_name {
let mut r_array = $real_name::new_from_i32(0);
for n in 0..$N {
r_array[n] = self[n].im;
}
return r_array;
}
#[allow(dead_code)]
fn mag( &self ) -> $real_name {
let mut r_array = $real_name::new_from_i32(0);
for n in 0..$N {
let re_pow = integer_array::utility::fixed_powi( self[n].re, 2 );
let im_pow = integer_array::utility::fixed_powi( self[n].im, 2 );
r_array[n] = integer_array::utility::sqrt(re_pow+im_pow, <$T>::from_num(0.001) );
}
return r_array;
}
#[allow(dead_code)]
fn arg( &self ) -> $real_name {
let mut r_array = $real_name::new_from_i32(0);
for n in 0..$N {
r_array[n] = integer_array::utility::atan2_precise_fixed( self[n].im, self[n].re );
}
return r_array;
}
}
impl $name {
#[allow(dead_code)]
fn odd(&self) -> [num::complex::Complex<$T>; $N/2] {
let mut r_array = [num::complex::Complex::<$T>::new( <$T>::from_num(0), <$T>::from_num(0) ); $N/2];
for n in 0..$N/2 {
r_array[n] = self[2*n+1];
}
return r_array;
}
#[allow(dead_code)]
fn even(&self) -> [num::complex::Complex<$T>; $N/2] {
let mut r_array = [num::complex::Complex::<$T>::new( <$T>::from_num(0), <$T>::from_num(0) ); $N/2];
for n in 0..$N/2 {
r_array[n] = self[2*n];
}
return r_array;
}
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn new() {
use crate as integer_array;
use fixed::{types::extra::U18, FixedI32};
use num::complex::Complex as C;
declare_array_complex!( CArr4, Arr4, 4, FixedI32<U18> );
let x = CArr4::new_from_i32( 1, 2 );
assert_eq!{ x.as_array_f32(), [ C{re:1.0, im:2.0}, C{re:1.0, im:2.0}, C{re:1.0, im:2.0}, C{re:1.0, im:2.0} ]};
}
#[test]
fn real() {
use crate as integer_array;
use fixed::{types::extra::U20, FixedI32};
integer_array::declare_array_complex!( CArr4, Arr4, 4, FixedI32<U20> );
let x = CArr4::new_from_i32( 1, 2 );
assert_eq!{ x.real(), Arr4::new_from_i32(1) };
}
}