@@ -100,6 +100,7 @@ def __init__(
100100 )
101101
102102 # Creating a random number generator
103+ self .random_seed = random_seed
103104 self .rng = np .random .RandomState (seed = random_seed )
104105
105106 # Generated noise sequence
@@ -119,7 +120,7 @@ def __call__(
119120 self ,
120121 signal : np .ndarray ,
121122 time : Optional [np .ndarray ] = None ,
122- max_imfs : Optional [int ] = - 1 ,
123+ max_imfs : Optional [int ] = None ,
123124 progress : bool = False ,
124125 ) -> np .ndarray :
125126 """allow instances to be called like functions"""
@@ -131,7 +132,13 @@ def __str__(self) -> str:
131132 """Get the full name and abbreviation of the algorithm"""
132133 return "Complete Ensemble Empirical Mode Decomposition with Adaptive Noise (CEEMDAN)"
133134
134- def generate_noise (
135+ def update_random_seed (self , random_seed : int ) -> None :
136+ """Update the random seed for random number generator to generate noise"""
137+ self .random_seed = random_seed
138+ # Create the random state generate
139+ self .rng = np .random .RandomState (seed = random_seed )
140+
141+ def _generate_noise (
135142 self , scale : float , size : Union [int , Sequence [int ]]
136143 ) -> np .ndarray :
137144 """
@@ -177,7 +184,7 @@ def _run_eemd(
177184 self ,
178185 signal : np .ndarray ,
179186 time : Optional [np .ndarray ] = None ,
180- max_imfs : Optional [int ] = - 1 ,
187+ max_imfs : Optional [int ] = None ,
181188 progress : Optional [bool ] = True ,
182189 ) -> np .ndarray :
183190 """Perform the specified EEMD algorithm to obtain the corresponding signal decomposition results."""
@@ -231,20 +238,26 @@ def _update_trial(self, trial: int) -> np.ndarray:
231238 noise = self .epsilon * self .all_noise_EMD [trial ][0 ]
232239
233240 # Return the result of a single EMD execution
234- return self ._emd (self ._signal + noise , self ._time , self .max_imfs )
241+ return self ._run_emd (self ._signal + noise , self ._time , self .max_imfs )
235242
236- def _emd (
243+ def _run_emd (
237244 self ,
238245 signal : np .ndarray ,
239246 time : Optional [np .ndarray ] = None ,
240247 max_imfs : Optional [int ] = None ,
241248 ) -> np .ndarray :
242249 """
243- Vanilla Empirical Mode Decomposition method
250+ Vanilla Empirical Mode Decomposition method.
244251
245- Perform the specified EMD algorithm to obtain the corresponding signal decomposition results.
252+ :param signal: the input 1D ndarray signal.
253+ :param time: the time array.
254+ :param max_imfs: the maximum number of IMFs to be decomposed.
255+ :return: the decomposed IMFs of the input signal.
246256 """
247- return self .EMD .fit_transform (signal = signal , time = time , max_imfs = max_imfs )
257+ # Perform the specified EMD algorithm to obtain the corresponding signal decomposition results.
258+ imfs = self .EMD .fit_transform (signal = signal , time = time , max_imfs = max_imfs )
259+
260+ return imfs
248261
249262 def get_imfs_and_residue (self ) -> Tuple [np .ndarray , np .ndarray ]:
250263 """
@@ -346,10 +359,12 @@ def fit_transform(
346359 scale_s = np .std (signal )
347360 signal = signal / scale_s
348361
362+ # Begin executing the specific decomposition algorithm
349363 max_imfs = self .max_imfs if max_imfs is None else max_imfs
364+ total = (max_imfs - 1 ) if max_imfs != - 1 else None
350365
351366 # Define the noise sequences to be added
352- self .all_noises = self .generate_noise (
367+ self .all_noises = self ._generate_noise (
353368 self .noise_scale , size = (self .trials , signal .size )
354369 )
355370
@@ -358,14 +373,10 @@ def fit_transform(
358373
359374 # Create the first IMF
360375 last_imf = self ._run_eemd (signal , time , max_imfs = 1 , progress = progress )[0 ]
361- res = np .empty (signal .size )
362376
363377 all_cimfs = last_imf .reshape ((- 1 , last_imf .size ))
364378 prev_res = signal - last_imf
365379
366- # Begin executing the specific decomposition algorithm
367- total = (max_imfs - 1 ) if max_imfs != - 1 else None
368-
369380 # Create an iterator object for signal decomposition
370381 it = (
371382 iter
@@ -374,7 +385,7 @@ def fit_transform(
374385 )
375386
376387 # Begin the algorithm's iteration
377- for i in it (range (max_imfs - 1 )):
388+ for _ in it (range (max_imfs - 1 )):
378389 # Number of IMFs currently decomposed
379390 imf_number = all_cimfs .shape [0 ]
380391
@@ -387,15 +398,17 @@ def fit_transform(
387398 noise_imf = self .all_noise_EMD [trial ]
388399 res = prev_res .copy ()
389400
401+ # add noise for every imf to be decomposed.
390402 if len (noise_imf ) > imf_number :
391403 res += beta * noise_imf [imf_number ]
392404
393405 # Extract the local mean, which is at the 2nd position
394- imfs = self ._emd (res , time , max_imfs = 1 )
406+ imfs = self ._run_emd (res , time , max_imfs = 1 )
395407 local_mean += imfs [- 1 ] / self .trials
396408
397409 # Record the results of this decomposition
398410 last_imf = prev_res - local_mean
411+ # vstack the new imf
399412 all_cimfs = np .vstack ((all_cimfs , last_imf ))
400413 prev_res = local_mean .copy ()
401414
@@ -406,6 +419,7 @@ def fit_transform(
406419 break
407420
408421 # Clear all IMF noise
422+ # The noise will be initialized for the new input signal
409423 del self .all_noise_EMD [:]
410424
411425 # Record the results of this decomposition
@@ -415,16 +429,3 @@ def fit_transform(
415429 self .residue = signal * scale_s - np .sum (self .imfs , axis = 0 )
416430
417431 return all_cimfs
418-
419-
420- if __name__ == '__main__' :
421- from pysdkit .data import test_univariate_signal
422- from pysdkit .plot import plot_IMFs
423-
424- time , signal = test_univariate_signal ()
425-
426- for max_imfs in [2 , 3 , 4 , 5 , 6 , 7 ]:
427- ceemdan = CEEMDAN (max_imfs = max_imfs )
428- imfs = ceemdan .fit_transform (signal )
429-
430- print (max_imfs , imfs .shape )
0 commit comments