jaidevd / pyhht

Python toolbox for the Hilbert-Huang transform
Other
254 stars 88 forks source link

Force stopping for complex signals #42

Closed WRAR891 closed 3 years ago

WRAR891 commented 6 years ago

Hi,

I'd really like to try your package, but there seems to be a problem handling complex valued inputs. I created several (simple) complex signals, and for each I receive: Force stopping EMD: amplitude too small.

example code: n = 1000 fc = 0.25 t = np.linspace(0, 1, n) x = np.exp(2.0j np.pi fc * t)

X = np.fft.fftshift(np.fft.fft(x)) X /= np.max(X) plt.plot(np.linspace(-0.5, 0.5, len(X)), np.abs(X) ** 2) plt.show()

decomposer = EMD(x, is_mode_complex=True) imfs = decomposer.decompose() plot_imfs(x, imfs, t)

Any insight you may have would be very helpful. Thanks.

jaidevd commented 6 years ago

Hi @Wrar891

This is strange. The is_mode_complex method was made precisely to deal with such signals. Thanks for reporting this. I'll check it out in a couple of days.

Thanks

WRAR891 commented 6 years ago

Thanks, Much appreciated! For what it's worth, I'm using Python 2.7. Can't see how that would cause it...

jaidevd commented 6 years ago

Hi @WRAR891

Can you please re-install from the latest dev branch and try this example again? Note that you don't have to specify is_mode_complex anymore, it will be automatically set if the input has any nonzero imaginary components.

Also, in this particular example, the input is only a quarter of a sinusoid, so you should get the same signal back as the IMF. Complex / Bivariate EMD in general should be fixed now. Please let me know what you see.

Thanks,

WRAR891 commented 6 years ago

Thanks for the effort. So the EMD does seem to return values not for complex-valued inputs. I'll work it a bit and let you know If I expose any other issues or suspect a problem.

WRAR891 commented 6 years ago

Just noticed a Typo on last comment, it should read: ... So the EMD does seem to return values for complex-valued inputs...

WRAR891 commented 6 years ago

jaidevd,

I'm not completely certain that EMD is working 100% correctly for complex-valued inputs. Taking an example from your tutorial:

t = np.linspace(0, 1, 1000) modes = np.sin(2 np.pi 5 t) + np.sin(2 np.pi 10 t) x = modes + t

X = np.fft.fftshift(np.fft.fft(x)) X /= np.max(X) plt.plot(np.linspace(-0.5, 0.5, len(X)), np.abs(X) ** 2) plt.show() ex1a

decomposer = EMD(x) imfs = decomposer.decompose() plot_imfs(x, imfs)

ex1b

which seems reasonable.

-------------------------------------------------------------------------------------------------------

Now lets put some spin on the tones...

def co(signal, fc): t = np.arange(0, len(signal)) return np.multiply(signal, np.exp(2.0j np.pi fc * t))

.... t = np.linspace(0, 1, 1000) modes = np.sin(2 np.pi 5 t) + np.sin(2 np.pi 10 t) x = modes + t

x = co(x, fc=0.1)

X = np.fft.fftshift(np.fft.fft(x)) X /= np.max(X) plt.plot(np.linspace(-0.5, 0.5, len(X)), np.abs(X) ** 2) plt.show() ex2a

decomposer = EMD(x) imfs = decomposer.decompose() plot_imfs(x, imfs) ex2b

This doesn't seem correct. We just translated the tones by fc (which = 0.1). I think that the modes should be the same, with the frequencies shifted by 0.1*fs (for any fs). Am I misunderstanding something? As an aside, plot_imfs() throws an exception if the input shape in (1,N), i.e. only one mode.

Respectfully,

jaidevd commented 6 years ago

@WRAR891 It seems like the first IMF in your example is the signal itself and everything else is negligible, that's clearly incorrect. I'll take a look tomorrow.

jaidevd commented 6 years ago

Whoa! @WRAR891 I just understood the point, simply shifting the frequencies is resulting in hugely different IMFs. This is also a bug.

jaidevd commented 3 years ago

Apologies for the delay on this. This will be fixed in the v0.2 release, targeted for end of February 2021.