PySDKit 0.4.28__tar.gz → 0.4.30__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 (157) hide show
  1. {pysdkit-0.4.28 → pysdkit-0.4.30}/PKG-INFO +3 -2
  2. {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/PKG-INFO +3 -2
  3. {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/SOURCES.txt +3 -1
  4. {pysdkit-0.4.28 → pysdkit-0.4.30}/README.md +2 -1
  5. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/__init__.py +12 -1
  6. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_hvd/hvd.py +1 -1
  7. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_jmd/__init__.py +4 -0
  8. pysdkit-0.4.30/pysdkit/_jmd/jmd.py +288 -0
  9. pysdkit-0.4.30/pysdkit/_jmd/mjmd.py +302 -0
  10. pysdkit-0.4.30/pysdkit/_jmd/sjmd.py +464 -0
  11. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_lmd/rlmd.py +2 -2
  12. pysdkit-0.4.30/pysdkit/tests/test_jmd.py +108 -0
  13. pysdkit-0.4.30/pysdkit/tests/test_sjmd.py +160 -0
  14. pysdkit-0.4.28/pysdkit/_ifd/__init__.py +0 -7
  15. pysdkit-0.4.28/pysdkit/_jmd/jmd.py +0 -395
  16. pysdkit-0.4.28/pysdkit/_jmd/mjmd.py +0 -34
  17. {pysdkit-0.4.28 → pysdkit-0.4.30}/LICENSE +0 -0
  18. {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/dependency_links.txt +0 -0
  19. {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/requires.txt +0 -0
  20. {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/top_level.txt +0 -0
  21. {pysdkit-0.4.28 → pysdkit-0.4.30}/pyproject.toml +0 -0
  22. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/__init__.py +0 -0
  23. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/alif.py +0 -0
  24. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/data/__init__.py +0 -0
  25. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/data/prefixed_double_filter.npy +0 -0
  26. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/iterative_filtering.py +0 -0
  27. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_apmd/__init__.py +0 -0
  28. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_apmd/apmd.py +0 -0
  29. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/__init__.py +0 -0
  30. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/_find_extrema.py +0 -0
  31. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/_prepare_points.py +0 -0
  32. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/_splines.py +0 -0
  33. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/ceemdan.py +0 -0
  34. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/eemd.py +0 -0
  35. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/efd.py +0 -0
  36. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/emd.py +0 -0
  37. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/hht/__init__.py +0 -0
  38. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/hht/frequency.py +0 -0
  39. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/hht/hht.py +0 -0
  40. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/memd.py +0 -0
  41. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/remd.py +0 -0
  42. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/tvf_emd.py +0 -0
  43. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/__init__.py +0 -0
  44. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/bemd.py +0 -0
  45. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/bmemd.py +0 -0
  46. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/emd2d.py +0 -0
  47. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_esmd/__init__.py +0 -0
  48. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_esmd/esmd.py +0 -0
  49. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ewt/__init__.py +0 -0
  50. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ewt/ewt.py +0 -0
  51. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ewt/ewt2d.py +0 -0
  52. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/__init__.py +0 -0
  53. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/extrema.py +0 -0
  54. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/faemd.py +0 -0
  55. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/faemd2d.py +0 -0
  56. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/faemd3d.py +0 -0
  57. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/filter.py +0 -0
  58. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_fmd/__init__.py +0 -0
  59. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_fmd/fmd.py +0 -0
  60. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_fmd/nfmd.py +0 -0
  61. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_hvd/__init__.py +0 -0
  62. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_itd/__init__.py +0 -0
  63. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_itd/itd.py +0 -0
  64. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_lmd/__init__.py +0 -0
  65. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_lmd/lmd.py +0 -0
  66. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_osd/__init__.py +0 -0
  67. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ssa/__init__.py +0 -0
  68. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ssa/ssa.py +0 -0
  69. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/__init__.py +0 -0
  70. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/acmd.py +0 -0
  71. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/avmd.py +0 -0
  72. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/ba_acmd.py +0 -0
  73. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/base.py +0 -0
  74. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/mvmd.py +0 -0
  75. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/ovmd.py +0 -0
  76. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/svmd.py +0 -0
  77. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/vmd_c.py +0 -0
  78. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/vmd_f.py +0 -0
  79. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/vme.py +0 -0
  80. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd2d/__init__.py +0 -0
  81. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd2d/cvmd2d.py +0 -0
  82. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd2d/vmd2d.py +0 -0
  83. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/__init__.py +0 -0
  84. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/avncmd.py +0 -0
  85. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/incmd.py +0 -0
  86. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/mncmd.py +0 -0
  87. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/vncmd.py +0 -0
  88. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/__init__.py +0 -0
  89. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_add_noise.py +0 -0
  90. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_cube.py +0 -0
  91. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_generator.py +0 -0
  92. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_image.py +0 -0
  93. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_models.py +0 -0
  94. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_test_univariate.py +0 -0
  95. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_time_series.py +0 -0
  96. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/texture.txt +0 -0
  97. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/__init__.py +0 -0
  98. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/_approxiamte_entropy.py +0 -0
  99. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/_permutation_entropy.py +0 -0
  100. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/_sample_entropy.py +0 -0
  101. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/__init__.py +0 -0
  102. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_base.py +0 -0
  103. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_kmeans.py +0 -0
  104. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_knn.py +0 -0
  105. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_pca.py +0 -0
  106. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/__init__.py +0 -0
  107. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_fourier_spectra.py +0 -0
  108. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_functions.py +0 -0
  109. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_plot_images.py +0 -0
  110. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_plot_imfs.py +0 -0
  111. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_plot_signal.py +0 -0
  112. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/__init__.py +0 -0
  113. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/__init__.py +0 -0
  114. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_cube.py +0 -0
  115. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_image.py +0 -0
  116. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_signal.py +0 -0
  117. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_univariate_signal.py +0 -0
  118. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/models/__init__.py +0 -0
  119. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/models/test_knn.py +0 -0
  120. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/models/test_pca.py +0 -0
  121. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/run_all.py +0 -0
  122. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_alif.py +0 -0
  123. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_apmd.py +0 -0
  124. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_avncmd.py +0 -0
  125. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_ceemdan.py +0 -0
  126. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_emd.py +0 -0
  127. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_ewt.py +0 -0
  128. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_faemd.py +0 -0
  129. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_faemd2d.py +0 -0
  130. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_faemd3d.py +0 -0
  131. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_itd.py +0 -0
  132. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_lmd.py +0 -0
  133. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_moving_decomp.py +0 -0
  134. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_ovmd.py +0 -0
  135. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_rlmd.py +0 -0
  136. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_stl.py +0 -0
  137. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_vmd.py +0 -0
  138. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_vmd2d.py +0 -0
  139. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/__init__.py +0 -0
  140. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_dtw.py +0 -0
  141. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_moving_decomp.py +0 -0
  142. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_mstl.py +0 -0
  143. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_stl.py +0 -0
  144. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/__init__.py +0 -0
  145. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_cite.py +0 -0
  146. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_correlation.py +0 -0
  147. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_diagnalization.py +0 -0
  148. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_differ.py +0 -0
  149. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_fft.py +0 -0
  150. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_function.py +0 -0
  151. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_hilbert.py +0 -0
  152. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_instantaneous.py +0 -0
  153. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_kernel_matrix.py +0 -0
  154. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_mirror.py +0 -0
  155. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_process.py +0 -0
  156. {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_smooth1d.py +0 -0
  157. {pysdkit-0.4.28 → pysdkit-0.4.30}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySDKit
3
- Version: 0.4.28
3
+ Version: 0.4.30
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>
@@ -182,7 +182,8 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
182
182
  | [`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) | ✔️ |
183
183
  | [`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) | ✖️ |
184
184
  | [`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) | ️✔️ |
185
- | [`MJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/mjmd.py) (Multivariate Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169393-multivariate-jump-plus-am-fm-mode-decomposition-mjmd?s_tid=prof_contriblnk) | ✖️ |
185
+ | [`MJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/mjmd.py) (Multivariate Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169393-multivariate-jump-plus-am-fm-mode-decomposition-mjmd?s_tid=prof_contriblnk) | ✔️ |
186
+ | [`SJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/sjmd.py) / `SMJMD` (Successive Jump and Mode Decomposition) | [[paper]](https://arxiv.org/abs/2504.08453) | [[code]]() | ✔️ |
186
187
  | [`ESMD`]() (Extreme-Point Symmetric Mode Decomposition) | [[paper]](https://arxiv.org/abs/1303.6540) | [[code]](https://github.com/WuShichao/esmd) | ✖️ |
187
188
  | [`STNBMD`]() (Short-Time Narrow-Band Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X16002443?via%3Dihub) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56226-short-time-narrow-band-mode-decomposition-stnbmd-toolbox) | ✖️ |
188
189
  | [`STL`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/tsa/_stl.py) (Seasonal-Trend decomposition using LOESS) | [[paper]](https://www.nniiem.ru/file/news/2016/stl-statistical-model.pdf) | [[code]](https://www.statsmodels.org/stable/examples/notebooks/generated/stl_decomposition.html) | ✔️ |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySDKit
3
- Version: 0.4.28
3
+ Version: 0.4.30
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>
@@ -182,7 +182,8 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
182
182
  | [`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) | ✔️ |
183
183
  | [`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) | ✖️ |
184
184
  | [`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) | ️✔️ |
185
- | [`MJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/mjmd.py) (Multivariate Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169393-multivariate-jump-plus-am-fm-mode-decomposition-mjmd?s_tid=prof_contriblnk) | ✖️ |
185
+ | [`MJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/mjmd.py) (Multivariate Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169393-multivariate-jump-plus-am-fm-mode-decomposition-mjmd?s_tid=prof_contriblnk) | ✔️ |
186
+ | [`SJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/sjmd.py) / `SMJMD` (Successive Jump and Mode Decomposition) | [[paper]](https://arxiv.org/abs/2504.08453) | [[code]]() | ✔️ |
186
187
  | [`ESMD`]() (Extreme-Point Symmetric Mode Decomposition) | [[paper]](https://arxiv.org/abs/1303.6540) | [[code]](https://github.com/WuShichao/esmd) | ✖️ |
187
188
  | [`STNBMD`]() (Short-Time Narrow-Band Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X16002443?via%3Dihub) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56226-short-time-narrow-band-mode-decomposition-stnbmd-toolbox) | ✖️ |
188
189
  | [`STL`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/tsa/_stl.py) (Seasonal-Trend decomposition using LOESS) | [[paper]](https://www.nniiem.ru/file/news/2016/stl-statistical-model.pdf) | [[code]](https://www.statsmodels.org/stable/examples/notebooks/generated/stl_decomposition.html) | ✔️ |
@@ -48,12 +48,12 @@ pysdkit/_fmd/fmd.py
48
48
  pysdkit/_fmd/nfmd.py
49
49
  pysdkit/_hvd/__init__.py
50
50
  pysdkit/_hvd/hvd.py
51
- pysdkit/_ifd/__init__.py
52
51
  pysdkit/_itd/__init__.py
53
52
  pysdkit/_itd/itd.py
54
53
  pysdkit/_jmd/__init__.py
55
54
  pysdkit/_jmd/jmd.py
56
55
  pysdkit/_jmd/mjmd.py
56
+ pysdkit/_jmd/sjmd.py
57
57
  pysdkit/_lmd/__init__.py
58
58
  pysdkit/_lmd/lmd.py
59
59
  pysdkit/_lmd/rlmd.py
@@ -115,10 +115,12 @@ pysdkit/tests/test_faemd.py
115
115
  pysdkit/tests/test_faemd2d.py
116
116
  pysdkit/tests/test_faemd3d.py
117
117
  pysdkit/tests/test_itd.py
118
+ pysdkit/tests/test_jmd.py
118
119
  pysdkit/tests/test_lmd.py
119
120
  pysdkit/tests/test_moving_decomp.py
120
121
  pysdkit/tests/test_ovmd.py
121
122
  pysdkit/tests/test_rlmd.py
123
+ pysdkit/tests/test_sjmd.py
122
124
  pysdkit/tests/test_stl.py
123
125
  pysdkit/tests/test_vmd.py
124
126
  pysdkit/tests/test_vmd2d.py
@@ -128,7 +128,8 @@ plot_IMFs_amplitude_spectra(IMFs, smooth="exp") # use exp smooth
128
128
  | [`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) | ✔️ |
129
129
  | [`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) | ✖️ |
130
130
  | [`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) | ️✔️ |
131
- | [`MJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/mjmd.py) (Multivariate Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169393-multivariate-jump-plus-am-fm-mode-decomposition-mjmd?s_tid=prof_contriblnk) | ✖️ |
131
+ | [`MJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/mjmd.py) (Multivariate Jump Plus AM-FM Mode Decomposition) | [[paper]](https://arxiv.org/abs/2407.07800) | [[code]](https://www.mathworks.com/matlabcentral/fileexchange/169393-multivariate-jump-plus-am-fm-mode-decomposition-mjmd?s_tid=prof_contriblnk) | ✔️ |
132
+ | [`SJMD`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/_jmd/sjmd.py) / `SMJMD` (Successive Jump and Mode Decomposition) | [[paper]](https://arxiv.org/abs/2504.08453) | [[code]]() | ✔️ |
132
133
  | [`ESMD`]() (Extreme-Point Symmetric Mode Decomposition) | [[paper]](https://arxiv.org/abs/1303.6540) | [[code]](https://github.com/WuShichao/esmd) | ✖️ |
133
134
  | [`STNBMD`]() (Short-Time Narrow-Band Mode Decomposition) | [[paper]](https://www.sciencedirect.com/science/article/pii/S0022460X16002443?via%3Dihub) | [[code]](https://ww2.mathworks.cn/matlabcentral/fileexchange/56226-short-time-narrow-band-mode-decomposition-stnbmd-toolbox) | ✖️ |
134
135
  | [`STL`](https://github.com/wwhenxuan/PySDKit/blob/main/pysdkit/tsa/_stl.py) (Seasonal-Trend decomposition using LOESS) | [[paper]](https://www.nniiem.ru/file/news/2016/stl-statistical-model.pdf) | [[code]](https://www.statsmodels.org/stable/examples/notebooks/generated/stl_decomposition.html) | ✔️ |
@@ -2,7 +2,7 @@
2
2
  A Python library for signal decomposition algorithms.
3
3
  """
4
4
 
5
- __version__ = "0.4.28"
5
+ __version__ = "0.4.30"
6
6
 
7
7
  # Empirical Mode Decomposition
8
8
  from ._emd import EMD
@@ -88,6 +88,12 @@ from ._ewt import ewt, EWT
88
88
  # Jump Plus AM-FM Mode Decomposition
89
89
  from ._jmd import JMD
90
90
 
91
+ # Multivariate Jump Plus AM-FM Mode Decomposition
92
+ from ._jmd import MJMD
93
+
94
+ # Successive Jump and Mode Decomposition (univariate / multivariate)
95
+ from ._jmd import SJMD, SMJMD
96
+
91
97
  # Feature Mode Decomposition
92
98
  from ._fmd import FMD
93
99
 
@@ -151,6 +157,8 @@ Adaptive Local Iterative Filtering | ALIF
151
157
  Adaptive Polymorphic Mode Decomposition | APMD
152
158
  Empirical Wavelet Transform | EWT
153
159
  Jump Plus AM-FM Mode Decomposition | JMD
160
+ Multivariate Jump Plus AM-FM Mode Decomposition | MJMD
161
+ Successive Jump and Mode Decomposition | SJMD / SMJMD
154
162
  Feature Mode Decomposition | FMD
155
163
  Moving Average Decomposition | Moving
156
164
  Seasonal-Trend decomposition using LOESS | STL
@@ -191,6 +199,9 @@ __all__ = [
191
199
  "ewt",
192
200
  "EWT",
193
201
  "JMD",
202
+ "MJMD",
203
+ "SJMD",
204
+ "SMJMD",
194
205
  "FMD",
195
206
  "Moving_Decomp",
196
207
  "STL",
@@ -173,7 +173,7 @@ class HVD(object):
173
173
  return imfs
174
174
 
175
175
 
176
- def make_window_real_valued(H, N):
176
+ def make_window_real_valued(H: np.ndarray, N: int) -> np.ndarray:
177
177
  """
178
178
  Make window real valued
179
179
 
@@ -5,3 +5,7 @@ Created on 2025/02/05 13:32:00
5
5
  @email: wwhenxuan@gmail.com
6
6
  """
7
7
  from .jmd import JMD
8
+ from .mjmd import MJMD
9
+ from .sjmd import SJMD, SMJMD
10
+
11
+ __all__ = ["JMD", "MJMD", "SJMD", "SMJMD"]
@@ -0,0 +1,288 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on 2025/02/05 13:31:52
4
+ @author: Whenxuan Wang
5
+ @email: wwhenxuan@gmail.com
6
+
7
+ Jump Plus AM-FM Mode Decomposition (JMD).
8
+
9
+ Faithful port of the authors' MATLAB ``JMD.m``.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ from typing import Optional, Tuple, Union
14
+
15
+ import numpy as np
16
+ from numpy import linalg
17
+ import scipy.sparse as sp
18
+
19
+ from pysdkit.utils import fft, fftshift, ifft, ifftshift
20
+
21
+
22
+ class JMD(object):
23
+ """
24
+ Jump Plus AM-FM Mode Decomposition.
25
+
26
+ Decomposes a nonstationary signal into AM–FM oscillatory modes and a
27
+ discontinuous jump component by jointly solving a VMD-like bandwidth
28
+ minimization and a jump prior (JOT-style ADMM).
29
+
30
+ Mojtaba Nazari, Anders Rosendal Korshøj and Naveed ur Rehman,
31
+ "Jump Plus AM-FM Mode Decomposition," IEEE TSP,
32
+ https://doi.org/10.48550/arXiv.2407.07800
33
+ """
34
+
35
+ def __init__(
36
+ self,
37
+ K: int,
38
+ alpha: float = 5000.0,
39
+ init: str = "zero",
40
+ tol: float = 1e-6,
41
+ beta: float = 0.03,
42
+ b_bar: float = 0.45,
43
+ tau: float = 5.0,
44
+ max_iter: int = 2000,
45
+ ) -> None:
46
+ """
47
+ :param K: number of AM–FM modes to recover
48
+ :param alpha: balancing parameter of the mode bandwidth
49
+ :param init: ``'zero'`` / ``'uniform'`` / ``'random'`` omega initialization
50
+ :param tol: convergence tolerance
51
+ :param beta: jump-constraint weight (≈ 1 / expected number of jumps)
52
+ :param b_bar: parameter related to the jump prior
53
+ :param tau: jump ADMM step (used to form ``gamma``; set carefully for noise)
54
+ :param max_iter: maximum number of iterations
55
+ """
56
+ self.K = int(K)
57
+ self.alpha = float(alpha)
58
+ self.init = str(init).lower()
59
+ self.tol = float(tol)
60
+ self.beta = float(beta)
61
+ self.b_bar = float(b_bar)
62
+ self.tau = float(tau)
63
+ self.max_iter = int(max_iter)
64
+
65
+ self.u: Optional[np.ndarray] = None
66
+ self.v: Optional[np.ndarray] = None
67
+ self.omega: Optional[np.ndarray] = None
68
+
69
+ def __call__(
70
+ self, signal: np.ndarray, return_all: bool = False
71
+ ) -> Union[Tuple[np.ndarray, np.ndarray, np.ndarray], np.ndarray]:
72
+ return self.fit_transform(signal=signal, return_all=return_all)
73
+
74
+ def __str__(self) -> str:
75
+ return "Jump Plus AM-FM Mode Decomposition (JMD)"
76
+
77
+ def jump_step(self, freqs: np.ndarray, T: int) -> Tuple[
78
+ float,
79
+ np.ndarray,
80
+ np.ndarray,
81
+ np.ndarray,
82
+ np.ndarray,
83
+ np.ndarray,
84
+ np.ndarray,
85
+ np.ndarray,
86
+ float,
87
+ float,
88
+ float,
89
+ ]:
90
+ """Initialize jump-ADMM variables (matches MATLAB jump block)."""
91
+ b = 2.0 / (self.b_bar**2)
92
+ gamma = self.tau * (0.5 * b * self.beta)
93
+ v = np.zeros(T, dtype=float)
94
+ d = np.ones(T)
95
+ D = sp.diags([-d, d], [0, 1], shape=(T, T), format="csr").tolil()
96
+ D[-1, :] = 0
97
+ D = D.tocsr()
98
+ DTD = (D.T @ D).toarray()
99
+ x = np.zeros(T, dtype=float)
100
+ rho = np.zeros(T, dtype=float)
101
+ coef1 = 1.0 / gamma
102
+ mu = 2.0 * self.beta / gamma
103
+ SPDiag = sp.eye(T, format="csr")
104
+ j_hat_plus = np.zeros((self.max_iter, len(freqs)), dtype=complex)
105
+ return (
106
+ b,
107
+ v,
108
+ x,
109
+ D.toarray(),
110
+ DTD,
111
+ SPDiag.toarray(),
112
+ j_hat_plus,
113
+ rho,
114
+ coef1,
115
+ mu,
116
+ gamma,
117
+ )
118
+
119
+ @staticmethod
120
+ def enc_fmirror(signal: np.ndarray) -> np.ndarray:
121
+ """Mirror extension matching ``JMD.m`` / VMD style."""
122
+ signal = np.asarray(signal, dtype=float).ravel()
123
+ t = signal.size
124
+ half = t // 2
125
+ return np.concatenate([signal[half - 1 :: -1], signal, signal[: half - 1 : -1]])
126
+
127
+ @staticmethod
128
+ def dec_fmirror(u: np.ndarray, T: int) -> np.ndarray:
129
+ """Remove mirrored flanks."""
130
+ return u[:, T // 4 : 3 * T // 4].copy()
131
+
132
+ @staticmethod
133
+ def _soft_jump(h: np.ndarray, mu: float, b: float) -> np.ndarray:
134
+ """Element-wise jump proximal map from MATLAB ``min(max(...),1).*h``."""
135
+ abs_h = np.abs(h) + np.finfo(float).eps
136
+ scale = (1.0 / (1.0 - mu * b)) - (
137
+ mu * np.sqrt(2.0 * b) / (1.0 - mu * b)
138
+ ) / abs_h
139
+ scale = np.clip(scale, 0.0, 1.0)
140
+ return scale * h
141
+
142
+ def _init_omega(self, fs: float) -> np.ndarray:
143
+ """Initialization of omega_k (MATLAB ``init`` cases 0/1/2)."""
144
+ omega_plus = np.zeros((self.max_iter, self.K), dtype=float)
145
+ if self.init == "zero":
146
+ return omega_plus
147
+ if self.init == "uniform":
148
+ for i in range(self.K):
149
+ omega_plus[0, i] = (0.5 / self.K) * i
150
+ return omega_plus
151
+ if self.init == "random":
152
+ omega_plus[0, :] = np.sort(
153
+ np.exp(np.log(fs) + (np.log(0.5) - np.log(fs)) * np.random.rand(self.K))
154
+ )
155
+ return omega_plus
156
+ raise ValueError("init must be 'zero', 'uniform', or 'random'")
157
+
158
+ def fit_transform(
159
+ self, signal: np.ndarray, return_all: bool = False
160
+ ) -> Union[Tuple[np.ndarray, np.ndarray, np.ndarray], np.ndarray]:
161
+ """
162
+ Run JMD on a univariate signal.
163
+
164
+ :param signal: 1-D time-domain signal
165
+ :param return_all: if True, return ``(modes, jump, omega)``
166
+ :return: modes ``(K, N)`` or ``(modes, jump, omega)``
167
+ """
168
+ signal = np.asarray(signal, dtype=float).ravel()
169
+ if signal.size % 2 == 1:
170
+ signal = signal[:-1]
171
+ if signal.size < 4:
172
+ raise ValueError("signal length must be at least 4 samples")
173
+ if self.K < 1:
174
+ raise ValueError("K must be >= 1")
175
+
176
+ # MATLAB: demean, restore mean on the jump at the end
177
+ shift = float(np.mean(signal))
178
+ signal = signal - shift
179
+
180
+ f = self.enc_fmirror(signal)
181
+ T = f.size
182
+ half_T = T // 2
183
+ t = np.arange(1, T + 1, dtype=float) / T
184
+ freqs = t - 0.5 - 1.0 / T
185
+ fs = 1.0 / signal.size
186
+
187
+ a2 = 50.0
188
+ t2 = np.arange(0.01, np.sqrt(2.0 / a2) + 1e-12, 0.001)
189
+ phi1 = (-a2 / 2.0) * (t2**2) + (np.sqrt(2.0 * a2) * t2)
190
+ if self.max_iter > phi1.size:
191
+ phi = np.concatenate([phi1, np.ones(self.max_iter - phi1.size)])
192
+ else:
193
+ phi = phi1[: self.max_iter].copy()
194
+ Alpha = self.alpha * phi
195
+
196
+ f_hat = fftshift(fft(f))
197
+ f_hat_plus = f_hat.copy()
198
+ f_hat_plus[:half_T] = 0.0
199
+
200
+ u_hat_plus = np.zeros((self.max_iter, freqs.size, self.K), dtype=complex)
201
+ omega_plus = self._init_omega(fs=fs)
202
+
203
+ u_diff = self.tol + np.spacing(1)
204
+ n = 0
205
+ sum_uk = 0.0
206
+
207
+ b, v, x, D, DTD, SPDiag, j_hat_plus, rho, coef1, mu, gamma = self.jump_step(
208
+ freqs=freqs, T=T
209
+ )
210
+ A_jump = SPDiag + gamma * DTD
211
+
212
+ while u_diff > self.tol and n < self.max_iter - 1:
213
+ sum_uk = u_hat_plus[n, :, self.K - 1] + sum_uk - u_hat_plus[n, :, 0]
214
+
215
+ for k in range(self.K):
216
+ if k > 0:
217
+ sum_uk = u_hat_plus[n + 1, :, k - 1] + sum_uk - u_hat_plus[n, :, k]
218
+ u_hat_plus[n + 1, :, k] = (f_hat_plus - sum_uk - j_hat_plus[n, :]) / (
219
+ 1.0 + Alpha[n] * (freqs - omega_plus[n, k]) ** 2
220
+ )
221
+
222
+ num = np.dot(
223
+ freqs[half_T:T], np.abs(u_hat_plus[n + 1, half_T:T, k]) ** 2
224
+ )
225
+ den = np.sum(np.abs(u_hat_plus[n + 1, half_T:T, k]) ** 2)
226
+ omega_plus[n + 1, k] = num / (den + np.finfo(float).eps)
227
+
228
+ # Back to time domain for jump update
229
+ u_hat = np.zeros((T, self.K), dtype=complex)
230
+ for k in range(self.K):
231
+ u_hat[half_T:T, k] = u_hat_plus[n + 1, half_T:T, k]
232
+ u_hat[half_T:0:-1, k] = np.conj(u_hat_plus[n + 1, half_T:T, k])
233
+ u_hat[0, k] = np.conj(u_hat[-1, k])
234
+
235
+ u = np.zeros((self.K, T), dtype=float)
236
+ for k in range(self.K):
237
+ u[k, :] = np.real(ifft(ifftshift(u_hat[:, k])))
238
+
239
+ rhs = gamma * (D.T @ x) - (D.T @ rho) + f - np.sum(u, axis=0)
240
+ v = linalg.solve(A_jump, rhs)
241
+
242
+ dv = D @ v
243
+ h = dv + coef1 * rho
244
+ x = self._soft_jump(h, mu=mu, b=b)
245
+ rho = rho - gamma * (x - dv)
246
+
247
+ v = v - (np.mean(v) - np.mean(f))
248
+
249
+ j_hat_plus[n + 1, :] = fftshift(fft(v))
250
+ j_hat_plus[n + 1, :half_T] = 0.0
251
+
252
+ n += 1
253
+ u_diff = np.spacing(1)
254
+ for i in range(self.K):
255
+ diff = u_hat_plus[n, :, i] - u_hat_plus[n - 1, :, i]
256
+ u_diff += (1.0 / T) * np.vdot(diff, diff).real
257
+ jdiff = j_hat_plus[n, :] - j_hat_plus[n - 1, :]
258
+ u_diff += (1.0 / T) * np.vdot(jdiff, jdiff).real
259
+ u_diff = abs(u_diff)
260
+
261
+ n_keep = min(n, self.max_iter - 1)
262
+ omega_hist = omega_plus[: n_keep + 1, :]
263
+
264
+ u_hat = np.zeros((T, self.K), dtype=complex)
265
+ for k in range(self.K):
266
+ u_hat[half_T:T, k] = u_hat_plus[n_keep, half_T:T, k]
267
+ u_hat[half_T:0:-1, k] = np.conj(u_hat_plus[n_keep, half_T:T, k])
268
+ u_hat[0, k] = np.conj(u_hat[-1, k])
269
+
270
+ u = np.zeros((self.K, T), dtype=float)
271
+ for k in range(self.K):
272
+ u[k, :] = np.real(ifft(ifftshift(u_hat[:, k])))
273
+
274
+ u = self.dec_fmirror(u, T=T)
275
+ v = v[T // 4 : 3 * T // 4] + shift
276
+
277
+ # Sort modes by ascending center frequency (MATLAB cleanup)
278
+ order = np.argsort(omega_hist[-1, :])
279
+ u = u[order, :]
280
+ omega = omega_hist[:, order]
281
+
282
+ self.u = u
283
+ self.v = v
284
+ self.omega = omega
285
+
286
+ if return_all:
287
+ return u, v, omega[-1]
288
+ return u