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.
Files changed (148) hide show
  1. {pysdkit-0.4.26 → pysdkit-0.4.27}/PKG-INFO +3 -3
  2. {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/PKG-INFO +3 -3
  3. {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/SOURCES.txt +7 -0
  4. {pysdkit-0.4.26 → pysdkit-0.4.27}/README.md +2 -2
  5. {pysdkit-0.4.26 → pysdkit-0.4.27}/pyproject.toml +3 -1
  6. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/__init__.py +7 -1
  7. pysdkit-0.4.27/pysdkit/_alif/__init__.py +6 -0
  8. pysdkit-0.4.27/pysdkit/_alif/_helpers.py +248 -0
  9. pysdkit-0.4.27/pysdkit/_alif/alif.py +191 -0
  10. pysdkit-0.4.27/pysdkit/_alif/data/__init__.py +1 -0
  11. pysdkit-0.4.27/pysdkit/_alif/data/prefixed_double_filter.npy +0 -0
  12. pysdkit-0.4.27/pysdkit/_alif/iterative_filtering.py +175 -0
  13. pysdkit-0.4.27/pysdkit/tests/test_alif.py +102 -0
  14. {pysdkit-0.4.26 → pysdkit-0.4.27}/LICENSE +0 -0
  15. {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/dependency_links.txt +0 -0
  16. {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/requires.txt +0 -0
  17. {pysdkit-0.4.26 → pysdkit-0.4.27}/PySDKit.egg-info/top_level.txt +0 -0
  18. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/__init__.py +0 -0
  19. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/_find_extrema.py +0 -0
  20. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/_prepare_points.py +0 -0
  21. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/_splines.py +0 -0
  22. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/ceemdan.py +0 -0
  23. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/eemd.py +0 -0
  24. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/efd.py +0 -0
  25. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/emd.py +0 -0
  26. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/hht/__init__.py +0 -0
  27. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/hht/frequency.py +0 -0
  28. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/hht/hht.py +0 -0
  29. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/memd.py +0 -0
  30. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/remd.py +0 -0
  31. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd/tvf_emd.py +0 -0
  32. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/__init__.py +0 -0
  33. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/bemd.py +0 -0
  34. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/bmemd.py +0 -0
  35. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_emd2d/emd2d.py +0 -0
  36. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_esmd/__init__.py +0 -0
  37. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_esmd/esmd.py +0 -0
  38. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ewt/__init__.py +0 -0
  39. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ewt/ewt.py +0 -0
  40. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ewt/ewt2d.py +0 -0
  41. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/__init__.py +0 -0
  42. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/extrema.py +0 -0
  43. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/faemd.py +0 -0
  44. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/faemd2d.py +0 -0
  45. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/faemd3d.py +0 -0
  46. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_faemd/filter.py +0 -0
  47. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_fmd/__init__.py +0 -0
  48. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_fmd/fmd.py +0 -0
  49. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_fmd/nfmd.py +0 -0
  50. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_hvd/__init__.py +0 -0
  51. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_hvd/hvd.py +0 -0
  52. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ifd/__init__.py +0 -0
  53. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_itd/__init__.py +0 -0
  54. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_itd/itd.py +0 -0
  55. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_jmd/__init__.py +0 -0
  56. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_jmd/jmd.py +0 -0
  57. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_jmd/mjmd.py +0 -0
  58. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_lmd/__init__.py +0 -0
  59. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_lmd/lmd.py +0 -0
  60. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_lmd/rlmd.py +0 -0
  61. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_osd/__init__.py +0 -0
  62. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ssa/__init__.py +0 -0
  63. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_ssa/ssa.py +0 -0
  64. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/__init__.py +0 -0
  65. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/acmd.py +0 -0
  66. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/avmd.py +0 -0
  67. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/ba_acmd.py +0 -0
  68. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/base.py +0 -0
  69. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/mvmd.py +0 -0
  70. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/svmd.py +0 -0
  71. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/vmd_c.py +0 -0
  72. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/vmd_f.py +0 -0
  73. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd/vme.py +0 -0
  74. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd2d/__init__.py +0 -0
  75. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd2d/cvmd2d.py +0 -0
  76. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vmd2d/vmd2d.py +0 -0
  77. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/__init__.py +0 -0
  78. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/avncmd.py +0 -0
  79. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/incmd.py +0 -0
  80. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/mncmd.py +0 -0
  81. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/_vncmd/vncmd.py +0 -0
  82. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/__init__.py +0 -0
  83. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_add_noise.py +0 -0
  84. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_cube.py +0 -0
  85. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_generator.py +0 -0
  86. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_image.py +0 -0
  87. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_models.py +0 -0
  88. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_test_univariate.py +0 -0
  89. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/_time_series.py +0 -0
  90. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/data/texture.txt +0 -0
  91. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/__init__.py +0 -0
  92. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/_approxiamte_entropy.py +0 -0
  93. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/_permutation_entropy.py +0 -0
  94. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/entropy/_sample_entropy.py +0 -0
  95. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/__init__.py +0 -0
  96. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_base.py +0 -0
  97. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_kmeans.py +0 -0
  98. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_knn.py +0 -0
  99. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/models/_pca.py +0 -0
  100. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/__init__.py +0 -0
  101. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_fourier_spectra.py +0 -0
  102. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_functions.py +0 -0
  103. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_plot_images.py +0 -0
  104. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_plot_imfs.py +0 -0
  105. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/plot/_plot_signal.py +0 -0
  106. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/__init__.py +0 -0
  107. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/__init__.py +0 -0
  108. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_cube.py +0 -0
  109. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_image.py +0 -0
  110. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_signal.py +0 -0
  111. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/data/test_generator_univariate_signal.py +0 -0
  112. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/models/__init__.py +0 -0
  113. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/models/test_knn.py +0 -0
  114. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/models/test_pca.py +0 -0
  115. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/run_all.py +0 -0
  116. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_avncmd.py +0 -0
  117. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_ceemdan.py +0 -0
  118. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_emd.py +0 -0
  119. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_ewt.py +0 -0
  120. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_faemd.py +0 -0
  121. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_faemd2d.py +0 -0
  122. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_faemd3d.py +0 -0
  123. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_itd.py +0 -0
  124. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_lmd.py +0 -0
  125. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_moving_decomp.py +0 -0
  126. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_rlmd.py +0 -0
  127. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_stl.py +0 -0
  128. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_vmd.py +0 -0
  129. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tests/test_vmd2d.py +0 -0
  130. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/__init__.py +0 -0
  131. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_dtw.py +0 -0
  132. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_moving_decomp.py +0 -0
  133. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_mstl.py +0 -0
  134. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/tsa/_stl.py +0 -0
  135. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/__init__.py +0 -0
  136. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_cite.py +0 -0
  137. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_correlation.py +0 -0
  138. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_diagnalization.py +0 -0
  139. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_differ.py +0 -0
  140. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_fft.py +0 -0
  141. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_function.py +0 -0
  142. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_hilbert.py +0 -0
  143. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_instantaneous.py +0 -0
  144. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_kernel_matrix.py +0 -0
  145. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_mirror.py +0 -0
  146. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_process.py +0 -0
  147. {pysdkit-0.4.26 → pysdkit-0.4.27}/pysdkit/utils/_smooth1d.py +0 -0
  148. {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.26
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.26
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) | ️✔️ |
@@ -63,4 +63,6 @@ where = ["."]
63
63
  include = ["pysdkit*"]
64
64
 
65
65
  [tool.setuptools.package-data]
66
- "*" = ["*.txt"]
66
+ "*" = ["*.txt", "*.npy"]
67
+ "pysdkit._alif" = ["data/*.npy"]
68
+ "pysdkit._alif.data" = ["*.npy"]
@@ -2,7 +2,7 @@
2
2
  A Python library for signal decomposition algorithms.
3
3
  """
4
4
 
5
- __version__ = "0.4.26"
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,6 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Adaptive Local Iterative Filtering (ALIF) package."""
3
+ from .alif import ALIF
4
+ from .iterative_filtering import IterativeFiltering
5
+
6
+ __all__ = ["ALIF", "IterativeFiltering"]
@@ -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.