laszukdawid / PyEMD

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

flatten does not work #27

Closed hongkahjun closed 5 years ago

hongkahjun commented 6 years ago

Hello

indmin = np.array([np.nonzero(T==t)[0] for t in min_pos]).flatten() indmax = np.array([np.nonzero(T==t)[0] for t in max_pos]).flatten()

does not flatten into one single array because the intermediate array is an object array if I dont specify a position or time array.

laszukdawid commented 6 years ago

Hi, I'm not sure if I understand what are you asking for, or stating. How is this related to package's functionality?

I'm guessing you are referring to lines 114-115 of EMD_matlab.py module. Firstly, this module is a legacy leftover as the algorithm was proven to be of the worst performance. Secondly, these lines seem to be doing what they're intended.

>>> T = np.arange(0, 1, 0.01)
>>> minPos = [T[2], T[20], T[-12]]
>>> indmin = np.array([np.nonzero(T==t)[0] for t in minPos]).flatten() 
>>> indmin.shape
(3,)
>>> indmin
array([ 2, 20, 88])
>>> indmin[0]
2
hongkahjun commented 6 years ago

Hi

Sorry was in a rush when I posted this. The 2 lines of code are from EMD.py, line 307 and 308. The version is 0.2.5. When I dont include a T parameter in EMD.emd(), the code throws an error. Specifically, File "C:\Anaconda3\lib\site-packages\PyEMD\EMD.py", line 316, in _prepare_points_simple if indmax[0] < indmin[0]: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

When I look into the debug, I find that indmax and indmin are numpy array of objects, and the objects are arrays of shape (2,) dtype int64

When I include a T parameter, the code runs smoothly, and indmax and indmin are arrays of int64.

laszukdawid commented 6 years ago

I've tried running emd without explicit T and cannot reproduce the error. Based on the numpy exception either indmin or indmax is a 2D array. If they were of shape (2, ) then that's fine (see example below). What numpy version have you installed? Any chance you could paste exactly what you're trying? Maybe you could share your testing signal?

Could you please run this:

import numpy as np
from PyEMD import EMD
signal = np.random.random(200)
emd = EMD()
imfs = emd(signal, max_imf=3)
print(imfs.shape)

Comparing arrays with shape (2,) and type int64

>>> import numpy as np
>>> indmin = np.arange(2, dtype=np.int64)
>>> indmax = np.array([5, 2], dtype=np.int64)
>>> indmin.shape
(2,)
>>> indmax.shape
(2,)
>>> indmin[0] < indmax[0]
True
georgedimitriadis commented 5 years ago

Hi,

I run into the same problem (python 3.5, numpy 1.14.2) and I resolved it by doing ind_min = np.array([np.nonzero(T==t)[0][0] for t in min_pos]).flatten() ind_max = np.array([np.nonzero(T==t)[0][0] for t in max_pos]).flatten()

np.nonzero(T==t)[0] still returns an array (single valued) and then the ind_min and ind_max are arrays of arrays (despite the flatten)

I am not sure though if this is the correct solution (since I am getting other errors further down).