extern crate libc;
extern crate num;
use array::Array;
use defines::{AfError, ConvDomain, ConvMode, InterpType};
use error::HANDLE_ERROR;
use self::num::Complex;
use self::libc::{c_uint, c_int, c_float, c_double, c_longlong, size_t};
use util::{ComplexFloating, FloatingPoint, HasAfEnum, RealFloating};
use util::{AfArray, MutAfArray};
#[allow(dead_code)]
extern {
fn af_approx1(out: MutAfArray, inp: AfArray, pos: AfArray,
method: c_int, off_grid: c_float) -> c_int;
fn af_approx2(out: MutAfArray, inp: AfArray, pos0: AfArray, pos1: AfArray,
method: c_int, off_grid: c_float) -> c_int;
fn af_set_fft_plan_cache_size(cache_size: size_t) -> c_int;
fn af_fft(out: MutAfArray, arr: AfArray,
nfac: c_double, odim0: c_longlong) -> c_int;
fn af_fft2(out: MutAfArray, arr: AfArray, nfac: c_double,
odim0: c_longlong, odim1: c_longlong) -> c_int;
fn af_fft3(out: MutAfArray, arr: AfArray, nfac: c_double,
odim0: c_longlong, odim1: c_longlong, odim2: c_longlong) -> c_int;
fn af_ifft(out: MutAfArray, arr: AfArray,
nfac: c_double, odim0: c_longlong) -> c_int;
fn af_ifft2(out: MutAfArray, arr: AfArray, nfac: c_double,
odim0: c_longlong, odim1: c_longlong) -> c_int;
fn af_ifft3(out: MutAfArray, arr: AfArray, nfac: c_double,
odim0: c_longlong, odim1: c_longlong, odim2: c_longlong) -> c_int;
fn af_fft_inplace(arr: AfArray, nfac: c_double) -> c_int;
fn af_fft2_inplace(arr: AfArray, nfac: c_double) -> c_int;
fn af_fft3_inplace(arr: AfArray, nfac: c_double) -> c_int;
fn af_ifft_inplace(arr: AfArray, nfac: c_double) -> c_int;
fn af_ifft2_inplace(arr: AfArray, nfac: c_double) -> c_int;
fn af_ifft3_inplace(arr: AfArray, nfac: c_double) -> c_int;
fn af_fft_r2c(out: MutAfArray, arr: AfArray,
nfac: c_double, pad0: c_longlong) -> c_int;
fn af_fft2_r2c(out: MutAfArray, arr: AfArray,
nfac: c_double, pad0: c_longlong, pad1: c_longlong) -> c_int;
fn af_fft3_r2c(out: MutAfArray, arr: AfArray,
nfac: c_double, pad0: c_longlong, pad1: c_longlong, pad2: c_longlong) -> c_int;
fn af_fft_c2r(out: MutAfArray, input: AfArray, nfac: c_double, is_odd: c_int) -> c_int;
fn af_fft2_c2r(out: MutAfArray, input: AfArray, nfac: c_double, is_odd: c_int) -> c_int;
fn af_fft3_c2r(out: MutAfArray, input: AfArray, nfac: c_double, is_odd: c_int) -> c_int;
fn af_convolve1(out: MutAfArray, s: AfArray, f: AfArray, m: c_uint, d: c_uint) -> c_int;
fn af_convolve2(out: MutAfArray, s: AfArray, f: AfArray, m: c_uint, d: c_uint) -> c_int;
fn af_convolve3(out: MutAfArray, s: AfArray, f: AfArray, m: c_uint, d: c_uint) -> c_int;
fn af_convolve2_sep(o: MutAfArray, c: AfArray, r: AfArray, s: AfArray, m: c_uint) -> c_int;
fn af_fft_convolve1(out: MutAfArray, s: AfArray, f: AfArray, m: c_uint) -> c_int;
fn af_fft_convolve2(out: MutAfArray, s: AfArray, f: AfArray, m: c_uint) -> c_int;
fn af_fft_convolve3(out: MutAfArray, s: AfArray, f: AfArray, m: c_uint) -> c_int;
fn af_fir(out: MutAfArray, b: AfArray, x: AfArray) -> c_int;
fn af_iir(out: MutAfArray, b: AfArray, a: AfArray, x: AfArray) -> c_int;
}
#[allow(unused_mut)]
pub fn approx1<T, P>(input: &Array<T>, pos: &Array<P>,
method: InterpType, off_grid: f32) -> Array<T>
where T: HasAfEnum + FloatingPoint,
P: HasAfEnum + RealFloating
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_approx1(&mut temp as MutAfArray, input.get() as AfArray,
pos.get() as AfArray, method as c_int, off_grid as c_float);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn approx2<T, P>(input: &Array<T>, pos0: &Array<P>, pos1: &Array<P>,
method: InterpType, off_grid: f32) -> Array<T>
where T: HasAfEnum + FloatingPoint,
P: HasAfEnum + RealFloating
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_approx2(&mut temp as MutAfArray, input.get() as AfArray,
pos0.get() as AfArray, pos1.get() as AfArray,
method as c_int, off_grid as c_float);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn set_fft_plan_cache_size(cache_size: usize) {
unsafe {
let err_val = af_set_fft_plan_cache_size(cache_size as size_t);
HANDLE_ERROR(AfError::from(err_val));
}
}
#[allow(unused_mut)]
pub fn fft<T>(input: &Array<T>, norm_factor: f64,
odim0: i64) -> Array< T::ComplexOutType >
where T: HasAfEnum + FloatingPoint,
<T as HasAfEnum>::ComplexOutType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft(&mut temp as MutAfArray,
input.get() as AfArray, norm_factor as c_double,
odim0 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn fft2<T>(input: &Array<T>, norm_factor: f64,
odim0: i64, odim1: i64) -> Array< T::ComplexOutType >
where T: HasAfEnum + FloatingPoint,
<T as HasAfEnum>::ComplexOutType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft2(&mut temp as MutAfArray,
input.get() as AfArray, norm_factor as c_double,
odim0 as c_longlong, odim1 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn fft3<T>(input: &Array<T>, norm_factor: f64,
odim0: i64, odim1: i64, odim2: i64) -> Array< T::ComplexOutType >
where T: HasAfEnum + FloatingPoint,
<T as HasAfEnum>::ComplexOutType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft3(&mut temp as MutAfArray,
input.get() as AfArray, norm_factor as c_double,
odim0 as c_longlong, odim1 as c_longlong, odim2 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn ifft<T>(input: &Array<T>, norm_factor: f64, odim0: i64) -> Array< T::ComplexOutType >
where T: HasAfEnum + FloatingPoint,
<T as HasAfEnum>::ComplexOutType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_ifft(&mut temp as MutAfArray,
input.get() as AfArray, norm_factor as c_double,
odim0 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn ifft2<T>(input: &Array<T>, norm_factor: f64,
odim0: i64, odim1: i64) -> Array< T::ComplexOutType >
where T: HasAfEnum + FloatingPoint,
<T as HasAfEnum>::ComplexOutType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_ifft2(&mut temp as MutAfArray,
input.get() as AfArray, norm_factor as c_double,
odim0 as c_longlong, odim1 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn ifft3<T>(input: &Array<T>, norm_factor: f64,
odim0: i64, odim1: i64, odim2: i64) -> Array< T::ComplexOutType >
where T: HasAfEnum + FloatingPoint,
<T as HasAfEnum>::ComplexOutType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_ifft3(&mut temp as MutAfArray,
input.get() as AfArray, norm_factor as c_double,
odim0 as c_longlong, odim1 as c_longlong, odim2 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
macro_rules! conv_func_def {
($doc_str: expr, $fn_name:ident, $ffi_name: ident) => (
#[doc=$doc_str]
#[allow(unused_mut)]
pub fn $fn_name<T, F>(signal: &Array<T>, filter: &Array<F>,
mode: ConvMode, domain: ConvDomain) -> Array<T>
where T: HasAfEnum,
F: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = $ffi_name(&mut temp as MutAfArray,
signal.get() as AfArray, filter.get() as AfArray,
mode as c_uint, domain as c_uint);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
)
}
conv_func_def!("1d convolution", convolve1, af_convolve1);
conv_func_def!("2d convolution", convolve2, af_convolve2);
conv_func_def!("3d convolution", convolve3, af_convolve3);
#[allow(unused_mut)]
pub fn convolve2_sep<T, F>(cfilt: &Array<F>, rfilt: &Array<F>, signal: &Array<T>,
mode: ConvMode) -> Array<T>
where T: HasAfEnum,
F: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_convolve2_sep(&mut temp as MutAfArray,
cfilt.get() as AfArray, rfilt.get() as AfArray,
signal.get() as AfArray, mode as c_uint);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
macro_rules! fft_conv_func_def {
($doc_str: expr, $fn_name:ident, $ffi_name: ident) => (
#[doc=$doc_str]
#[allow(unused_mut)]
pub fn $fn_name<T, F>(signal: &Array<T>, filter: &Array<F>,
mode: ConvMode) -> Array<T>
where T: HasAfEnum,
F: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = $ffi_name(&mut temp as MutAfArray, signal.get() as AfArray,
filter.get() as AfArray, mode as c_uint);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
)
}
fft_conv_func_def!("1d convolution using fast-fourier transform", fft_convolve1, af_fft_convolve1);
fft_conv_func_def!("2d convolution using fast-fourier transform", fft_convolve2, af_fft_convolve2);
fft_conv_func_def!("3d convolution using fast-fourier transform", fft_convolve3, af_fft_convolve3);
#[allow(unused_mut)]
pub fn fir<B, X>(b: &Array<B>, x: &Array<X>) -> Array<X>
where B: HasAfEnum,
X: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fir(&mut temp as MutAfArray, b.get() as AfArray, x.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn iir<T: HasAfEnum>(b: &Array<T>, a: &Array<T>, x: &Array<T>) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_iir(&mut temp as MutAfArray,
b.get() as AfArray, a.get() as AfArray, x.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn fft_inplace<T>(input: &mut Array<T>, norm_factor: f64)
where T: HasAfEnum + ComplexFloating
{
unsafe {
let err_val = af_fft_inplace(input.get() as AfArray, norm_factor as c_double);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn fft2_inplace<T>(input: &mut Array<T>, norm_factor: f64)
where T: HasAfEnum + ComplexFloating
{
unsafe {
let err_val = af_fft2_inplace(input.get() as AfArray, norm_factor as c_double);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn fft3_inplace<T>(input: &mut Array<T>, norm_factor: f64)
where T: HasAfEnum + ComplexFloating
{
unsafe {
let err_val = af_fft3_inplace(input.get() as AfArray, norm_factor as c_double);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn ifft_inplace<T>(input: &mut Array<T>, norm_factor: f64)
where T: HasAfEnum + ComplexFloating
{
unsafe {
let err_val = af_ifft_inplace(input.get() as AfArray, norm_factor as c_double);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn ifft2_inplace<T>(input: &mut Array<T>, norm_factor: f64)
where T: HasAfEnum + ComplexFloating
{
unsafe {
let err_val = af_ifft2_inplace(input.get() as AfArray, norm_factor as c_double);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn ifft3_inplace<T>(input: &mut Array<T>, norm_factor: f64)
where T: HasAfEnum + ComplexFloating
{
unsafe {
let err_val = af_ifft3_inplace(input.get() as AfArray, norm_factor as c_double);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn fft_r2c<T>(input: &Array<T>, norm_factor: f64, pad0: i64) -> Array< Complex<T> >
where T: HasAfEnum + RealFloating,
Complex<T>: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft_r2c(&mut temp as MutAfArray, input.get() as AfArray,
norm_factor as c_double, pad0 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn fft2_r2c<T>(input: &Array<T>, norm_factor: f64,
pad0: i64, pad1: i64) -> Array< Complex<T> >
where T: HasAfEnum + RealFloating,
Complex<T>: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft2_r2c(&mut temp as MutAfArray, input.get() as AfArray,
norm_factor as c_double, pad0 as c_longlong, pad1 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn fft3_r2c<T>(input: &Array<T>, norm_factor: f64,
pad0: i64, pad1: i64, pad2: i64) -> Array< Complex<T> >
where T: HasAfEnum + RealFloating,
Complex<T>: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft3_r2c(&mut temp as MutAfArray, input.get() as AfArray,
norm_factor as c_double, pad0 as c_longlong,
pad1 as c_longlong, pad2 as c_longlong);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn fft_c2r<T>(input: &Array<T>,
norm_factor: f64, is_odd: bool) -> Array< T::BaseType >
where T: HasAfEnum + ComplexFloating,
<T as HasAfEnum>::BaseType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft_c2r(&mut temp as MutAfArray, input.get() as AfArray,
norm_factor as c_double, is_odd as c_int);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn fft2_c2r<T>(input: &Array<T>,
norm_factor: f64, is_odd: bool) -> Array< T::BaseType >
where T: HasAfEnum + ComplexFloating,
<T as HasAfEnum>::BaseType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft2_c2r(&mut temp as MutAfArray, input.get() as AfArray,
norm_factor as c_double, is_odd as c_int);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn fft3_c2r<T>(input: &Array<T>,
norm_factor: f64, is_odd: bool) -> Array< T::BaseType >
where T: HasAfEnum + ComplexFloating,
<T as HasAfEnum>::BaseType: HasAfEnum
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_fft3_c2r(&mut temp as MutAfArray, input.get() as AfArray,
norm_factor as c_double, is_odd as c_int);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}