PySDKit 0.4.26__tar.gz → 0.4.27__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pysdkit-0.4.26 → pysdkit-0.4.27}/PKG-INFO +3 -3
- {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/PKG-INFO +3 -3
- {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/SOURCES.txt +7 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/README.md +2 -2
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pyproject.toml +3 -1
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/__init__.py +7 -1
- pysdkit-0.4.27/pysdkit/_alif/__init__.py +6 -0
- pysdkit-0.4.27/pysdkit/_alif/_helpers.py +248 -0
- pysdkit-0.4.27/pysdkit/_alif/alif.py +191 -0
- pysdkit-0.4.27/pysdkit/_alif/data/__init__.py +1 -0
- pysdkit-0.4.27/pysdkit/_alif/data/prefixed_double_filter.npy +0 -0
- pysdkit-0.4.27/pysdkit/_alif/iterative_filtering.py +175 -0
- pysdkit-0.4.27/pysdkit/tests/test_alif.py +102 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/LICENSE +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/dependency_links.txt +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/requires.txt +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/top_level.txt +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/_find_extrema.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/_prepare_points.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/_splines.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/ceemdan.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/eemd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/efd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/emd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/hht/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/hht/frequency.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/hht/hht.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/memd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/remd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/tvf_emd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/bemd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/bmemd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/emd2d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_esmd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_esmd/esmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ewt/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ewt/ewt.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ewt/ewt2d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/extrema.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/faemd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/faemd2d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/faemd3d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/filter.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_fmd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_fmd/fmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_fmd/nfmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_hvd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_hvd/hvd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ifd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_itd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_itd/itd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_jmd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_jmd/jmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_jmd/mjmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_lmd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_lmd/lmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_lmd/rlmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_osd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ssa/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ssa/ssa.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/acmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/avmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/ba_acmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/base.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/mvmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/svmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/vmd_c.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/vmd_f.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/vme.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd2d/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd2d/cvmd2d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd2d/vmd2d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/avncmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/incmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/mncmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/vncmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_add_noise.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_cube.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_generator.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_image.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_models.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_test_univariate.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_time_series.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/texture.txt +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/_approxiamte_entropy.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/_permutation_entropy.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/_sample_entropy.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_base.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_kmeans.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_knn.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_pca.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_fourier_spectra.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_functions.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_plot_images.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_plot_imfs.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_plot_signal.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_cube.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_image.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_signal.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_univariate_signal.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/models/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/models/test_knn.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/models/test_pca.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/run_all.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_avncmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_ceemdan.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_emd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_ewt.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_faemd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_faemd2d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_faemd3d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_itd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_lmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_moving_decomp.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_rlmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_stl.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_vmd.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_vmd2d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_dtw.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_moving_decomp.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_mstl.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_stl.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/__init__.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_cite.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_correlation.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_diagnalization.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_differ.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_fft.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_function.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_hilbert.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_instantaneous.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_kernel_matrix.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_mirror.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_process.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_smooth1d.py +0 -0
- {pysdkit-0.4.26 → pysdkit-0.4.27}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PySDKit
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.27
|
|
4
4
|
Summary: A Python library for signal decomposition algorithms with a unified interface.
|
|
5
5
|
Author: josefinez, Deeksha Manjunath, Yuan Feng, JacktheFowler
|
|
6
6
|
Author-email: Whenxuan Wang <wwhenxuan@gmail.com>, RuiZhe Wang <3133986068@qq.com>, WenTong Zhao <23049200290@stu.xidian.edu.cn>
|
|
@@ -159,7 +159,7 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
|
|
|
159
159
|
| [`FAEMD3D`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_faemd/faemd3d.py) (Three-Dimensional Fast and Adaptive EMD) | [[paper]](https://ieeexplore.ieee.org/document/8447300) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/71270-fast-and-adaptive-multivariate-and-multidimensional-emd) | ✖️ |
|
|
160
160
|
| [`HVD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_hvd/hvd.py) (Hilbert Vibration Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X06001556) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/178804-hilbert-vibration-decomposition?s_tid=FX_rc1_behav) | ✔️ |
|
|
161
161
|
| [`ITD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_itd/itd.py) (Intrinsic Time-Scale Decomposition) | [[paper]](https://royalsocietypublishing.org/doi/10.1098/rspa.2006.1761) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/69380-intrinsic-time-scale-decomposition-itd) | ✔️ |
|
|
162
|
-
| [`ALIF`]() (Adaptive Local Iterative Filtering) | [[paper]](https://arxiv.org/abs/1411.6051) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56210-alif) |
|
|
162
|
+
| [`ALIF`]() (Adaptive Local Iterative Filtering) | [[paper]](https://arxiv.org/abs/1411.6051) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56210-alif) | ✔️ |
|
|
163
163
|
| [`LMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_lmd/lmd.py) (Local Mean Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S1051200418308133?via%3Dihub) | [[code]](https://github.com/shownlin/PyLMD/blob/master/PyLMD/LMD.py) | ✔️ |
|
|
164
164
|
| [`RLMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_lmd/rlmd.py) (Robust Local Mean Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S0888327017301619) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/66935-robust-local-mean-decomposition-rlmd) | ✔️ |
|
|
165
165
|
| [`FMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_fmd/fmd.py) (Feature Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/document/9732251) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/108099-feature-mode-decomposition-fmd) | ✖️ |
|
|
@@ -176,7 +176,7 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
|
|
|
176
176
|
| [`VNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/vncmd.py) (Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/document/7990179) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/64292-variational-nonlinear-chirp-mode-decomposition) | ✔️ |
|
|
177
177
|
| [`INCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/incmd.py) (Iterative Nonlinear Chirp Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X2030403X?via%3Dihub) | [[code]](https://github.com/sheadan/IterativeNCMD) | ✔️ |
|
|
178
178
|
| [`MNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/mncmd.py) (Multivariate Nonlinear Chirp Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S0165168420302103) | [[code]]() | ✖️ |
|
|
179
|
-
| [`AVNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/avncmd.py) (Adaptive Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/abstract/document/9746147) | [[code]](https://github.com/HauLiang/AVNCMD) |
|
|
179
|
+
| [`AVNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/avncmd.py) (Adaptive Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/abstract/document/9746147) | [[code]](https://github.com/HauLiang/AVNCMD) | ✔️ |
|
|
180
180
|
| [`ACMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vmd/acmd.py) (Adaptive Chirp Mode Decomposition) | [[paper]]() | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/121373-data-driven-adaptive-chirp-mode-decomposition?s_tid=srchtitle) | ✔️ |
|
|
181
181
|
| [`BA-ACMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vmd/ba_acmd.py) (Bandwidth-aware adaptive chirp mode decomposition) | [[paper]](https://journals.sagepub.com/doi/abs/10.1177/14759217231174699) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/132792-bandwidth-aware-adaptive-chirp-mode-decomposition-ba-acmd?s_tid=srchtitle) | ✖️ |
|
|
182
182
|
| [`JMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/jmd.py) (Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169388-jump-plus-am-fm-mode-decomposition-jmd?s_tid=prof_contriblnk) | ️✔️ |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PySDKit
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.27
|
|
4
4
|
Summary: A Python library for signal decomposition algorithms with a unified interface.
|
|
5
5
|
Author: josefinez, Deeksha Manjunath, Yuan Feng, JacktheFowler
|
|
6
6
|
Author-email: Whenxuan Wang <wwhenxuan@gmail.com>, RuiZhe Wang <3133986068@qq.com>, WenTong Zhao <23049200290@stu.xidian.edu.cn>
|
|
@@ -159,7 +159,7 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
|
|
|
159
159
|
| [`FAEMD3D`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_faemd/faemd3d.py) (Three-Dimensional Fast and Adaptive EMD) | [[paper]](https://ieeexplore.ieee.org/document/8447300) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/71270-fast-and-adaptive-multivariate-and-multidimensional-emd) | ✖️ |
|
|
160
160
|
| [`HVD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_hvd/hvd.py) (Hilbert Vibration Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X06001556) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/178804-hilbert-vibration-decomposition?s_tid=FX_rc1_behav) | ✔️ |
|
|
161
161
|
| [`ITD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_itd/itd.py) (Intrinsic Time-Scale Decomposition) | [[paper]](https://royalsocietypublishing.org/doi/10.1098/rspa.2006.1761) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/69380-intrinsic-time-scale-decomposition-itd) | ✔️ |
|
|
162
|
-
| [`ALIF`]() (Adaptive Local Iterative Filtering) | [[paper]](https://arxiv.org/abs/1411.6051) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56210-alif) |
|
|
162
|
+
| [`ALIF`]() (Adaptive Local Iterative Filtering) | [[paper]](https://arxiv.org/abs/1411.6051) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56210-alif) | ✔️ |
|
|
163
163
|
| [`LMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_lmd/lmd.py) (Local Mean Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S1051200418308133?via%3Dihub) | [[code]](https://github.com/shownlin/PyLMD/blob/master/PyLMD/LMD.py) | ✔️ |
|
|
164
164
|
| [`RLMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_lmd/rlmd.py) (Robust Local Mean Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S0888327017301619) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/66935-robust-local-mean-decomposition-rlmd) | ✔️ |
|
|
165
165
|
| [`FMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_fmd/fmd.py) (Feature Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/document/9732251) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/108099-feature-mode-decomposition-fmd) | ✖️ |
|
|
@@ -176,7 +176,7 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
|
|
|
176
176
|
| [`VNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/vncmd.py) (Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/document/7990179) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/64292-variational-nonlinear-chirp-mode-decomposition) | ✔️ |
|
|
177
177
|
| [`INCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/incmd.py) (Iterative Nonlinear Chirp Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X2030403X?via%3Dihub) | [[code]](https://github.com/sheadan/IterativeNCMD) | ✔️ |
|
|
178
178
|
| [`MNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/mncmd.py) (Multivariate Nonlinear Chirp Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S0165168420302103) | [[code]]() | ✖️ |
|
|
179
|
-
| [`AVNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/avncmd.py) (Adaptive Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/abstract/document/9746147) | [[code]](https://github.com/HauLiang/AVNCMD) |
|
|
179
|
+
| [`AVNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/avncmd.py) (Adaptive Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/abstract/document/9746147) | [[code]](https://github.com/HauLiang/AVNCMD) | ✔️ |
|
|
180
180
|
| [`ACMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vmd/acmd.py) (Adaptive Chirp Mode Decomposition) | [[paper]]() | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/121373-data-driven-adaptive-chirp-mode-decomposition?s_tid=srchtitle) | ✔️ |
|
|
181
181
|
| [`BA-ACMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vmd/ba_acmd.py) (Bandwidth-aware adaptive chirp mode decomposition) | [[paper]](https://journals.sagepub.com/doi/abs/10.1177/14759217231174699) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/132792-bandwidth-aware-adaptive-chirp-mode-decomposition-ba-acmd?s_tid=srchtitle) | ✖️ |
|
|
182
182
|
| [`JMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/jmd.py) (Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169388-jump-plus-am-fm-mode-decomposition-jmd?s_tid=prof_contriblnk) | ️✔️ |
|
|
@@ -7,6 +7,12 @@ PySDKit.egg-info/dependency_links.txt
|
|
|
7
7
|
PySDKit.egg-info/requires.txt
|
|
8
8
|
PySDKit.egg-info/top_level.txt
|
|
9
9
|
pysdkit/__init__.py
|
|
10
|
+
pysdkit/_alif/__init__.py
|
|
11
|
+
pysdkit/_alif/_helpers.py
|
|
12
|
+
pysdkit/_alif/alif.py
|
|
13
|
+
pysdkit/_alif/iterative_filtering.py
|
|
14
|
+
pysdkit/_alif/data/__init__.py
|
|
15
|
+
pysdkit/_alif/data/prefixed_double_filter.npy
|
|
10
16
|
pysdkit/_emd/__init__.py
|
|
11
17
|
pysdkit/_emd/_find_extrema.py
|
|
12
18
|
pysdkit/_emd/_prepare_points.py
|
|
@@ -97,6 +103,7 @@ pysdkit/plot/_plot_imfs.py
|
|
|
97
103
|
pysdkit/plot/_plot_signal.py
|
|
98
104
|
pysdkit/tests/__init__.py
|
|
99
105
|
pysdkit/tests/run_all.py
|
|
106
|
+
pysdkit/tests/test_alif.py
|
|
100
107
|
pysdkit/tests/test_avncmd.py
|
|
101
108
|
pysdkit/tests/test_ceemdan.py
|
|
102
109
|
pysdkit/tests/test_emd.py
|
|
@@ -105,7 +105,7 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
|
|
|
105
105
|
| [`FAEMD3D`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_faemd/faemd3d.py) (Three-Dimensional Fast and Adaptive EMD) | [[paper]](https://ieeexplore.ieee.org/document/8447300) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/71270-fast-and-adaptive-multivariate-and-multidimensional-emd) | ✖️ |
|
|
106
106
|
| [`HVD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_hvd/hvd.py) (Hilbert Vibration Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X06001556) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/178804-hilbert-vibration-decomposition?s_tid=FX_rc1_behav) | ✔️ |
|
|
107
107
|
| [`ITD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_itd/itd.py) (Intrinsic Time-Scale Decomposition) | [[paper]](https://royalsocietypublishing.org/doi/10.1098/rspa.2006.1761) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/69380-intrinsic-time-scale-decomposition-itd) | ✔️ |
|
|
108
|
-
| [`ALIF`]() (Adaptive Local Iterative Filtering) | [[paper]](https://arxiv.org/abs/1411.6051) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56210-alif) |
|
|
108
|
+
| [`ALIF`]() (Adaptive Local Iterative Filtering) | [[paper]](https://arxiv.org/abs/1411.6051) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56210-alif) | ✔️ |
|
|
109
109
|
| [`LMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_lmd/lmd.py) (Local Mean Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S1051200418308133?via%3Dihub) | [[code]](https://github.com/shownlin/PyLMD/blob/master/PyLMD/LMD.py) | ✔️ |
|
|
110
110
|
| [`RLMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_lmd/rlmd.py) (Robust Local Mean Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S0888327017301619) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/66935-robust-local-mean-decomposition-rlmd) | ✔️ |
|
|
111
111
|
| [`FMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_fmd/fmd.py) (Feature Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/document/9732251) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/108099-feature-mode-decomposition-fmd) | ✖️ |
|
|
@@ -122,7 +122,7 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
|
|
|
122
122
|
| [`VNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/vncmd.py) (Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/document/7990179) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/64292-variational-nonlinear-chirp-mode-decomposition) | ✔️ |
|
|
123
123
|
| [`INCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/incmd.py) (Iterative Nonlinear Chirp Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X2030403X?via%3Dihub) | [[code]](https://github.com/sheadan/IterativeNCMD) | ✔️ |
|
|
124
124
|
| [`MNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/mncmd.py) (Multivariate Nonlinear Chirp Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/abs/pii/S0165168420302103) | [[code]]() | ✖️ |
|
|
125
|
-
| [`AVNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/avncmd.py) (Adaptive Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/abstract/document/9746147) | [[code]](https://github.com/HauLiang/AVNCMD) |
|
|
125
|
+
| [`AVNCMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vncmd/avncmd.py) (Adaptive Variational Nonlinear Chirp Mode Decomposition) | [[paper]](https://ieeexplore.ieee.org/abstract/document/9746147) | [[code]](https://github.com/HauLiang/AVNCMD) | ✔️ |
|
|
126
126
|
| [`ACMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vmd/acmd.py) (Adaptive Chirp Mode Decomposition) | [[paper]]() | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/121373-data-driven-adaptive-chirp-mode-decomposition?s_tid=srchtitle) | ✔️ |
|
|
127
127
|
| [`BA-ACMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_vmd/ba_acmd.py) (Bandwidth-aware adaptive chirp mode decomposition) | [[paper]](https://journals.sagepub.com/doi/abs/10.1177/14759217231174699) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/132792-bandwidth-aware-adaptive-chirp-mode-decomposition-ba-acmd?s_tid=srchtitle) | ✖️ |
|
|
128
128
|
| [`JMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/jmd.py) (Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169388-jump-plus-am-fm-mode-decomposition-jmd?s_tid=prof_contriblnk) | ️✔️ |
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
A Python library for signal decomposition algorithms.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
__version__ = "0.4.
|
|
5
|
+
__version__ = "0.4.27"
|
|
6
6
|
|
|
7
7
|
# Empirical Mode Decomposition
|
|
8
8
|
from ._emd import EMD
|
|
@@ -73,6 +73,9 @@ from ._vncmd import INCMD
|
|
|
73
73
|
# Adaptive Variational Nonlinear Chirp Mode Decomposition
|
|
74
74
|
from ._vncmd import AVNCMD
|
|
75
75
|
|
|
76
|
+
# Adaptive Local Iterative Filtering
|
|
77
|
+
from ._alif import ALIF
|
|
78
|
+
|
|
76
79
|
# Empirical Wavelet Transform
|
|
77
80
|
from ._ewt import ewt, EWT
|
|
78
81
|
|
|
@@ -136,6 +139,8 @@ Variational Mode Decomposition for 2D Image | VMD2D
|
|
|
136
139
|
Compact VMD for 2D Image | CVMD2D
|
|
137
140
|
Variational Nonlinear Chirp Mode Decomposition | VNCMD
|
|
138
141
|
Iterative Nonlinear Chirp Mode Decomposition | INCMD
|
|
142
|
+
Adaptive Variational Nonlinear Chirp Mode Dec. | AVNCMD
|
|
143
|
+
Adaptive Local Iterative Filtering | ALIF
|
|
139
144
|
Empirical Wavelet Transform | EWT
|
|
140
145
|
Jump Plus AM-FM Mode Decomposition | JMD
|
|
141
146
|
Feature Mode Decomposition | FMD
|
|
@@ -172,6 +177,7 @@ __all__ = [
|
|
|
172
177
|
"VNCMD",
|
|
173
178
|
"INCMD",
|
|
174
179
|
"AVNCMD",
|
|
180
|
+
"ALIF",
|
|
175
181
|
"ewt",
|
|
176
182
|
"EWT",
|
|
177
183
|
"JMD",
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Shared helpers for Iterative Filtering (IF) and Adaptive Local Iterative Filtering (ALIF).
|
|
4
|
+
|
|
5
|
+
MATLAB reference: https://github.com/Cicone/ALIF
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
_FILTER_PATH = os.path.join(
|
|
15
|
+
os.path.dirname(os.path.abspath(__file__)),
|
|
16
|
+
"data",
|
|
17
|
+
"prefixed_double_filter.npy",
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
_MM_CACHE: Optional[np.ndarray] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def load_prefixed_filter() -> np.ndarray:
|
|
24
|
+
"""Load the prefixed double filter shipped with the package."""
|
|
25
|
+
global _MM_CACHE
|
|
26
|
+
if _MM_CACHE is None:
|
|
27
|
+
if not os.path.isfile(_FILTER_PATH):
|
|
28
|
+
raise FileNotFoundError("Missing ALIF filter data: {}".format(_FILTER_PATH))
|
|
29
|
+
_MM_CACHE = np.load(_FILTER_PATH).astype(np.float64).ravel()
|
|
30
|
+
return _MM_CACHE
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_mask_v1(y: np.ndarray, k: float) -> np.ndarray:
|
|
34
|
+
"""
|
|
35
|
+
Resample the prefixed filter ``y`` to a mask of half-width ``k``.
|
|
36
|
+
|
|
37
|
+
Port of MATLAB ``get_mask_v1`` from ALIFv5_4.m / IF_v8_3.m.
|
|
38
|
+
"""
|
|
39
|
+
y = np.asarray(y, dtype=np.float64).ravel()
|
|
40
|
+
n = y.size
|
|
41
|
+
m = (n - 1) / 2.0
|
|
42
|
+
|
|
43
|
+
if k < 0:
|
|
44
|
+
return np.array([], dtype=np.float64)
|
|
45
|
+
|
|
46
|
+
if k <= m:
|
|
47
|
+
if abs(k - round(k)) < 1e-12:
|
|
48
|
+
k_int = int(round(k))
|
|
49
|
+
a = np.zeros(2 * k_int + 1, dtype=np.float64)
|
|
50
|
+
for i in range(1, 2 * k_int + 2):
|
|
51
|
+
s = (i - 1) * (2 * m + 1) / (2 * k_int + 1) + 1
|
|
52
|
+
t = i * (2 * m + 1) / (2 * k_int + 1)
|
|
53
|
+
s2 = np.ceil(s) - s
|
|
54
|
+
t1 = t - np.floor(t)
|
|
55
|
+
cs = int(np.ceil(s))
|
|
56
|
+
ft = int(np.floor(t))
|
|
57
|
+
mid = y[cs - 1 : ft].sum() if ft >= cs else 0.0
|
|
58
|
+
a[i - 1] = mid + s2 * y[cs - 1] + t1 * y[ft - 1]
|
|
59
|
+
return a
|
|
60
|
+
|
|
61
|
+
new_k = int(np.floor(k))
|
|
62
|
+
extra = k - new_k
|
|
63
|
+
c = (2 * m + 1) / (2 * new_k + 1 + 2 * extra)
|
|
64
|
+
a = np.zeros(2 * new_k + 3, dtype=np.float64)
|
|
65
|
+
|
|
66
|
+
t = extra * c + 1
|
|
67
|
+
t1 = t - np.floor(t)
|
|
68
|
+
ft = int(np.floor(t))
|
|
69
|
+
a[0] = y[:ft].sum() + t1 * y[ft - 1]
|
|
70
|
+
|
|
71
|
+
for i in range(2, 2 * new_k + 3):
|
|
72
|
+
s = extra * c + (i - 2) * c + 1
|
|
73
|
+
t = extra * c + (i - 1) * c
|
|
74
|
+
s2 = np.ceil(s) - s
|
|
75
|
+
t1 = t - np.floor(t)
|
|
76
|
+
cs = int(np.ceil(s))
|
|
77
|
+
ft = int(np.floor(t))
|
|
78
|
+
mid = y[cs - 1 : ft].sum() if ft >= cs else 0.0
|
|
79
|
+
a[i - 1] = mid + s2 * y[cs - 1] + t1 * y[ft - 1]
|
|
80
|
+
|
|
81
|
+
t2 = np.ceil(t) - t
|
|
82
|
+
ct = int(np.ceil(t))
|
|
83
|
+
a[-1] = y[ct - 1 :].sum() + t2 * y[ct - 1]
|
|
84
|
+
return a
|
|
85
|
+
|
|
86
|
+
dx = 0.01
|
|
87
|
+
f = y / dx
|
|
88
|
+
dy = m * dx / k
|
|
89
|
+
x_src = np.arange(0.0, m + 1e-12, 1.0)
|
|
90
|
+
x_query = np.arange(0.0, m + 1e-12, m / k)
|
|
91
|
+
b = np.interp(x_query, x_src, f[int(m) : 2 * int(m) + 1])
|
|
92
|
+
a = np.concatenate([b[:0:-1], b]) * dy
|
|
93
|
+
if abs(np.abs(a).sum() - 1.0) > 1e-14:
|
|
94
|
+
a = a / np.abs(a).sum()
|
|
95
|
+
return a
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def maxmins(
|
|
99
|
+
f: np.ndarray,
|
|
100
|
+
extension_type: str = "p",
|
|
101
|
+
tol: float = 1e-15,
|
|
102
|
+
) -> np.ndarray:
|
|
103
|
+
"""
|
|
104
|
+
Locate extrema of ``f`` (0-based indices).
|
|
105
|
+
|
|
106
|
+
Port of MATLAB ``Maxmins_v3_3`` (periodic / constant cases used by IF & ALIF).
|
|
107
|
+
"""
|
|
108
|
+
f = np.asarray(f, dtype=np.float64).ravel()
|
|
109
|
+
n_old = f.size
|
|
110
|
+
if n_old < 3:
|
|
111
|
+
return np.array([], dtype=int)
|
|
112
|
+
|
|
113
|
+
df = np.diff(f)
|
|
114
|
+
h = 0
|
|
115
|
+
|
|
116
|
+
if extension_type == "p":
|
|
117
|
+
while h < n_old - 1 and abs(df[h]) <= tol:
|
|
118
|
+
h += 1
|
|
119
|
+
if h >= n_old - 1:
|
|
120
|
+
return np.array([], dtype=int)
|
|
121
|
+
matlab_h = h + 1
|
|
122
|
+
df = np.diff(np.concatenate([f, f[1 : matlab_h + 1]]))
|
|
123
|
+
n_ext = n_old + matlab_h
|
|
124
|
+
loop_start = matlab_h
|
|
125
|
+
else:
|
|
126
|
+
n_ext = n_old
|
|
127
|
+
loop_start = 1
|
|
128
|
+
if extension_type == "c" and abs(df[0]) <= tol:
|
|
129
|
+
while h < n_old - 1 and abs(df[h]) <= tol:
|
|
130
|
+
h += 1
|
|
131
|
+
loop_start = h + 1
|
|
132
|
+
|
|
133
|
+
maxs = []
|
|
134
|
+
mins = []
|
|
135
|
+
c = 0
|
|
136
|
+
last_df = 0
|
|
137
|
+
posc = 0
|
|
138
|
+
|
|
139
|
+
def _mod_to_0based(matlab_idx: int) -> int:
|
|
140
|
+
m = matlab_idx % n_old
|
|
141
|
+
if m == 0:
|
|
142
|
+
m = n_old
|
|
143
|
+
return m - 1
|
|
144
|
+
|
|
145
|
+
for i_mat in range(loop_start, n_ext - 1):
|
|
146
|
+
i0 = i_mat - 1
|
|
147
|
+
if i0 + 1 >= df.size:
|
|
148
|
+
break
|
|
149
|
+
prod = df[i0] * df[i0 + 1]
|
|
150
|
+
|
|
151
|
+
if -tol <= prod <= tol:
|
|
152
|
+
if df[i0] < -tol:
|
|
153
|
+
last_df = -1
|
|
154
|
+
posc = i_mat
|
|
155
|
+
elif df[i0] > tol:
|
|
156
|
+
last_df = 1
|
|
157
|
+
posc = i_mat
|
|
158
|
+
c += 1
|
|
159
|
+
if df[i0 + 1] < -tol:
|
|
160
|
+
if last_df == 1:
|
|
161
|
+
maxs.append(_mod_to_0based(posc + (c - 1) // 2 + 1))
|
|
162
|
+
c = 0
|
|
163
|
+
if df[i0 + 1] > tol:
|
|
164
|
+
if last_df == -1:
|
|
165
|
+
mins.append(_mod_to_0based(posc + (c - 1) // 2 + 1))
|
|
166
|
+
c = 0
|
|
167
|
+
|
|
168
|
+
if prod < -tol:
|
|
169
|
+
if df[i0] < -tol and df[i0 + 1] > tol:
|
|
170
|
+
m = (i_mat + 1) % n_old
|
|
171
|
+
if m == 0:
|
|
172
|
+
m = 1
|
|
173
|
+
mins.append(m - 1)
|
|
174
|
+
last_df = -1
|
|
175
|
+
elif df[i0] > tol and df[i0 + 1] < -tol:
|
|
176
|
+
m = (i_mat + 1) % n_old
|
|
177
|
+
if m == 0:
|
|
178
|
+
m = 1
|
|
179
|
+
maxs.append(m - 1)
|
|
180
|
+
last_df = 1
|
|
181
|
+
|
|
182
|
+
if c > 0 and extension_type == "c":
|
|
183
|
+
if last_df > 0:
|
|
184
|
+
maxs.append(posc)
|
|
185
|
+
else:
|
|
186
|
+
mins.append(posc)
|
|
187
|
+
|
|
188
|
+
if not maxs and not mins:
|
|
189
|
+
return np.array([], dtype=int)
|
|
190
|
+
|
|
191
|
+
maxmins_arr = np.sort(np.unique(np.array(maxs + mins, dtype=int)))
|
|
192
|
+
if extension_type == "c" and maxmins_arr.size > 0:
|
|
193
|
+
if maxmins_arr[0] != 0 and maxmins_arr[-1] != n_old - 1:
|
|
194
|
+
maxmins_arr = np.unique(np.concatenate([[0], maxmins_arr, [n_old - 1]]))
|
|
195
|
+
return maxmins_arr.astype(int)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def build_ifft_kernel(mask: np.ndarray, n: int) -> np.ndarray:
|
|
199
|
+
"""Embed a short mask into an FFT multiplier of length ``n`` (periodic IF)."""
|
|
200
|
+
a = np.asarray(mask, dtype=np.float64).ravel()
|
|
201
|
+
nza = n - a.size
|
|
202
|
+
if nza < 0:
|
|
203
|
+
raise ValueError("Signal shorter than mask; tile the signal first.")
|
|
204
|
+
|
|
205
|
+
if nza % 2 == 0:
|
|
206
|
+
a_pad = np.concatenate([np.zeros(nza // 2), a, np.zeros(nza // 2)])
|
|
207
|
+
half = (a_pad.size - 1) // 2
|
|
208
|
+
a_centered = np.concatenate([a_pad[half:], a_pad[:half]])
|
|
209
|
+
else:
|
|
210
|
+
a_pad = np.concatenate(
|
|
211
|
+
[np.zeros((nza - 1) // 2), a, np.zeros((nza - 1) // 2 + 1)]
|
|
212
|
+
)
|
|
213
|
+
mid = a_pad.size // 2
|
|
214
|
+
a_centered = np.concatenate([a_pad[mid - 1 :], a_pad[: mid - 1]])
|
|
215
|
+
|
|
216
|
+
return np.real(np.fft.fft(a_centered))
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def adaptive_average(
|
|
220
|
+
h: np.ndarray, mask_lengths: np.ndarray, mm: np.ndarray
|
|
221
|
+
) -> np.ndarray:
|
|
222
|
+
"""
|
|
223
|
+
Position-dependent moving average used by ALIF (``ave = W * h``).
|
|
224
|
+
|
|
225
|
+
Implemented without forming the dense ``N x N`` matrix.
|
|
226
|
+
"""
|
|
227
|
+
h = np.asarray(h, dtype=np.float64).ravel()
|
|
228
|
+
mask_lengths = np.asarray(mask_lengths, dtype=np.float64).ravel()
|
|
229
|
+
n = h.size
|
|
230
|
+
ave = np.zeros(n, dtype=np.float64)
|
|
231
|
+
|
|
232
|
+
for i in range(n):
|
|
233
|
+
k = float(mask_lengths[i])
|
|
234
|
+
if k <= 0:
|
|
235
|
+
continue
|
|
236
|
+
wn = get_mask_v1(mm, k)
|
|
237
|
+
if wn.size == 0:
|
|
238
|
+
continue
|
|
239
|
+
norm1 = np.abs(wn).sum()
|
|
240
|
+
if norm1 <= 0:
|
|
241
|
+
continue
|
|
242
|
+
wn = wn / norm1
|
|
243
|
+
half = (wn.size - 1) // 2
|
|
244
|
+
idxs = np.arange(i - half, i + half + 1) % n
|
|
245
|
+
if idxs.size != wn.size:
|
|
246
|
+
continue
|
|
247
|
+
ave[i] = float(np.dot(wn, h[idxs]))
|
|
248
|
+
return ave
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Adaptive Local Iterative Filtering (ALIF).
|
|
4
|
+
|
|
5
|
+
MATLAB reference: https://github.com/Cicone/ALIF
|
|
6
|
+
Paper: Cicone, A., Liu, J., Zhou, H. Adaptive Local Iterative Filtering for Signal
|
|
7
|
+
Decomposition and Instantaneous Frequency analysis. ACHA, 41(2):384-411, 2016.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
from scipy.interpolate import interp1d
|
|
16
|
+
|
|
17
|
+
from pysdkit._alif._helpers import (
|
|
18
|
+
adaptive_average,
|
|
19
|
+
load_prefixed_filter,
|
|
20
|
+
maxmins,
|
|
21
|
+
)
|
|
22
|
+
from pysdkit._alif.iterative_filtering import IterativeFiltering
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ALIF(object):
|
|
26
|
+
"""
|
|
27
|
+
Adaptive Local Iterative Filtering.
|
|
28
|
+
|
|
29
|
+
Decomposes a (approximately) periodic signal into IMFs plus a trend:
|
|
30
|
+
signal ≈ IMF_1 + ... + IMF_K + trend
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
delta: float = 1e-4,
|
|
36
|
+
ext_points: int = 3,
|
|
37
|
+
max_imfs: int = 100,
|
|
38
|
+
xi: float = 1.6,
|
|
39
|
+
max_inner: int = 500,
|
|
40
|
+
max_time: float = np.inf,
|
|
41
|
+
verbose: int = 0,
|
|
42
|
+
) -> None:
|
|
43
|
+
"""
|
|
44
|
+
:param delta: relative energy stopping criterion for the inner loop
|
|
45
|
+
:param ext_points: stop when fewer than this many extrema remain
|
|
46
|
+
:param max_imfs: maximum number of IMFs (excluding the trend)
|
|
47
|
+
:param xi: mask-length scale factor (``ALIF.xi`` in the MATLAB code)
|
|
48
|
+
:param max_inner: maximum inner-loop iterations per IMF
|
|
49
|
+
:param max_time: wall-clock time budget in seconds
|
|
50
|
+
:param verbose: print progress when > 0
|
|
51
|
+
"""
|
|
52
|
+
self.delta = delta
|
|
53
|
+
self.ext_points = ext_points
|
|
54
|
+
self.max_imfs = max_imfs
|
|
55
|
+
self.xi = xi
|
|
56
|
+
self.max_inner = max_inner
|
|
57
|
+
self.max_time = max_time
|
|
58
|
+
self.verbose = verbose
|
|
59
|
+
|
|
60
|
+
self.imfs: Optional[np.ndarray] = None
|
|
61
|
+
self.mask_lengths: Optional[np.ndarray] = None
|
|
62
|
+
|
|
63
|
+
def __call__(self, signal: np.ndarray) -> np.ndarray:
|
|
64
|
+
return self.fit_transform(signal)
|
|
65
|
+
|
|
66
|
+
def __str__(self) -> str:
|
|
67
|
+
return "Adaptive Local Iterative Filtering (ALIF)"
|
|
68
|
+
|
|
69
|
+
def _instantaneous_periods(
|
|
70
|
+
self, signal: np.ndarray, extrema: np.ndarray
|
|
71
|
+
) -> np.ndarray:
|
|
72
|
+
"""Cubic-interpolate inter-extrema spacings onto the sample grid."""
|
|
73
|
+
n = signal.size
|
|
74
|
+
# MATLAB: T_f = [diff(maxmins) (maxmins(1)+N-maxmins(end))]
|
|
75
|
+
# extrema are 0-based; convert spacings consistently
|
|
76
|
+
ext = extrema.astype(int)
|
|
77
|
+
t_f = np.diff(ext).astype(np.float64)
|
|
78
|
+
t_f = np.append(t_f, ext[0] + n - ext[-1])
|
|
79
|
+
|
|
80
|
+
# Replicate extrema / periods for smooth periodic interpolation
|
|
81
|
+
temp_t = np.tile(t_f, 11)
|
|
82
|
+
temp_ext = np.concatenate([ext + k * n for k in range(11)]).astype(np.float64)
|
|
83
|
+
# Query 1..11N in MATLAB → 0..11N-1 in Python, then take center block
|
|
84
|
+
query = np.arange(1, 11 * n + 1, dtype=np.float64)
|
|
85
|
+
# Interpolate with cubic; MATLAB interp1(...,'cubic')
|
|
86
|
+
# Use 1-based style abscissa: extrema positions as MATLAB indices
|
|
87
|
+
temp_ext_m = temp_ext + 1.0
|
|
88
|
+
interp = interp1d(
|
|
89
|
+
temp_ext_m,
|
|
90
|
+
temp_t,
|
|
91
|
+
kind="cubic",
|
|
92
|
+
fill_value="extrapolate",
|
|
93
|
+
assume_sorted=False,
|
|
94
|
+
)
|
|
95
|
+
temp_i = interp(query)
|
|
96
|
+
return np.asarray(temp_i[5 * n : 6 * n], dtype=np.float64)
|
|
97
|
+
|
|
98
|
+
def _mask_from_periods(self, i_t: np.ndarray) -> np.ndarray:
|
|
99
|
+
"""
|
|
100
|
+
Smooth the instantaneous-period curve with IF and scale by ``2 * xi``.
|
|
101
|
+
"""
|
|
102
|
+
n_try = 1
|
|
103
|
+
i_t0 = i_t.copy()
|
|
104
|
+
while True:
|
|
105
|
+
iff = IterativeFiltering(
|
|
106
|
+
delta=0.001,
|
|
107
|
+
ext_points=3,
|
|
108
|
+
max_imfs=n_try,
|
|
109
|
+
xi=1.6,
|
|
110
|
+
alpha=1.0,
|
|
111
|
+
max_inner=200,
|
|
112
|
+
verbose=0,
|
|
113
|
+
)
|
|
114
|
+
imf_it = iff.fit_transform(i_t0)
|
|
115
|
+
trend = imf_it[-1]
|
|
116
|
+
n_imfs = imf_it.shape[0] - 1
|
|
117
|
+
if trend.min() <= 0 and n_imfs == n_try:
|
|
118
|
+
n_try += 1
|
|
119
|
+
if n_try > 20:
|
|
120
|
+
# Fall back to a positive smooth version of i_t
|
|
121
|
+
trend = np.maximum(i_t, 1.0)
|
|
122
|
+
break
|
|
123
|
+
elif trend.min() <= 0:
|
|
124
|
+
trend = np.maximum(trend, 1.0)
|
|
125
|
+
break
|
|
126
|
+
else:
|
|
127
|
+
break
|
|
128
|
+
|
|
129
|
+
return 2.0 * self.xi * np.asarray(trend, dtype=np.float64)
|
|
130
|
+
|
|
131
|
+
def fit_transform(self, signal: np.ndarray, return_masks: bool = False):
|
|
132
|
+
"""
|
|
133
|
+
Run ALIF on a 1-D signal.
|
|
134
|
+
|
|
135
|
+
:param signal: input samples (treated as one period of a periodic signal)
|
|
136
|
+
:param return_masks: if True, also return the mask-length functions
|
|
137
|
+
:return: IMFs with shape ``(n_imfs + 1, N)`` (last row = trend),
|
|
138
|
+
optionally ``mask_lengths`` with shape ``(n_imfs, N)``
|
|
139
|
+
"""
|
|
140
|
+
f = np.asarray(signal, dtype=np.float64).ravel().copy()
|
|
141
|
+
n = f.size
|
|
142
|
+
mm = load_prefixed_filter()
|
|
143
|
+
|
|
144
|
+
imfs = []
|
|
145
|
+
masks = []
|
|
146
|
+
t0 = time.perf_counter()
|
|
147
|
+
|
|
148
|
+
extrema = maxmins(f, extension_type="p")
|
|
149
|
+
while (
|
|
150
|
+
extrema.size > self.ext_points
|
|
151
|
+
and len(imfs) < self.max_imfs
|
|
152
|
+
and (time.perf_counter() - t0) < self.max_time
|
|
153
|
+
):
|
|
154
|
+
if self.verbose > 0:
|
|
155
|
+
print("ALIF: extracting IMF #{}".format(len(imfs) + 1))
|
|
156
|
+
|
|
157
|
+
i_t = self._instantaneous_periods(f, extrema)
|
|
158
|
+
mask_len = self._mask_from_periods(i_t)
|
|
159
|
+
|
|
160
|
+
if np.ceil(np.max(mask_len)) >= np.floor(n / 2.0):
|
|
161
|
+
if self.verbose > 0:
|
|
162
|
+
print(
|
|
163
|
+
"Mask length exceeds half the signal; "
|
|
164
|
+
"try reducing xi. Stopping IMF extraction."
|
|
165
|
+
)
|
|
166
|
+
break
|
|
167
|
+
|
|
168
|
+
masks.append(mask_len.copy())
|
|
169
|
+
h = f.copy()
|
|
170
|
+
sd = np.inf
|
|
171
|
+
in_step = 0
|
|
172
|
+
while sd > self.delta and in_step < self.max_inner:
|
|
173
|
+
in_step += 1
|
|
174
|
+
ave = adaptive_average(h, mask_len, mm)
|
|
175
|
+
denom = np.linalg.norm(h) ** 2
|
|
176
|
+
sd = (np.linalg.norm(ave) ** 2 / denom) if denom > 0 else 0.0
|
|
177
|
+
h = h - ave
|
|
178
|
+
if self.verbose > 1 and in_step % 10 == 0:
|
|
179
|
+
print(" step {:3d} SD={:.6e}".format(in_step, sd))
|
|
180
|
+
|
|
181
|
+
imfs.append(h)
|
|
182
|
+
f = f - h
|
|
183
|
+
extrema = maxmins(f, extension_type="p")
|
|
184
|
+
|
|
185
|
+
imfs.append(f)
|
|
186
|
+
self.imfs = np.vstack(imfs)
|
|
187
|
+
self.mask_lengths = np.vstack(masks) if masks else np.zeros((0, n))
|
|
188
|
+
|
|
189
|
+
if return_masks:
|
|
190
|
+
return self.imfs, self.mask_lengths
|
|
191
|
+
return self.imfs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Package data for the prefixed double filter used by ALIF / IF.
|
|
Binary file
|