Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to use scipy.signal.spectral.lombscargle

I'm refering to the following post : Using scipy.signal.spectral.lombscargle for period discovery

I realize the answer given correct for certain case.

Frequency for sin(x), which is 1/(2* pi)

# imports the numerical array and scientific computing packages
import numpy as np
import scipy as sp
from scipy.signal import spectral

# generates 100 evenly spaced points between 1 and 1000
time = np.linspace(1, 1000, 100)

# computes the sine value of each of those points
mags = np.sin(time)

# scales the sine values so that the mean is 0 and the variance is 1 (the documentation specifies that this must be done)
scaled_mags = (mags-mags.mean())/mags.std()

# generates 1000 frequencies between 0.01 and 1
freqs = np.linspace(0.01, 1, 1000)

# computes the Lomb Scargle Periodogram of the time and scaled magnitudes using each frequency as a guess
periodogram = spectral.lombscargle(time, scaled_mags, freqs)

# returns the inverse of the frequence (i.e. the period) of the largest periodogram value
print "1/2pi = " + str(1/(2*np.pi))
print "Frequency = " + str(freqs[np.argmax(periodogram)] / 2.0 / np.pi)

The following is printed. Is fine. I guess. The reason we divide the lombscargle result with 2pi is that, we need to convert radian to frequency. (f = radian / 2pi)

1/2pi = 0.159154943092
Frequency = 0.159154943092

However, thing seems goes wrong for the following case.

Frequency for sin(2x), which is 1/(pi)

# imports the numerical array and scientific computing packages
import numpy as np
import scipy as sp
from scipy.signal import spectral

# generates 100 evenly spaced points between 1 and 1000
time = np.linspace(1, 1000, 100)

# computes the sine value of each of those points
mags = np.sin(2 * time)

# scales the sine values so that the mean is 0 and the variance is 1 (the documentation specifies that this must be done)
scaled_mags = (mags-mags.mean())/mags.std()

# generates 1000 frequencies between 0.01 and 1
freqs = np.linspace(0.01, 1, 1000)

# computes the Lomb Scargle Periodogram of the time and scaled magnitudes using each frequency as a guess
periodogram = spectral.lombscargle(time, scaled_mags, freqs)

# returns the inverse of the frequence (i.e. the period) of the largest periodogram value
print "1/pi = " + str(1/(np.pi))
print "Frequency = " + str(freqs[np.argmax(periodogram)] / 2.0 / np.pi)

The following is being printed.

1/pi = 0.318309886184
Frequency = 0.0780862900972

Seem incorrect. Any step that I had missed out?

like image 901
Cheok Yan Cheng Avatar asked Jan 25 '13 09:01

Cheok Yan Cheng


People also ask

How do you find the power spectral density of a signal in Python?

pyplot. psd() function is used to plot power spectral density. In the Welch's average periodogram method for evaluating power spectral density (say, Pxx), the vector 'x' is divided equally into NFFT segments. Every segment is windowed by the function window and detrended by the function detrend.

What is Lombscargle?

The Lomb–Scargle periodogram is a method that allows efficient computation of a Fourier-like power spectrum estimator from such unevenly sampled data, resulting in an intuitive means of determining the period of oscillation.

What is Nperseg in Python?

I actually thought that nperseg is the number of time localised points and nfft is the number of frequency used.

What is Periodogram in Python?

The Lomb-Scargle periodogram (named for Lomb (1976) and Scargle (1982)) is a classic method for finding periodicity in irregularly-sampled data. It is in many ways analogous to the more familiar Fourier Power Spectral Density (PSD) often used for detecting periodicity in regularly-sampled data.


1 Answers

You are rightfully expecting the peak to show up at 1 / pi, but the highest frequency you are testing is 1 / 2 / pi... Try the following single change :

freqs = linspace(0.01, 3, 3000)

and now the output is the expected:

1/pi = 0.318309886184
Frequency = 0.318311478264

Note, though, that if you plot periodogram against freqs / 2 / np.pi, the graph looks like this:

enter image description here

So for a more complicated signal, you cannot rely on just looking for the max of periodogram to find the dominant frequency, because the harmonics may fool you.

like image 151
Jaime Avatar answered Oct 07 '22 09:10

Jaime