///
/// This file is part of ILNumerics Community Edition.
///
/// ILNumerics Community Edition - high performance computing for applications.
/// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
///
/// ILNumerics Community Edition is free software: you can redistribute it and/or modify
/// it under the terms of the GNU General Public License version 3 as published by
/// the Free Software Foundation.
///
/// ILNumerics Community Edition is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with ILNumerics Community Edition. See the file License.txt in the root
/// of your distribution package. If not, see .
///
/// In addition this software uses the following components and/or licenses:
///
/// =================================================================================
/// The Open Toolkit Library License
///
/// Copyright (c) 2006 - 2009 the Open Toolkit library.
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights to
/// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
/// the Software, and to permit persons to whom the Software is furnished to do
/// so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all
/// copies or substantial portions of the Software.
///
/// =================================================================================
///
#pragma warning disable 1591
using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using ILNumerics.Exceptions;
using ILNumerics.Misc;
namespace ILNumerics.Native {
///
/// Wrapper for FFT interface using FFTW3 libs
///
public unsafe class ILFFTW3FFT : IILFFT, IDisposable {
#region pinvoke definitions
///
/// This struct is used to define (n-dimensional) transform sizes
///
/// This struct is only user in C-API. It is NOT used for the Fortran interface (i.e. it's not used in here)!!!
[StructLayout(LayoutKind.Sequential)]
private struct fftw_iodim {
///
/// length of dimension
///
public int n;
///
/// input stride
///
public int iS;
///
/// output stride
///
public int oS;
}
#region DOUBLE PRECISION INTERFACE ********* COMPLEX
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_1d_(ref IntPtr plan, ref int n, [In,Out] complex* input, [In,Out] complex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] complex* input, [In,Out] complex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] complex* input, [In,Out] complex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] complex* input, [In,Out] complex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
/****************************************************************** REAL-COMPLEX ***/
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_r2c_1d_(ref IntPtr plan, ref int n, [In,Out] double* input, [In,Out] complex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_r2c_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] double* input, [In,Out] complex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_r2c_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] double* input, [In,Out] complex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] double* input, [In,Out] complex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_c2r_1d_(ref IntPtr plan, ref int n, [In,Out] complex* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_c2r_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] complex* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_c2r_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] complex* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] complex* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_r2r_1d_(ref IntPtr plan, ref int n, [In,Out] double* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_r2r_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] double* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_r2r_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] double* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_r2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] double* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
/************************************ ADVANCED INTERFACE *************************************/
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_many_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, ref int howmany, [In,Out] complex* input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] complex* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_many_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int [] n, ref int howmany, [In,Out] double* input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] complex* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_many_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int [] n, ref int howmany, [In,Out] complex* input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] double* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_many_r2r_( ref IntPtr plan, ref int rank, [In,Out] int [] n, ref int howmany, [In,Out] double [] input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] double* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_KIND kind, ref FFTW_PLANCREATION flags);
/************************************ GURU INTERFACE *************************************/
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_guru_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] complex* input, [In,Out] complex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_guru_split_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] double* ri, [In,Out] double* ii, [In,Out] double* ro, [In,Out] double* io, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_guru_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] double* input, [In,Out] complex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_guru_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] complex* input, [In,Out] double* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_guru_split_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] double* ri, [In,Out] double* ro, [In,Out] double* io, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_guru_split_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] double* ri, [In,Out] double* ii, [In,Out] double* ro, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_plan_guru_r2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] double* input, [In,Out] double* output, ref FFTW_KIND kind, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_dft_(ref IntPtr plan, [In,Out] complex* input, [In,Out] complex* output);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_split_dft_(ref IntPtr plan, [In,Out] double* ri, [In,Out] double* ii, [In,Out] double* ro, [In,Out] double* io);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_dft_r2c_(ref IntPtr plan, [In,Out] double* ri, [In,Out] complex* ii);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_split_dft_r2c_(ref IntPtr plan, [In,Out] double* input, [In,Out] double* ro, [In,Out] double* ri);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_dft_c2r_(ref IntPtr plan, [In,Out] complex* input, [In,Out] double* output);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_split_dft_c2r_(ref IntPtr plan, [In,Out] double* ri, [In,Out] double* ii, [In,Out] double* output);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_r2r_(ref IntPtr plan, [In,Out] double* input, [In,Out] double* output);
/************************************ BASIC PLAN EXECUTION & MISC ******************************/
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_execute_(ref IntPtr plan);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_destroy_plan_(ref IntPtr plan);
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void dfftw_cleanup_();
[DllImport("libfftw3-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void fftw_set_timelimit(ref double seconds);
#endregion DOUBLE PRECISION INTERFACE
#region SINGLE PRECISION INTERFACE
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_1d_(ref IntPtr plan, ref int n, [In,Out] fcomplex* input, [In,Out] fcomplex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] fcomplex* input, [In,Out] fcomplex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] fcomplex* input, [In,Out] fcomplex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] fcomplex* input, [In,Out] fcomplex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
/****************************************************************** REAL-COMPLEX ***/
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_r2c_1d_(ref IntPtr plan, ref int n, [In,Out] float* input, [In,Out] fcomplex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_r2c_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] float* input, [In,Out] fcomplex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_r2c_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] float* input, [In,Out] fcomplex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] float* input, [In,Out] fcomplex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_c2r_1d_(ref IntPtr plan, ref int n, [In,Out] fcomplex* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_c2r_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] fcomplex* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_c2r_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] fcomplex* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] fcomplex* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_r2r_1d_(ref IntPtr plan, ref int n, [In,Out] float* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_r2r_2d_(ref IntPtr plan, ref int nx, ref int ny, [In,Out] float* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_r2r_3d_(ref IntPtr plan, ref int nx, ref int ny, ref int nz, [In,Out] float* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_r2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] float* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
/************************************ ADVANCED INTERFACE *************************************/
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_many_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, ref int howmany, [In,Out] fcomplex* input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] fcomplex* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_many_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int [] n, ref int howmany, [In,Out] float* input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] fcomplex* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_many_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int [] n, ref int howmany, [In,Out] fcomplex* input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] float* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_many_r2r_( ref IntPtr plan, ref int rank, [In,Out] int [] n, ref int howmany, [In,Out] float [] input, [In,Out] int[] inembed, ref int istride, ref int idist, [In,Out] float* output, [In,Out] int[] onembed, ref int ostride, ref int odist, ref FFTW_KIND kind, ref FFTW_PLANCREATION flags);
/************************************ GURU INTERFACE *************************************/
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_guru_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] fcomplex* input, [In,Out] fcomplex* output, ref FFTW_DIRECTION sign, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_guru_split_dft_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] float* ri, [In,Out] float* ii, [In,Out] float* ro, [In,Out] float* io, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_guru_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] float* input, [In,Out] fcomplex* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_guru_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] fcomplex* input, [In,Out] float* output, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_guru_split_dft_r2c_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] float* ri, [In,Out] float* ro, [In,Out] float* io, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_guru_split_dft_c2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] float* ri, [In,Out] float* ii, [In,Out] float* ro, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_plan_guru_r2r_(ref IntPtr plan, ref int rank, [In,Out] int[] n, [In,Out] int[] iS, [In,Out] int[] iO, ref int howmany_rank, [In,Out] int[] hn, [In,Out] int[] hiS, [In,Out] int[] hiO, [In,Out] float* input, [In,Out] float* output, ref FFTW_KIND kind, ref FFTW_PLANCREATION flags);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_dft_(ref IntPtr plan, [In,Out] fcomplex* input, [In,Out] fcomplex* output);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_split_dft_(ref IntPtr plan, [In,Out] float* ri, [In,Out] float* ii, [In,Out] float* ro, [In,Out] float* io);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_dft_r2c_(ref IntPtr plan, [In,Out] float* ri, [In,Out] fcomplex* ii);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_split_dft_r2c_(ref IntPtr plan, [In,Out] float* input, [In,Out] float* ro, [In,Out] float* ri);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_dft_c2r_(ref IntPtr plan, [In,Out] fcomplex* input, [In,Out] float* output);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_split_dft_c2r_(ref IntPtr plan, [In,Out] float* ri, [In,Out] float* ii, [In,Out] float* output);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_r2r_(ref IntPtr plan, [In,Out] float* input, [In,Out] float* output);
/************************************ BASIC PLAN EXECUTION & MISC ******************************/
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_execute_(ref IntPtr plan);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_destroy_plan_(ref IntPtr plan);
[DllImport("libfftw3f-3",CallingConvention =CallingConvention.Cdecl),SuppressUnmanagedCodeSecurity]
private static extern void sfftw_cleanup_();
#endregion SINGLE PRECISION INTERFACE
#endregion
#region FFTW CONSTANTS
[FlagsAttribute]
public enum FFTW_PLANCREATION : uint {
MEASURE = 0u,
DESTROY_INPUT = (1U << 0),
UNALIGNED = (1U << 1),
CONSERVE_MEMORY = (1U << 2),
EXHAUSTIVE = (1U << 3), /* NO_EXHAUSTIVE is default */
PRESERVE_INPUT = (1U << 4), /* cancels FFTW_DESTROY_INPUT */
PATIENT = (1U << 5), /* IMPATIENT is default */
ESTIMATE = (1U << 6)
}
public enum FFTW_DIRECTION {
FORWARD = -1,
BACKWARDS = 1
}
public enum FFTW_KIND {
R2HC=0,
HC2R=1,
DHT=2,
REDFT00=3,
REDFT01=4,
REDFT10=5,
REDFT11=6,
RODFT00=7,
RODFT01=8,
RODFT10=9,
RODFT11=10
}
#endregion
#region attributes
object _lockobject = new object();
int[] m_n,m_is,m_os, m_hn, m_his, m_hos;
//List m_tmpDims = new List(10);
#endregion
#region constructor
public ILFFTW3FFT () {
// fftw internally caches the plans, so ....
m_n = new int[10];
m_is = new int[10];
m_os = new int[10];
m_hn = new int[2];
m_his = new int[2];
m_hos = new int[2];
}
#endregion
#region IILFFT Member - 1-D
public ILRetArray< complex > FFTForward1D (ILInArray< double > A, int dim) {
return FFTForward (A,dim,1);
}
#region HYCALPER AUTO GENERATED CODE
public ILRetArray< fcomplex > FFTBackward1D (ILInArray< fcomplex > A, int dim) {
return FFTBackward (A,dim,1);
}
public ILRetArray< complex > FFTBackward1D (ILInArray< complex > A, int dim) {
return FFTBackward (A,dim,1);
}
public ILRetArray< fcomplex > FFTForward1D (ILInArray< fcomplex > A, int dim) {
return FFTForward (A,dim,1);
}
public ILRetArray< fcomplex > FFTForward1D (ILInArray< float > A, int dim) {
return FFTForward (A,dim,1);
}
public ILRetArray< complex > FFTForward1D (ILInArray< complex > A, int dim) {
return FFTForward (A,dim,1);
}
#endregion HYCALPER AUTO GENERATED CODE
public ILRetArray< double > FFTBackwSym1D(ILInArray< complex > A, int dim) {
return ILMath.real(FFTBackward1D(A,dim));
}
#region HYCALPER AUTO GENERATED CODE
public ILRetArray< float > FFTBackwSym1D(ILInArray< fcomplex > A, int dim) {
return ILMath.real(FFTBackward1D(A,dim));
}
#endregion HYCALPER AUTO GENERATED CODE
#endregion
#region IILFFT Member - n-D
public ILRetArray< complex > FFTForward (ILInArray< double > A, int nDims) {
return FFTForward (A,0,nDims);
}
public ILRetArray< complex> FFTForward(ILInArray< double> A, int firstDim, int nDims) {
using (ILScope.Enter(A)) {
if (object.Equals(A, null) || nDims < 0 || firstDim < 0)
throw new ILArgumentException("invalid parameter!");
if (A.IsEmpty) return ILArray< complex>.empty(A.Size);
if (A.IsScalar || (A.Size[firstDim] == 1 && nDims == 1))
return ILMath.tocomplex(A);
if (nDims > A.Size.NumberOfDimensions)
nDims = A.Size.NumberOfDimensions;
// prepare output array
ILArray< complex> ret = ILMath.tocomplex(A);
IntPtr plan = IntPtr.Zero;
int hrank = 2;
FFTW_DIRECTION dir = FFTW_DIRECTION.FORWARD;
lock (_lockobject) {
FFTW_PLANCREATION flags = FFTW_PLANCREATION.ESTIMATE;
if (nDims > m_n.Length) resizeCache(nDims);
for (int i = 0; i < nDims; i++) {
m_n[i] = A.Size[i + firstDim];
m_is[i] = A.Size.SequentialIndexDistance(i + firstDim);
m_os[i] = m_is[i];
}
m_hn[0] = A.Size.SequentialIndexDistance(firstDim);
m_his[0] = 1;
m_hos[0] = 1;
m_his[1] = A.Size.SequentialIndexDistance(nDims + firstDim);
m_hn[1] = A.Size.NumberOfElements / m_his[1];
m_hos[1] = m_his[1];
fixed ( complex* retArr = ret.GetArrayForWrite()) {
dfftw_plan_guru_dft_(ref plan, ref nDims, m_n, m_is, m_os,
ref hrank, m_hn, m_his, m_hos,
retArr, retArr,
ref dir, ref flags);
}
}
if (plan == IntPtr.Zero)
throw new ILInvalidOperationException("error creating plan for fftw3 (guru interface)");
dfftw_execute_(ref plan);
dfftw_destroy_plan_(ref plan);
return ret;
}
}
#region HYCALPER AUTO GENERATED CODE
public ILRetArray< fcomplex > FFTBackward (ILInArray< fcomplex > A, int nDims) {
return FFTBackward (A,0,nDims);
}
public ILRetArray< fcomplex> FFTBackward(ILInArray< fcomplex> A, int firstDim, int nDims) {
using (ILScope.Enter(A)) {
if (object.Equals(A, null) || nDims < 0 || firstDim < 0)
throw new ILArgumentException("invalid parameter!");
if (A.IsEmpty) return ILArray< fcomplex>.empty(A.Size);
if (A.IsScalar || (A.Size[firstDim] == 1 && nDims == 1))
return A.C;
if (nDims > A.Size.NumberOfDimensions)
nDims = A.Size.NumberOfDimensions;
// prepare output array
ILArray< fcomplex> ret = A.C;
IntPtr plan = IntPtr.Zero;
int hrank = 2;
FFTW_DIRECTION dir = FFTW_DIRECTION.BACKWARDS;
lock (_lockobject) {
FFTW_PLANCREATION flags = FFTW_PLANCREATION.ESTIMATE;
if (nDims > m_n.Length) resizeCache(nDims);
for (int i = 0; i < nDims; i++) {
m_n[i] = A.Size[i + firstDim];
m_is[i] = A.Size.SequentialIndexDistance(i + firstDim);
m_os[i] = m_is[i];
}
m_hn[0] = A.Size.SequentialIndexDistance(firstDim);
m_his[0] = 1;
m_hos[0] = 1;
m_his[1] = A.Size.SequentialIndexDistance(nDims + firstDim);
m_hn[1] = A.Size.NumberOfElements / m_his[1];
m_hos[1] = m_his[1];
fixed ( fcomplex* retArr = ret.GetArrayForWrite()) {
sfftw_plan_guru_dft_(ref plan, ref nDims, m_n, m_is, m_os,
ref hrank, m_hn, m_his, m_hos,
retArr, retArr,
ref dir, ref flags);
}
}
if (plan == IntPtr.Zero)
throw new ILInvalidOperationException("error creating plan for fftw3 (guru interface)");
dfftw_execute_(ref plan);
dfftw_destroy_plan_(ref plan);
ret /= new fcomplex(m_his[1]/m_hn[0],0.0f);
return ret;
}
}
public ILRetArray< complex > FFTBackward (ILInArray< complex > A, int nDims) {
return FFTBackward (A,0,nDims);
}
public ILRetArray< complex> FFTBackward(ILInArray< complex> A, int firstDim, int nDims) {
using (ILScope.Enter(A)) {
if (object.Equals(A, null) || nDims < 0 || firstDim < 0)
throw new ILArgumentException("invalid parameter!");
if (A.IsEmpty) return ILArray< complex>.empty(A.Size);
if (A.IsScalar || (A.Size[firstDim] == 1 && nDims == 1))
return A.C;
if (nDims > A.Size.NumberOfDimensions)
nDims = A.Size.NumberOfDimensions;
// prepare output array
ILArray< complex> ret = A.C;
IntPtr plan = IntPtr.Zero;
int hrank = 2;
FFTW_DIRECTION dir = FFTW_DIRECTION.BACKWARDS;
lock (_lockobject) {
FFTW_PLANCREATION flags = FFTW_PLANCREATION.ESTIMATE;
if (nDims > m_n.Length) resizeCache(nDims);
for (int i = 0; i < nDims; i++) {
m_n[i] = A.Size[i + firstDim];
m_is[i] = A.Size.SequentialIndexDistance(i + firstDim);
m_os[i] = m_is[i];
}
m_hn[0] = A.Size.SequentialIndexDistance(firstDim);
m_his[0] = 1;
m_hos[0] = 1;
m_his[1] = A.Size.SequentialIndexDistance(nDims + firstDim);
m_hn[1] = A.Size.NumberOfElements / m_his[1];
m_hos[1] = m_his[1];
fixed ( complex* retArr = ret.GetArrayForWrite()) {
dfftw_plan_guru_dft_(ref plan, ref nDims, m_n, m_is, m_os,
ref hrank, m_hn, m_his, m_hos,
retArr, retArr,
ref dir, ref flags);
}
}
if (plan == IntPtr.Zero)
throw new ILInvalidOperationException("error creating plan for fftw3 (guru interface)");
dfftw_execute_(ref plan);
dfftw_destroy_plan_(ref plan);
ret /= new complex(m_his[1]/m_hn[0],0.0f);
return ret;
}
}
public ILRetArray< fcomplex > FFTForward (ILInArray< fcomplex > A, int nDims) {
return FFTForward (A,0,nDims);
}
public ILRetArray< fcomplex> FFTForward(ILInArray< fcomplex> A, int firstDim, int nDims) {
using (ILScope.Enter(A)) {
if (object.Equals(A, null) || nDims < 0 || firstDim < 0)
throw new ILArgumentException("invalid parameter!");
if (A.IsEmpty) return ILArray< fcomplex>.empty(A.Size);
if (A.IsScalar || (A.Size[firstDim] == 1 && nDims == 1))
return A.C;
if (nDims > A.Size.NumberOfDimensions)
nDims = A.Size.NumberOfDimensions;
// prepare output array
ILArray< fcomplex> ret = A.C;
IntPtr plan = IntPtr.Zero;
int hrank = 2;
FFTW_DIRECTION dir = FFTW_DIRECTION.FORWARD;
lock (_lockobject) {
FFTW_PLANCREATION flags = FFTW_PLANCREATION.ESTIMATE;
if (nDims > m_n.Length) resizeCache(nDims);
for (int i = 0; i < nDims; i++) {
m_n[i] = A.Size[i + firstDim];
m_is[i] = A.Size.SequentialIndexDistance(i + firstDim);
m_os[i] = m_is[i];
}
m_hn[0] = A.Size.SequentialIndexDistance(firstDim);
m_his[0] = 1;
m_hos[0] = 1;
m_his[1] = A.Size.SequentialIndexDistance(nDims + firstDim);
m_hn[1] = A.Size.NumberOfElements / m_his[1];
m_hos[1] = m_his[1];
fixed ( fcomplex* retArr = ret.GetArrayForWrite()) {
sfftw_plan_guru_dft_(ref plan, ref nDims, m_n, m_is, m_os,
ref hrank, m_hn, m_his, m_hos,
retArr, retArr,
ref dir, ref flags);
}
}
if (plan == IntPtr.Zero)
throw new ILInvalidOperationException("error creating plan for fftw3 (guru interface)");
dfftw_execute_(ref plan);
dfftw_destroy_plan_(ref plan);
return ret;
}
}
public ILRetArray< fcomplex > FFTForward (ILInArray< float > A, int nDims) {
return FFTForward (A,0,nDims);
}
public ILRetArray< fcomplex> FFTForward(ILInArray< float> A, int firstDim, int nDims) {
using (ILScope.Enter(A)) {
if (object.Equals(A, null) || nDims < 0 || firstDim < 0)
throw new ILArgumentException("invalid parameter!");
if (A.IsEmpty) return ILArray< fcomplex>.empty(A.Size);
if (A.IsScalar || (A.Size[firstDim] == 1 && nDims == 1))
return ILMath.tofcomplex(A);
if (nDims > A.Size.NumberOfDimensions)
nDims = A.Size.NumberOfDimensions;
// prepare output array
ILArray< fcomplex> ret = ILMath.tofcomplex(A);
IntPtr plan = IntPtr.Zero;
int hrank = 2;
FFTW_DIRECTION dir = FFTW_DIRECTION.FORWARD;
lock (_lockobject) {
FFTW_PLANCREATION flags = FFTW_PLANCREATION.ESTIMATE;
if (nDims > m_n.Length) resizeCache(nDims);
for (int i = 0; i < nDims; i++) {
m_n[i] = A.Size[i + firstDim];
m_is[i] = A.Size.SequentialIndexDistance(i + firstDim);
m_os[i] = m_is[i];
}
m_hn[0] = A.Size.SequentialIndexDistance(firstDim);
m_his[0] = 1;
m_hos[0] = 1;
m_his[1] = A.Size.SequentialIndexDistance(nDims + firstDim);
m_hn[1] = A.Size.NumberOfElements / m_his[1];
m_hos[1] = m_his[1];
fixed ( fcomplex* retArr = ret.GetArrayForWrite()) {
sfftw_plan_guru_dft_(ref plan, ref nDims, m_n, m_is, m_os,
ref hrank, m_hn, m_his, m_hos,
retArr, retArr,
ref dir, ref flags);
}
}
if (plan == IntPtr.Zero)
throw new ILInvalidOperationException("error creating plan for fftw3 (guru interface)");
dfftw_execute_(ref plan);
dfftw_destroy_plan_(ref plan);
return ret;
}
}
public ILRetArray< complex > FFTForward (ILInArray< complex > A, int nDims) {
return FFTForward (A,0,nDims);
}
public ILRetArray< complex> FFTForward(ILInArray< complex> A, int firstDim, int nDims) {
using (ILScope.Enter(A)) {
if (object.Equals(A, null) || nDims < 0 || firstDim < 0)
throw new ILArgumentException("invalid parameter!");
if (A.IsEmpty) return ILArray< complex>.empty(A.Size);
if (A.IsScalar || (A.Size[firstDim] == 1 && nDims == 1))
return A.C;
if (nDims > A.Size.NumberOfDimensions)
nDims = A.Size.NumberOfDimensions;
// prepare output array
ILArray< complex> ret = A.C;
IntPtr plan = IntPtr.Zero;
int hrank = 2;
FFTW_DIRECTION dir = FFTW_DIRECTION.FORWARD;
lock (_lockobject) {
FFTW_PLANCREATION flags = FFTW_PLANCREATION.ESTIMATE;
if (nDims > m_n.Length) resizeCache(nDims);
for (int i = 0; i < nDims; i++) {
m_n[i] = A.Size[i + firstDim];
m_is[i] = A.Size.SequentialIndexDistance(i + firstDim);
m_os[i] = m_is[i];
}
m_hn[0] = A.Size.SequentialIndexDistance(firstDim);
m_his[0] = 1;
m_hos[0] = 1;
m_his[1] = A.Size.SequentialIndexDistance(nDims + firstDim);
m_hn[1] = A.Size.NumberOfElements / m_his[1];
m_hos[1] = m_his[1];
fixed ( complex* retArr = ret.GetArrayForWrite()) {
dfftw_plan_guru_dft_(ref plan, ref nDims, m_n, m_is, m_os,
ref hrank, m_hn, m_his, m_hos,
retArr, retArr,
ref dir, ref flags);
}
}
if (plan == IntPtr.Zero)
throw new ILInvalidOperationException("error creating plan for fftw3 (guru interface)");
dfftw_execute_(ref plan);
dfftw_destroy_plan_(ref plan);
return ret;
}
}
#endregion HYCALPER AUTO GENERATED CODE
public ILRetArray< double > FFTBackwSym(ILInArray< complex > A, int nDims) {
return ILMath.real(FFTBackward(A,nDims));
}
#region HYCALPER AUTO GENERATED CODE
public ILRetArray< float > FFTBackwSym(ILInArray< fcomplex > A, int nDims) {
return ILMath.real(FFTBackward(A,nDims));
}
#endregion HYCALPER AUTO GENERATED CODE
#endregion
#region IILFFT Member - Misc
public bool CachePlans {
get {
return true;
}
}
public void FreePlans() {
FreeAllDescriptors();
}
public bool SpeedyHermitian {
get { return false; }
}
#endregion
#region private helper
private void FreeAllDescriptors() {
try {
dfftw_cleanup_();
sfftw_cleanup_();
} catch (Exception) { }
}
private void resizeCache(int size) {
if (m_n.Length >= size) return;
m_n = new int[size];
m_is = new int[size];
m_os = new int[size];
}
#endregion
#region IDisposable Member
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose (bool manual) {
if (manual) {
FreeAllDescriptors();
}
}
~ILFFTW3FFT () {
Dispose(true);
}
#endregion
}
}