diff --git a/README.md b/README.md index f30561f..001b720 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,19 @@ -Nim bindings to the FFTW3 library. +Nim bindings to the FFTW3 library, to compute Fourier transforms of various kinds with high performance. -Read the doc : https://clonkk.github.io/nimfftw3/doc/fftw3.html +# Installation -Set of Nim bindings to the excellent FFTW library, to compute Fourier transforms of various kinds with high performance. +Use nimble `nimble install fftw3` to install the latest released version + +# Usage + +I advise to read the fftw documentation : + +You can find the generated documentation here with the complete API and examples : https://clonkk.github.io/nimfftw3/doc/fftw3.html + +# History These bindings were originally generated here : https://github.com/ziotom78/nimfftw3/blob/master/fftw3.nim +# License + These bindings are released under a LGPL license. FFTW3 is released under a GPLv2 or above license. diff --git a/doc/fftw3.html b/doc/fftw3.html index 9f53edf..a1fab10 100644 --- a/doc/fftw3.html +++ b/doc/fftw3.html @@ -466,7 +466,7 @@

Examples

C-Bin # Create a plan var plan : fftw_plan = fftw_plan_dft(input, output, FFTW_FORWARD, FFTW_ESTIMATE) # Execute plan in-place -fftw_execute(plan)

+fftw_execute(plan)Arraymancer non-official API for ease of useFFT Shift Because FFT-Shift is used in many FFT based AlgorithmFFTW Execute APIFFTW Plan APIFFTW Plan Many APIFFTW "Guru" API This is the "I know what I'm doing and want to optimize every last bits of performance" API of FFTWFFTW Utility & Cleanup API

Types

@@ -1440,7 +1440,7 @@

Procs

diff --git a/src/fftw3.nim b/src/fftw3.nim index e712367..8ac655c 100644 --- a/src/fftw3.nim +++ b/src/fftw3.nim @@ -42,7 +42,7 @@ ## # Execute plan in-place ## fftw_execute(plan) -# Arraymancer non-official API for ease of use +## Arraymancer non-official API for ease of use import arraymancer import sequtils @@ -97,7 +97,8 @@ type fftw_complex* = Complex64 fftw_plan* = pointer -# Utility procedures +## FFT Shift +## Because FFT-Shift is used in many FFT based Algorithm proc circshift_impl[T](t: Tensor[T], xshift: int, yshift: int, zshift: int): Tensor[T]= assert(t.rank == 3) var X = t.shape[0] @@ -171,6 +172,7 @@ proc ifftshift*[T](t: Tensor[T]): Tensor[T]= let zshift = (t.shape[2]+1) div 2 result = circshift(t, @[xshift.int, yshift.int, zshift.int]) +## FFTW Execute API proc fftw_execute*(p: fftw_plan) {.cdecl, importc: "fftw_execute", dynlib: LibraryName.} @@ -205,7 +207,6 @@ proc fftw_execute_dft_c2r*(p: fftw_plan, input: Tensor[fftw_complex], output: fftw_execute_dft_c2r(p, input.get_data_ptr, cast[ptr cdouble](output.get_data_ptr)) - proc fftw_execute_split_dft*(p: fftw_plan; ri: ptr cdouble; ii: ptr cdouble; ro: ptr cdouble; io: ptr cdouble) {.cdecl, importc: "fftw_execute_split_dft", dynlib: LibraryName.} @@ -219,7 +220,7 @@ proc fftw_execute_split_dft_c2r*(p: fftw_plan; ri: ptr cdouble; ii: ptr cdouble; importc: "fftw_execute_split_dft_c2r", dynlib: LibraryName.} - +## FFTW Plan API proc fftw_plan_dft*(rank: cint; n: ptr cint; `in`: ptr fftw_complex; `out`: ptr fftw_complex; sign: cint; flags: cuint): fftw_plan {. @@ -264,7 +265,6 @@ proc fftw_plan_dft_3d*(input: Tensor[fftw_complex], output: Tensor[fftw_complex] result = fftw_plan_dft_3d(shape[0], shape[1], shape[2], input.get_data_ptr, output.get_data_ptr,sign, flags) - proc fftw_plan_dft_r2c*(rank: cint; n: ptr cint; `in`: ptr cdouble; `out`: ptr fftw_complex; flags: cuint): fftw_plan {. cdecl, importc: "fftw_plan_dft_r2c", dynlib: LibraryName.} @@ -395,6 +395,7 @@ proc fftw_plan_r2r_3d*(input: Tensor[float64], output: Tensor[float64], kinds: s let shape : seq[cint] = map(input.shape.toSeq, proc(x: int): cint= x.cint) result = fftw_plan_r2r_3d(shape[0], shape[1], shape[2], cast[ptr cdouble](input.get_data_ptr), cast[ptr cdouble](output.get_data_ptr), kinds[0], kinds[1], kinds[2], flags) +## FFTW Plan Many API proc fftw_plan_many_dft*(rank: cint; n: ptr cint; howmany: cint; `in`: ptr fftw_complex; inembed: ptr cint; @@ -428,6 +429,8 @@ proc fftw_plan_many_r2r*(rank: cint; n: ptr cint; howmany: cint; +## FFTW "Guru" API +## This is the "I know what I'm doing and want to optimize every last bits of performance" API of FFTW proc fftw_plan_guru_dft*(rank: cint; dims: ptr fftw_iodim; howmany_rank: cint; howmany_dims: ptr fftw_iodim; `in`: ptr fftw_complex; @@ -508,6 +511,8 @@ proc fftw_plan_guru64_r2r*(rank: cint; dims: ptr fftw_iodim64; kind: ptr fftw_r2r_kind; flags: cuint): fftw_plan {. cdecl, importc: "fftw_plan_guru64_r2r", dynlib: LibraryName.} +## FFTW Utility & Cleanup API + proc fftw_destroy_plan*(p: fftw_plan) {.cdecl, importc: "fftw_destroy_plan", dynlib: LibraryName.} proc fftw_forget_wisdom*() {.cdecl, importc: "fftw_forget_wisdom", diff --git a/tests/test1.nim b/tests/test1.nim index 40ccdc5..432f7d8 100644 --- a/tests/test1.nim +++ b/tests/test1.nim @@ -30,6 +30,8 @@ proc main()= var orig = newTensor[Complex64](dims) let ifft = fftw_plan_dft(output, orig, FFTW_BACKWARD, FFTW_ESTIMATE) fftw_execute_dft(ifft, output, orig) + + # FFTW does not normalize inverse fft let size = complex(orig.size.float64) orig = orig /. size @@ -37,5 +39,6 @@ proc main()= check compare(randData, orig.map(x => x.re)) fftw_destroy_plan(fft) + fftw_destroy_plan(ifft) main()