2

If the trailing dimension of an array x is odd, the transform y = irfftn(rfftn(x)) does not have the same shape as the input array. Is this by design? And if so, what is the motivation? Example code is below.

import numpy as np

shapes = [(10, 10), (11, 11), (10, 11), (11, 10)]

for shape in shapes:
    x = np.random.uniform(0, 1, shape)
    y = np.fft.irfftn(np.fft.rfftn(x))
    if x.shape != y.shape:
        print("expected shape %s but got %s" % (shape, y.shape))

# Output
# expected shape (11, 11) but got (11, 10)
# expected shape (10, 11) but got (10, 10)
Till Hoffmann
  • 9,479
  • 6
  • 46
  • 64

1 Answers1

4

You need to pass second parameter x.shape in your case the code will looks like:

import numpy as np

shapes = [(10, 10), (11, 11), (10, 11), (11, 10)]

for shape in shapes:
    x = np.random.uniform(0, 1, shape)
    y = np.fft.irfftn(np.fft.rfftn(x),x.shape)
    if x.shape != y.shape:
        print("expected shape %s but got %s" % (shape, y.shape))

from the docs

This function computes the inverse of the N-dimensional discrete Fourier Transform for real input over any number of axes in an M-dimensional array by means of the Fast Fourier Transform (FFT). In other words, irfftn(rfftn(a), a.shape) == a to within numerical accuracy. (The a.shape is necessary like len(a) is for irfft, and for the same reason.)

x.shape descriptions from the same docs:

s : sequence of ints, optional Shape (length of each transformed axis) of the output (s[0] refers to axis 0, s[1] to axis 1, etc.). s is also the number of input points used along this axis, except for the last axis, where s[-1]//2+1 points of the input are used. Along any axis, if the shape indicated by s is smaller than that of the input, the input is cropped. If it is larger, the input is padded with zeros. If s is not given, the shape of the input along the axes specified by axes is used.

https://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.irfftn.html

Laser
  • 6,652
  • 8
  • 54
  • 85