question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug with spectra when using real fft

See original GitHub issue

I think there is a bug with the power spectrum estimates when a real dimension is provided.

For real fft, Hermitian symmetry is exploited to compute only the non-negative frequency terms. But we can’t ignore the energy in the negative frequency terms when computing spectra. To account for this, we need to multiply by 2 the energy of all but the first (DC) mode (and last mode if the signal length even - see https://numpy.org/doc/stable/reference/generated/numpy.fft.rfft.html).

I can demonstrate the issue and the fix through comparison to scipy.signal.periodogram:

import xrft
import numpy as np
import scipy.signal
import xarray as xr
import matplotlib.pyplot as plt 

x = xr.DataArray(np.random.normal(0, 1, size=100), 
                 dims=['t'], 
                 coords=[range(0,100)])


f_scipy, p_scipy = scipy.signal.periodogram(x.values,
                                            window='rectangular')
p_xrft = xrft.xrft.power_spectrum(x, 
                                  dim=['t'], 
                                  real='t',
                                  detrend='constant')

# For even length signals the last mode includes both the +ve and -ve contributions
correction = np.ones_like(f_scipy)
correction[1:-1] = 2

plt.plot(f_scipy, p_scipy,
         label='scipy psd')
plt.plot(p_xrft.freq_t, p_xrft, 
         color='C2', label='xrft psd')
plt.plot(p_xrft.freq_t, correction*p_xrft, 
         linestyle='--', color='C1', label='corrected xrft psd')
plt.xlabel('freq')
plt.ylabel('psd')
plt.legend()

delete-3

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
lanouguecommented, Jan 29, 2021

Hi @dougiesquire, I fully agree with you. We have to decide if we want to be compliant with scipy.signal.periodogram(). And populate the documentation for sure.

1reaction
rabernatcommented, Jan 28, 2021

Thanks for the explanations @lanougue! I think it’s super important we get all of this documented in the documentation.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Two dimensional FFT showing unexpected frequencies above ...
I want to analyze the frequency spectrum of my E(x,y) signal using a two dimensional fast fourier transform (FFT) using python.
Read more >
Why is it a bad idea to filter by zeroing out FFT bins?
"FFT gives poor time resolution" FFT gives no time resolution, it's a spectral domain transform and so, like said afterwards, gives only ...
Read more >
Why are the return-values of fft and fftfreq so terrible?
First of all, the amplitude needs to be corrected for the length of the signal. Secondly, there is no kwarg to get a...
Read more >
ifft returns a complex signal from a real fft spectrum - MathWorks
Hi all,. I've been trying to synthesize a 1 second long complex tone with 10 harmonics (at 200Hz, 400Hz, ... 2000Hz) of equal...
Read more >
FFT(1) - PhysioNet
Using appropriate options, fft can produce polar or rectangular format amplitude spectra, or power spectra, or it can perform an inverse FFT to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found