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 @@
C-Bin
var plan : fftw_plan = fftw_plan_dft(input, output, FFTW_FORWARD, FFTW_ESTIMATE)
-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
@@ -1440,7 +1440,7 @@
- Made with Nim. Generated: 2020-06-10 12:19:53 UTC
+ Made with Nim. Generated: 2020-09-15 09:29:24 UTC
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()