The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
zufft computes the same transforms as fftwtools without the FFTW system library, and under a permissive licence. This vignette maps every fftwtools call to its zufft equivalent. Where fftwtools is installed, each example also checks that both give the same values.
Scaling. fftwtools, like stats::fft(),
never scales: an inverse after a forward transform multiplies by the
length. zufft follows scipy.fft and divides the inverse by
the length by default (norm = "backward"). Use
norm = "none" to get fftwtools’ numbers exactly.
x <- c(1, 4, 2, 8, 5, 7)
fft_c2c(fft_c2c(x), inverse = TRUE) # x again
#> [1] 1+0i 4+0i 2+0i 8+0i 5+0i 7+0i
fft_c2c(fft_c2c(x), inverse = TRUE, norm = "none") # 6 * x, as fftwtools
#> [1] 6+0i 24+0i 12+0i 48+0i 30+0i 42+0iHalf spectra. fftwtools’ HermConj = 1
(its default) returns the full spectrum of real input, and
HermConj = 0 the non-redundant half. In zufft that is the
choice between fft_c2c() and fft_r2c().
fft_c2c(x) # full spectrum, as fftw(x) and fftw_r2c(x)
#> [1] 27+0.000000e+00i -5+5.196152e+00i 0+4.440892e-16i -11+0.000000e+00i
#> [5] 0-4.440892e-16i -5-5.196152e+00i
fft_r2c(x) # first n %/% 2 + 1 values, as fftw_r2c(x, HermConj = 0)
#> [1] 27+0.000000e+00i -5+5.196152e+00i 0+4.440892e-16i -11+0.000000e+00iTo go back from a half spectrum you need the original length, because
an even and an odd length give the same half size. Both packages take it
as n:
| fftwtools | zufft |
|---|---|
fftw(x) |
fft_c2c(x) |
fftw(x, inverse = 1) |
fft_c2c(x, inverse = TRUE, norm = "none") |
fftw(x, HermConj = 0) (real x) |
fft_r2c(x) |
fftw(X, inverse = 1, HermConj = 0, n = n) |
fft_c2r(X, n = n, norm = "none") |
fftw_r2c(x) |
fft_c2c(x) |
fftw_r2c(x, HermConj = 0) |
fft_r2c(x) |
fftw_c2r(X, HermConj = 0, n = n) |
fft_c2r(X, n = n, norm = "none") |
fftw_c2r(X) (full spectrum) |
Re(fft_c2c(X, inverse = TRUE, norm = "none")) |
fftw_c2c(x, inverse = i) |
fft_c2c(x, inverse = i, norm = "none") |
inverse = 0 and inverse = 1 work in zufft
too.
z <- complex(real = rnorm(8), imaginary = rnorm(8))
all.equal(fft_c2c(z, inverse = 1, norm = "none"), fftwtools::fftw_c2c(z, inverse = 1))
#> [1] TRUE
all.equal(fft_r2c(x), fftwtools::fftw_r2c(x, HermConj = 0))
#> [1] TRUE
all.equal(fft_c2r(X, n = 7, norm = "none"), fftwtools::fftw_c2r(X, HermConj = 0, n = 7))
#> [1] TRUEfftwtools’ mvfftw* functions transform each column. In
zufft that is axes = 1.
| fftwtools | zufft |
|---|---|
mvfftw(m), mvfftw_c2c(m) |
fft_c2c(m, axes = 1) |
mvfftw_r2c(m, HermConj = 0) |
fft_r2c(m, axes = 1) |
mvfftw_c2r(M, HermConj = 0, n = n) |
fft_c2r(M, n = n, axes = 1, norm = "none") |
mvfftw(..., fftplanopt = 1) |
nothing to do: zufft caches its plans |
| fftwtools | zufft |
|---|---|
fftw2d(x), fftw_c2c_2d(x),
fftw3d(x), fftw_c2c_3d(x),
fftw_c2c_xd(x) |
fft_c2c(x) |
fftw_r2c_2d(x, HermConj = 0) |
fft_r2c(x) |
fftw_r2c_3d(x, HermConj = 0) |
fft_r2c(x) |
FFTW stores arrays row by row, so fftwtools’ real 2-D and 3-D transforms halve R’s first dimension. zufft’s real transforms do the same by default: in R the first dimension is the contiguous one, and halving it is the fast choice.
install.packages("zufft") is enough,
everywhere.bench/RESULTS.md, zufft is faster than fftwtools on most
cases and within 1.5 times everywhere, because it caches its plans while
fftwtools plans on every call. Multi-dimensional complex transforms gain
the most.workers = 2 (or
fft_workers(2)) splits a transform over threads; fftwtools
has none.fft_dct() and
fft_dst() (types 1 to 4), any subset of axes, cropping and
zero-padding with n, and fft_next_len() for
fast lengths.fft_c2r() never
modifies its input, while FFTW’s complex-to-real transform destroys
it.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.