-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
rfft and irfft ignore float32 and complex64 dtypes, and always return float64 or complex128 arrays #6012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I forgot something important : I'm using numpy 1.8.2 and python 3.4.1 on linux (fedora 21) |
I beleive numpy doesn't support float32 for fft. If you want that, you will need to use Scipy, although, IIRC, there may be some problems there also due to inaccuracy in the transform of data whose length has large prime factors. Probably fixable, but I don't think it is fixed yet. |
It's okay with scipy.fftpack rfft, but... while digging the problem, I've also found some similar behaviors in scipy.interpolate, for instance. |
Numpy is more basic than Scipy. The ufuncs suppport all the relevant types, as do most of the linalg routines these days, but in general Scipy is more complete. Numpy support for all the types does evolve but it isn't a high priority. |
And |
For anyone coming from Google, here's how to replace numpy's import numpy.fft as fft
import scipy.fftpack as scifft
import numpy as np
x = np.random.randn(10, 10).astype(np.float32)
# Using two invocations of scipy.fftpack.rfft & irfft. Adjust your call to these
# functions with extra arguments (n, overwrite_x, etc.) as needed.
rfft2 = lambda x: scifft.rfft(scifft.rfft(x, axis=1), axis=0)
irfft2 = lambda X: scifft.irfft(scifft.irfft(X, axis=0))
xScipy = irfft2(rfft2(x))
# Using numpy.fft.rfft2 & irfft2
xNumpy = fft.irfft2(fft.rfft2(x))
# Verify all equal. Note that the scipy version is float32, while the numpy
# version was implictly upcast to float64. For this reason, `allclose` needs a
# looser absolute tolerance, more in line with single-precision.
assert (np.allclose(x, xScipy, atol=2e-7))
assert (np.allclose(x, xNumpy))
print 'Tests pass. Scipy type: %s, Numpy type: %s' % (xScipy.dtype,
xNumpy.dtype) (I realize this test just shows that the forward- and backwards-transforms are inverses of each other, and not that the correct frequency domain content is generated—but I've verified that frequency-domain filtering works using both versions here.) |
When i use a float32 dtype array as the argument to numpy.fft.rfft, I get a complex128 dtype array as the output instead of a complex64 dtype array.
Similarly, when I use a complex64 dtype array as the argument to numpy.fft.irfft, I get a float64 dtype array instead of a float32 dtype array.
Here is a code snippet :
In [4]: a = np.array([1., 2., 3.], dtype=np.float32)
In [5]: a
Out[5]: array([ 1., 2., 3.], dtype=float32)
In [6]: b = np.fft.rfft(a)
In [7]: b
Out[7]: array([ 6.0+0.j , -1.5+0.8660254j])
In [8]: b.dtype
Out[8]: dtype('complex128')
In [9]: b.astype(np.complex64)
Out[9]: array([ 6.0+0.j , -1.5+0.86602539j], dtype=complex64)
In [10]: c = np.fft.irfft(b)
In [11]: c
Out[11]: array([ 2.25, 3.75])
In [12]: c.dtype
Out[12]: dtype('float64')
The text was updated successfully, but these errors were encountered: