use super::super::meta;
use super::{
Buffer, BufferBorrow, ComplexFreqVec, ComplexTimeVec, DataDomain, Domain, DspVec, ErrorReason,
FromVector, GenDspVec, MetaData, NumberSpace, RealFreqVec, RealTimeVec, ToSlice, TypeMetaData,
};
use super::{Resize, ToComplexVector, ToDspVector, ToRealVector, ToSliceMut, VoidResult};
use crate::multicore_support::MultiCoreSettings;
use crate::numbers::*;
use crate::simd_extensions::*;
use std::mem;
use std::result;
fn round_len(len: usize) -> usize {
fn get_reg_len<T: RealNumber, Reg: SimdGeneric<T>>(_: RegType<Reg>) -> usize {
Reg::LEN
}
let reg_len = sel_reg!(get_reg_len::<f32>());
((len + reg_len - 1) / reg_len) * reg_len
}
pub trait InterleaveToVector<T>: ToSlice<T>
where
T: RealNumber,
{
fn interleave_to_complex_time_vec(
&self,
other: &Self,
) -> result::Result<ComplexTimeVec<Vec<T>, T>, ErrorReason>;
fn interleave_to_complex_freq_vec(
&self,
other: &Self,
) -> result::Result<ComplexFreqVec<Vec<T>, T>, ErrorReason>;
}
pub struct SingleBufferBurrow<'a, T: RealNumber + 'a> {
owner: &'a mut SingleBuffer<T>,
}
impl<'a, T: RealNumber + 'a> ToSlice<T> for SingleBufferBurrow<'a, T> {
fn to_slice(&self) -> &[T] {
&self.owner.temp.to_slice()
}
fn len(&self) -> usize {
self.owner.temp.len()
}
fn is_empty(&self) -> bool {
self.owner.temp.is_empty()
}
fn alloc_len(&self) -> usize {
self.owner.temp.alloc_len()
}
fn try_resize(&mut self, len: usize) -> VoidResult {
self.owner.temp.try_resize(len)
}
}
impl<'a, T: RealNumber + 'a> ToSliceMut<T> for SingleBufferBurrow<'a, T> {
fn to_slice_mut(&mut self) -> &mut [T] {
self.owner.temp.to_slice_mut()
}
}
impl<'a, T: RealNumber> BufferBorrow<Vec<T>, T> for SingleBufferBurrow<'a, T> {
fn trade(self, storage: &mut Vec<T>) {
mem::swap(&mut self.owner.temp, storage);
}
}
#[derive(Default)]
pub struct SingleBuffer<T>
where
T: RealNumber,
{
temp: Vec<T>,
}
impl<T> SingleBuffer<T>
where
T: RealNumber,
{
pub fn new() -> SingleBuffer<T> {
SingleBuffer { temp: Vec::new() }
}
pub fn with_capacity(len: usize) -> SingleBuffer<T> {
SingleBuffer {
temp: vec![T::zero(); len],
}
}
}
impl<'a, T> Buffer<'a, Vec<T>, T> for SingleBuffer<T>
where
T: RealNumber + 'a,
{
type Borrow = SingleBufferBurrow<'a, T>;
fn borrow(&'a mut self, len: usize) -> Self::Borrow {
self.temp
.try_resize(len)
.expect("Resizing a Vec must be possible");
SingleBufferBurrow { owner: self }
}
fn alloc_len(&self) -> usize {
self.temp.capacity()
}
}
pub struct NoBuffer;
pub struct NoBufferBurrow<T: RealNumber> {
data: Vec<T>,
}
impl<T: RealNumber> ToSlice<T> for NoBufferBurrow<T> {
fn to_slice(&self) -> &[T] {
self.data.to_slice()
}
fn len(&self) -> usize {
self.data.len()
}
fn is_empty(&self) -> bool {
self.data.is_empty()
}
fn alloc_len(&self) -> usize {
self.data.alloc_len()
}
fn try_resize(&mut self, len: usize) -> VoidResult {
self.data.try_resize(len)
}
}
impl<T: RealNumber> ToSliceMut<T> for NoBufferBurrow<T> {
fn to_slice_mut(&mut self) -> &mut [T] {
self.data.to_slice_mut()
}
}
impl<'a, T: RealNumber> BufferBorrow<Vec<T>, T> for NoBufferBurrow<T> {
fn trade(mut self, storage: &mut Vec<T>) {
mem::swap(&mut self.data, storage);
}
}
impl<'a, T> Buffer<'a, Vec<T>, T> for NoBuffer
where
T: RealNumber,
{
type Borrow = NoBufferBurrow<T>;
fn borrow(&mut self, len: usize) -> Self::Borrow {
NoBufferBurrow {
data: vec![T::zero(); len],
}
}
fn alloc_len(&self) -> usize {
0
}
}
pub type RealTimeVec32 = DspVec<Vec<f32>, f32, meta::Real, meta::Time>;
pub type RealFreqVec32 = DspVec<Vec<f32>, f32, meta::Real, meta::Freq>;
pub type ComplexTimeVec32 = DspVec<Vec<f32>, f32, meta::Complex, meta::Time>;
pub type ComplexFreqVec32 = DspVec<Vec<f32>, f32, meta::Complex, meta::Freq>;
pub type GenDspVec32 = DspVec<Vec<f32>, f32, meta::RealOrComplex, meta::TimeOrFreq>;
pub type RealTimeVec64 = DspVec<Vec<f64>, f64, meta::Real, meta::Time>;
pub type RealFreqVec64 = DspVec<Vec<f64>, f64, meta::Real, meta::Freq>;
pub type ComplexTimeVec64 = DspVec<Vec<f64>, f64, meta::Complex, meta::Time>;
pub type ComplexFreqVec64 = DspVec<Vec<f64>, f64, meta::Complex, meta::Freq>;
pub type GenDspVec64 = DspVec<Vec<f64>, f64, meta::RealOrComplex, meta::TimeOrFreq>;
impl<T> ToSlice<T> for Vec<T>
where
T: RealNumber,
{
fn to_slice(&self) -> &[T] {
self
}
fn len(&self) -> usize {
self.len()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
fn alloc_len(&self) -> usize {
self.capacity()
}
fn try_resize(&mut self, len: usize) -> VoidResult {
self.resize(len, T::zero());
Ok(())
}
}
impl<T> ToSliceMut<T> for Vec<T>
where
T: RealNumber,
{
fn to_slice_mut(&mut self) -> &mut [T] {
&mut self[..]
}
}
impl<T> Resize for Vec<T>
where
T: RealNumber,
{
fn resize(&mut self, len: usize) {
self.resize(len, T::zero());
}
}
impl<T> ToSlice<T> for Box<[T]> {
fn to_slice(&self) -> &[T] {
self
}
fn len(&self) -> usize {
(**self).len()
}
fn is_empty(&self) -> bool {
(**self).is_empty()
}
fn alloc_len(&self) -> usize {
self.len()
}
fn try_resize(&mut self, len: usize) -> VoidResult {
if len > self.len() {
Err(ErrorReason::TypeCanNotResize)
} else {
Ok(())
}
}
}
impl<T> ToSliceMut<T> for Box<[T]> {
fn to_slice_mut(&mut self) -> &mut [T] {
self
}
}
impl<T> ToDspVector<T> for Vec<T>
where
T: RealNumber,
{
fn to_gen_dsp_vec(self, is_complex: bool, domain: DataDomain) -> GenDspVec<Self, T> {
let mut len = self.len();
if len % 2 != 0 && is_complex {
len = 0;
}
GenDspVec {
data: self,
delta: T::one(),
domain: meta::TimeOrFreq {
domain_current: domain,
},
number_space: meta::RealOrComplex {
is_complex_current: is_complex,
},
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
fn to_dsp_vec<N, D>(self, meta_data: &TypeMetaData<T, N, D>) -> DspVec<Self, T, N, D>
where
N: NumberSpace,
D: Domain,
{
let mut len = self.len();
if len % 2 != 0 && meta_data.is_complex() {
len = 0;
}
DspVec {
data: self,
delta: meta_data.delta,
domain: meta_data.domain.clone(),
number_space: meta_data.number_space.clone(),
valid_len: len,
multicore_settings: meta_data.multicore_settings,
}
}
}
impl<T> ToRealVector<T> for Vec<T>
where
T: RealNumber,
{
fn to_real_time_vec(mut self) -> RealTimeVec<Self, T> {
let len = self.len();
expand_to_full_capacity(&mut self);
RealTimeVec {
data: self,
delta: T::one(),
domain: meta::Time,
number_space: meta::Real,
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
fn to_real_freq_vec(mut self) -> RealFreqVec<Self, T> {
let len = self.len();
expand_to_full_capacity(&mut self);
RealFreqVec {
data: self,
delta: T::one(),
domain: meta::Freq,
number_space: meta::Real,
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
}
impl<T> ToComplexVector<Vec<T>, T> for Vec<T>
where
T: RealNumber,
{
fn to_complex_time_vec(mut self) -> ComplexTimeVec<Self, T> {
let len = self.len();
expand_to_full_capacity(&mut self);
ComplexTimeVec {
data: self,
delta: T::one(),
domain: meta::Time,
number_space: meta::Complex,
valid_len: if len % 2 == 0 { len } else { 0 },
multicore_settings: MultiCoreSettings::default(),
}
}
fn to_complex_freq_vec(mut self) -> ComplexFreqVec<Self, T> {
let len = self.len();
expand_to_full_capacity(&mut self);
ComplexFreqVec {
data: self,
delta: T::one(),
domain: meta::Freq,
number_space: meta::Complex,
valid_len: if len % 2 == 0 { len } else { 0 },
multicore_settings: MultiCoreSettings::default(),
}
}
}
impl<T> ToComplexVector<Vec<T>, T> for Vec<Complex<T>>
where
T: RealNumber,
{
fn to_complex_time_vec(self) -> ComplexTimeVec<Vec<T>, T> {
let len = self.len();
let vec = complex_vec_to_interleaved_vec(self);
ComplexTimeVec {
data: vec,
delta: T::one(),
domain: meta::Time,
number_space: meta::Complex,
valid_len: 2 * len,
multicore_settings: MultiCoreSettings::default(),
}
}
fn to_complex_freq_vec(self) -> ComplexFreqVec<Vec<T>, T> {
let len = self.len();
let vec = complex_vec_to_interleaved_vec(self);
ComplexFreqVec {
data: vec,
delta: T::one(),
domain: meta::Freq,
number_space: meta::Complex,
valid_len: 2 * len,
multicore_settings: MultiCoreSettings::default(),
}
}
}
impl<T> ToDspVector<T> for Box<[T]>
where
T: RealNumber,
{
fn to_gen_dsp_vec(self, is_complex: bool, domain: DataDomain) -> GenDspVec<Self, T> {
let mut len = self.len();
if len % 2 != 0 && is_complex {
len = 0;
}
GenDspVec {
data: self,
delta: T::one(),
domain: meta::TimeOrFreq {
domain_current: domain,
},
number_space: meta::RealOrComplex {
is_complex_current: is_complex,
},
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
fn to_dsp_vec<N, D>(self, meta_data: &TypeMetaData<T, N, D>) -> DspVec<Self, T, N, D>
where
N: NumberSpace,
D: Domain,
{
let mut len = self.len();
if len % 2 != 0 && meta_data.is_complex() {
len = 0;
}
DspVec {
data: self,
delta: meta_data.delta,
domain: meta_data.domain.clone(),
number_space: meta_data.number_space.clone(),
valid_len: len,
multicore_settings: meta_data.multicore_settings,
}
}
}
impl<T> ToRealVector<T> for Box<[T]>
where
T: RealNumber,
{
fn to_real_time_vec(self) -> RealTimeVec<Self, T> {
let len = self.len();
RealTimeVec {
data: self,
delta: T::one(),
domain: meta::Time,
number_space: meta::Real,
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
fn to_real_freq_vec(self) -> RealFreqVec<Self, T> {
let len = self.len();
RealFreqVec {
data: self,
delta: T::one(),
domain: meta::Freq,
number_space: meta::Real,
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
}
impl<T> ToComplexVector<Box<[T]>, T> for Box<[T]>
where
T: RealNumber,
{
fn to_complex_time_vec(self) -> ComplexTimeVec<Self, T> {
let mut len = self.len();
if len % 2 != 0 {
len = 0;
}
ComplexTimeVec {
data: self,
delta: T::one(),
domain: meta::Time,
number_space: meta::Complex,
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
fn to_complex_freq_vec(self) -> ComplexFreqVec<Self, T> {
let mut len = self.len();
if len % 2 != 0 {
len = 0;
}
ComplexFreqVec {
data: self,
delta: T::one(),
domain: meta::Freq,
number_space: meta::Complex,
valid_len: len,
multicore_settings: MultiCoreSettings::default(),
}
}
}
impl<Type, T> InterleaveToVector<T> for Type
where
Type: ToSlice<T>,
T: RealNumber,
{
fn interleave_to_complex_time_vec(
&self,
other: &Self,
) -> result::Result<ComplexTimeVec<Vec<T>, T>, ErrorReason> {
if self.len() != other.len() {
return Err(ErrorReason::InputMustHaveTheSameSize);
}
let rounded_len = round_len(self.len() + other.len());
let mut data = Vec::with_capacity(rounded_len);
let len = self.len();
let real = self.to_slice();
let imag = other.to_slice();
for i in 0..len {
data.push(real[i]);
data.push(imag[i]);
}
let data_length = data.len();
Ok(ComplexTimeVec {
data,
delta: T::one(),
domain: meta::Time,
number_space: meta::Complex,
valid_len: data_length,
multicore_settings: MultiCoreSettings::default(),
})
}
fn interleave_to_complex_freq_vec(
&self,
other: &Self,
) -> result::Result<ComplexFreqVec<Vec<T>, T>, ErrorReason> {
if self.len() != other.len() {
return Err(ErrorReason::InputMustHaveTheSameSize);
}
let rounded_len = round_len(self.len() + other.len());
let mut data = Vec::with_capacity(rounded_len);
let len = self.len();
let real = self.to_slice();
let imag = other.to_slice();
for i in 0..len {
data.push(real[i]);
data.push(imag[i]);
}
let data_length = data.len();
Ok(ComplexFreqVec {
data,
delta: T::one(),
domain: meta::Freq,
number_space: meta::Complex,
valid_len: data_length,
multicore_settings: MultiCoreSettings::default(),
})
}
}
impl<T, D> FromVector<T> for DspVec<Vec<T>, T, meta::Complex, D>
where
T: RealNumber,
D: Domain,
{
type Output = Vec<Complex<T>>;
fn get(self) -> (Self::Output, usize) {
let len = self.valid_len / 2;
(interleaved_vec_to_complex_vec(self.data), len)
}
}
impl<T, D> From<DspVec<Vec<T>, T, meta::Real, D>> for Vec<T>
where
T: RealNumber,
D: Domain,
{
fn from(mut vector: DspVec<Vec<T>, T, meta::Real, D>) -> Self {
let len = vector.valid_len;
vector.data.truncate(len);
vector.data
}
}
impl<T, D> From<DspVec<Vec<T>, T, meta::Complex, D>> for Vec<Complex<T>>
where
T: RealNumber,
D: Domain,
{
fn from(mut vector: DspVec<Vec<T>, T, meta::Complex, D>) -> Self {
let len = vector.valid_len;
vector.data.truncate(len);
interleaved_vec_to_complex_vec(vector.data)
}
}
fn expand_to_full_capacity<T>(vec: &mut Vec<T>)
where
T: Zero,
{
while vec.len() < vec.capacity() {
vec.push(T::zero());
}
}
fn complex_vec_to_interleaved_vec<T>(mut vec: Vec<Complex<T>>) -> Vec<T>
where
T: RealNumber,
{
expand_to_full_capacity(&mut vec);
let boxed = vec.into_boxed_slice();
let len = boxed.len();
unsafe {
let mut trans: Box<[T]> = mem::transmute(boxed);
let vec = Vec::<T>::from_raw_parts(&mut trans[0] as *mut T, len * 2, len * 2);
mem::forget(trans); vec
}
}
fn interleaved_vec_to_complex_vec<T>(mut vec: Vec<T>) -> Vec<Complex<T>>
where
T: RealNumber,
{
expand_to_full_capacity(&mut vec);
let boxed = vec.into_boxed_slice();
let len = boxed.len();
unsafe {
let mut trans: Box<[Complex<T>]> = mem::transmute(boxed);
let vec =
Vec::<Complex<T>>::from_raw_parts(&mut trans[0] as *mut Complex<T>, len / 2, len / 2);
mem::forget(trans); vec
}
}
#[cfg(test)]
mod tests {
use super::super::*;
use super::complex_vec_to_interleaved_vec;
use crate::conv_types::*;
use num_complex::Complex32;
#[test]
fn complex_vec_to_interleaved_vec_test() {
let complex = vec![Complex32::new(0.0, 0.0); 5];
let real = complex_vec_to_interleaved_vec(complex);
assert_eq!(real.len(), 10);
assert_eq!(
&real[..],
&[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
);
}
#[test]
fn vec_into_test_real() {
let mut dsp_vec = vec![0.0; 100].to_real_time_vec();
let mut buffer = SingleBuffer::new();
assert_eq!(dsp_vec.points(), 100);
assert_eq!(dsp_vec.len(), 100);
dsp_vec
.interpolatei(&mut buffer, &RaisedCosineFunction::new(0.35), 2)
.unwrap();
assert_eq!(dsp_vec.points(), 200);
assert_eq!(dsp_vec.len(), 200);
let vec: Vec<f64> = dsp_vec.into();
assert_eq!(vec.len(), 200);
}
#[test]
fn vec_into_test_complex() {
let mut dsp_vec = vec![0.0; 100].to_complex_time_vec();
let mut buffer = SingleBuffer::new();
assert_eq!(dsp_vec.points(), 50);
assert_eq!(dsp_vec.len(), 100);
dsp_vec
.interpolatei(&mut buffer, &RaisedCosineFunction::new(0.35), 2)
.unwrap();
assert_eq!(dsp_vec.points(), 100);
assert_eq!(dsp_vec.len(), 200);
let vec: Vec<Complex<f64>> = dsp_vec.into();
assert_eq!(vec.len(), 100);
}
}