laszukdawid / PyEMD

Python implementation of Empirical Mode Decompoisition (EMD) method
https://pyemd.readthedocs.io/
Apache License 2.0
867 stars 224 forks source link

Fix CEEMDAN and test it #46

Closed nescirem closed 5 years ago

nescirem commented 5 years ago
  1. The original signal S should not be changed. So I use S[:] = S/scale_s instead of S = S/scale_s to fix it.
  2. Add a test case that reflects what I am trying to fix.
  3. When I call the function ceemdan multiple times in one main program, the program will only use the random noise which was generated in the first call, though the different random seed is given before each call. So I cleaned the relevant list/array after each call to the function. Maybe there will be a better way to fix that? I need some help.

    I understand signal processing is not something that can be sloppy, so I test it to check I have Fixed that: (IMFs' MD5 is calculated to make sure the IMFs in a different case is same or not)

Before: (seed=114514, MD5=f5ac70aa2e917d87187d8b76207354e0) before_seed114514-f5ac70aa2e917d87187d8b76207354e0.png Fig.1 case A.1 The original Signal is scaled and the residuum is wrong.

After: (seed=114514, MD5=f5ac70aa2e917d87187d8b76207354e0) after_seed114514-f5ac70aa2e917d87187d8b76207354e0.png Fig.2 case A.2

Before: (seed=89889, MD5=0b528aef0f9c710ef02a66685dd4e8ea) before_seed89889-0b528aef0f9c710ef02a66685dd4e8ea.png Fig.3 case B.1

After: (seed=89889, MD5=0b528aef0f9c710ef02a66685dd4e8ea) after_seed89889-0b528aef0f9c710ef02a66685dd4e8ea.png Fig.4 case B.2

After: (random seed, MD5=9452d9dd49ba9f16a7eb18d60519bf31) after_randomSeed-9452d9dd49ba9f16a7eb18d60519bf31.png Fig.5 case C

After: (another random seed, MD5=cc2aa1a1d229899e64f59a88090ead5e) after_randomSeed-cc2aa1a1d229899e64f59a88090ead5e.png Fig.6 case D

Obviously what I did does not change the IMFs (if the random seed is the same).


Sample code of the case A.2 is here:

import wave
import numpy as np
import pylab as plt
import hashlib

from PyEMD import CEEMDAN#, Visualisation#, EMD, Visualisation

# CEEMDAN options
max_imf = -1

# Import acoustic signal
N = 513
tMin, tMax = 0, 1
t = np.linspace(tMin, tMax, N)

sin = lambda x, p: np.sin(2*np.pi*x*t+p)
S = 3*np.sin(15*2*np.pi*t*(t-0.8)**2)
S += 2*np.sin(18*2*np.pi*t*(0.3*t))
S += 4*sin(14, 2.7)*(t+0.2)**1.5
S += t**1.7 -t

# Prepare and run CEEMDAN
ceemdan = CEEMDAN()

seed = 114514
ceemdan.noise_seed(seed)
C_IMFs = ceemdan(S, t, max_imf)

m2 = hashlib.md5()
m2.update(C_IMFs)
md5 = m2.hexdigest()
print("the MD5 of IMFs is:"+md5)

imfNo  = C_IMFs.shape[0]

# Plot results in a grid
c = np.floor(np.sqrt(imfNo+2))
r = np.ceil((imfNo+2)/c)

plt.ioff()
plt.figure(figsize=(10,10))

plt.subplot(r,c,1)
plt.plot(t, S, 'r')
plt.xlim((tMin, tMax))
plt.title("Original signal")

plt.subplot(r,c,2)
plt.plot(t, S-np.sum(C_IMFs, axis=0), 'r')
plt.xlim((tMin, tMax))
plt.title("Residuum")

for num in range(imfNo):
    plt.subplot(r,c,num+3)
    plt.plot(t, C_IMFs[num],'g')
    plt.xlim((tMin, tMax))
    plt.title("Imf "+str(num+1))

plt.savefig("after_seed"+str(seed)+"-"+md5)
print("Done")
codecov-io commented 5 years ago

Codecov Report

Merging #46 into master will increase coverage by 0.88%. The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #46      +/-   ##
==========================================
+ Coverage    68.5%   69.39%   +0.88%     
==========================================
  Files          17       17              
  Lines        1810     1820      +10     
  Branches      166      167       +1     
==========================================
+ Hits         1240     1263      +23     
+ Misses        538      528      -10     
+ Partials       32       29       -3
Impacted Files Coverage Δ
PyEMD/tests/test_ceemdan.py 97.89% <100%> (-0.95%) :arrow_down:
PyEMD/CEEMDAN.py 94.3% <100%> (+4.96%) :arrow_up:
PyEMD/EMD.py 87.5% <0%> (+0.24%) :arrow_up:
PyEMD/tests/test_eemd.py 100% <0%> (+3.17%) :arrow_up:
PyEMD/EEMD.py 83.58% <0%> (+7.46%) :arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update de373ec...09993ee. Read the comment docs.