Skip to content

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

Closed
Bernard-Couderc opened this issue Jun 24, 2015 · 7 comments

Comments

@Bernard-Couderc
Copy link

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')

@Bernard-Couderc
Copy link
Author

I forgot something important : I'm using numpy 1.8.2 and python 3.4.1 on linux (fedora 21)

@charris
Copy link
Member

charris commented Jun 24, 2015

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.

@Bernard-Couderc
Copy link
Author

It's okay with scipy.fftpack rfft, but... while digging the problem, I've also found some similar behaviors in scipy.interpolate, for instance.
I thought that numpy and scipy both transparently supported float32 and complex64. Am I wrong?

@charris
Copy link
Member

charris commented Jun 28, 2015

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.

@fasiha
Copy link

fasiha commented Aug 20, 2015

And scipy.fftpack lacks rfft2, whose convenience I was enjoying in numpy. :(

@fasiha
Copy link

fasiha commented Aug 26, 2015

For anyone coming from Google, here's how to replace numpy's rfft2 with scipy's 1D functions that works for me, specifically the rfft2 and irfft2 lambdas.

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.)

@WarrenWeckesser
Copy link
Member

This is also discussed in gh-17801.

Even though this issue is the older one, I'm closing it as the duplicate, because the discussion in gh-17801 is probably more up-to-date.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants