Kars
Kars

Reputation: 39

Why does my ifft result in the real part of the complex number being infinite?

I am writing a script that simulates random white noise to study its behavior when shifted into its signal form.

Below is the function that I am having a problem with:

def white_noise(n: int, N: int, slope: int = grad):
    """
    - Creates a data set of white noise with size n, N;
    - Filters this dataset with the corresponding slope;
        This slope is usually equal to -5/3 or -2/3
    - Makes sure the slope is equal to the requested slope in the double log scale.

    @param n: size of random array
    @param N: number of random arrays
    @param slope: slope of the gradient
    @return: white_noise, filtered white_noise and the original signal
    """
    x = np.linspace(0, 1, n)
    slope_loglog = (10 ** (slope * np.log10(x) + 1))

    white_noise = rnd.rand(n, N) ** 2 # squaring the white noise to retrieve the power spectrum
    white_noise_filtered = []
    white_noise_signal = []
    white_noise_retransformed = []

    for k in range(N):
        white_noise_filtered.append(white_noise[:,k] * slope_loglog)
        white_noise_signal.append(fft.ifft(white_noise[:,k] * slope_loglog))

    white_noise_filtered, white_noise_signal, white_noise_retransformed = \
        np.asarray((white_noise_filtered, white_noise_signal, white_noise_retransformed))

    white_noise_filtered = white_noise_filtered.transpose()
    white_noise_signal = white_noise_signal.transpose().imag


    return white_noise, white_noise_filtered, white_noise_signal, white_noise_retransformed, slope_loglog

During the step where I apply the inverse fast Fourier transform (1D), my simulated noise generates a complex array (which is to be expected when dealing with Fourier transformations). What I do not understand is why the real part from all of the complex values equals 'Inf'. These should have a finite value, so what am I doing wrong?

(Note: the slope_loglog has to do with log-log transformed data having a gradient of -5/3.)

Since I need the ifft and thereafter the fft to achieve the original noise again (or shifted), I need to understand why my script does this. Taking only the imaginary part of the array 'white_noise_signal' does not result in the original noise.

Upvotes: 0

Views: 789

Answers (1)

Nils Werner
Nils Werner

Reputation: 36835

This has nothing to do with FFT/IFFT

np.log10(0) = -np.inf

and

10 ** np.inf = np.inf

So if you use a negative slope, i.e. slope = -1

10 ** (slope * np.log10(0)) = np.inf

Multiply that with any signal and you will get inf.

Also, you can simplify your code significantly if you skip using lists inbetween:

def white_noise(n: int, N: int, slope: int = -5/3):
    """
    - Creates a data set of white noise with size n, N;
    - Filters this dataset with the corresponding slope;
        This slope is usually equal to -5/3 or -2/3
    - Makes sure the slope is equal to the requested slope in the double log scale.

    @param n: size of random array
    @param N: number of random arrays
    @param slope: slope of the gradient
    @return: white_noise, filtered white_noise and the original signal
    """

    x = np.linspace(0, 1, n)
    slope_loglog = (10 ** (slope * np.log10(x) + 1))

    white_noise = np.random.rand(n, N) ** 2 # cubing the white noise to retrieve the power spectrum

    white_noise_filtered = (white_noise * slope_loglog).T
    white_noise_signal = (np.fft.ifft(white_noise, axis=-1) * slope_loglog).T.imag

    return white_noise, white_noise_filtered, white_noise_signal, slope_loglog

Upvotes: 1

Related Questions