#[cfg(any(feature = "doc", feature="use_sse", feature="use_avx"))]
extern crate simd;
#[cfg(any(feature = "doc", feature="use_gpu"))]
extern crate ocl;
#[cfg(feature="std")]
extern crate num_cpus;
#[cfg(feature="std")]
extern crate crossbeam;
extern crate num_traits;
extern crate num_complex;
extern crate rustfft;
#[cfg(any(feature = "doc", feature="use_gpu"))]
extern crate clfft;
extern crate arrayvec;
mod vector_types;
mod multicore_support;
mod simd_extensions;
pub mod window_functions;
pub mod conv_types;
pub use vector_types::*;
pub use multicore_support::MultiCoreSettings;
mod gpu_support;
use std::mem;
mod inline_vector;
use numbers::*;
use std::ops::Range;
pub mod numbers {
pub use num_traits::Float;
pub use num_traits::One;
pub use num_complex::Complex;
pub use num_traits::Num;
use std::fmt::Debug;
use num_traits;
use simd_extensions::*;
use gpu_support::{Gpu32, Gpu64, GpuRegTrait, GpuFloat};
use std::ops::*;
pub trait DspNumber
: Num + Copy + Clone + Send + Sync + ToSimd + Debug + num_traits::Signed + num_traits::FromPrimitive + 'static
{
}
impl<T> DspNumber for T
where T: Num + Copy + Clone + Send + Sync + ToSimd + Debug + num_traits::Signed + num_traits::FromPrimitive + 'static
{
}
pub trait ToSimd: Sized + Sync + Send {
type Reg: Simd<Self> + SimdGeneric<Self> + SimdApproximations<Self> + Copy + Sync + Send + Add<Output = Self::Reg> + Sub<Output = Self::Reg> + Mul<Output = Self::Reg> + Div<Output = Self::Reg> + Zero;
type GpuReg: GpuRegTrait;
}
impl ToSimd for f32 {
type Reg = Reg32;
type GpuReg = Gpu32;
}
impl ToSimd for f64 {
type Reg = Reg64;
type GpuReg = Gpu64;
}
pub trait RealNumber: Float + DspNumber + GpuFloat + num_traits::FloatConst {}
impl<T> RealNumber for T where T: Float + DspNumber + GpuFloat + num_traits::FloatConst {}
pub trait Zero {
fn zero() -> Self;
}
impl<T> Zero for T
where T: DspNumber
{
fn zero() -> Self {
<Self as num_traits::Zero>::zero()
}
}
impl<T> Zero for Complex<T>
where T: DspNumber
{
fn zero() -> Self {
<Self as num_traits::Zero>::zero()
}
}
}
fn array_to_complex<T>(array: &[T]) -> &[Complex<T>] {
unsafe {
let len = array.len();
if len % 2 != 0 {
panic!("Argument must have an even length");
}
let trans: &[Complex<T>] = mem::transmute(array);
&trans[0..len / 2]
}
}
fn array_to_complex_mut<T>(array: &mut [T]) -> &mut [Complex<T>] {
unsafe {
let len = array.len();
if len % 2 != 0 {
panic!("Argument must have an even length");
}
let trans: &mut [Complex<T>] = mem::transmute(array);
&mut trans[0..len / 2]
}
}
fn memcpy<T: Copy>(data: &mut [T], from: Range<usize>, to: usize) {
use std::ptr::copy;
assert!(from.start <= from.end);
assert!(from.end <= data.len());
assert!(to <= data.len() - (from.end - from.start));
unsafe {
let ptr = data.as_mut_ptr();
copy(ptr.offset(from.start as isize),
ptr.offset(to as isize),
from.end - from.start)
}
}
fn memzero<T: Copy>(data: &mut [T], range: Range<usize>) {
use std::ptr::write_bytes;
assert!(range.start <= range.end);
assert!(range.end <= data.len());
unsafe {
let ptr = data.as_mut_ptr();
write_bytes(ptr.offset(range.start as isize), 0, range.end - range.start);
}
}
#[cfg(test)]
mod tests {
use super::*;
use simd_extensions::Simd;
#[test]
fn to_simd_test() {
let reg = <f32 as ToSimd>::Reg::splat(1.0);
let sum = reg.sum_real();
assert!(sum > 0.0);
}
}