PySDKit 0.4.28__tar.gz → 0.4.29__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 (155) hide show
  1. {pysdkit-0.4.28 → pysdkit-0.4.29}/PKG-INFO +2 -2
  2. {pysdkit-0.4.28 → pysdkit-0.4.29}/PySDKit.egg-info/PKG-INFO +2 -2
  3. {pysdkit-0.4.28 → pysdkit-0.4.29}/PySDKit.egg-info/SOURCES.txt +1 -1
  4. {pysdkit-0.4.28 → pysdkit-0.4.29}/README.md +1 -1
  5. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/__init__.py +6 -1
  6. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_hvd/hvd.py +1 -1
  7. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_jmd/__init__.py +3 -0
  8. pysdkit-0.4.29/pysdkit/_jmd/jmd.py +288 -0
  9. pysdkit-0.4.29/pysdkit/_jmd/mjmd.py +302 -0
  10. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_lmd/rlmd.py +2 -2
  11. pysdkit-0.4.29/pysdkit/tests/test_jmd.py +108 -0
  12. pysdkit-0.4.28/pysdkit/_ifd/__init__.py +0 -7
  13. pysdkit-0.4.28/pysdkit/_jmd/jmd.py +0 -395
  14. pysdkit-0.4.28/pysdkit/_jmd/mjmd.py +0 -34
  15. {pysdkit-0.4.28 → pysdkit-0.4.29}/LICENSE +0 -0
  16. {pysdkit-0.4.28 → pysdkit-0.4.29}/PySDKit.egg-info/dependency_links.txt +0 -0
  17. {pysdkit-0.4.28 → pysdkit-0.4.29}/PySDKit.egg-info/requires.txt +0 -0
  18. {pysdkit-0.4.28 → pysdkit-0.4.29}/PySDKit.egg-info/top_level.txt +0 -0
  19. {pysdkit-0.4.28 → pysdkit-0.4.29}/pyproject.toml +0 -0
  20. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_alif/__init__.py +0 -0
  21. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_alif/alif.py +0 -0
  22. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_alif/data/__init__.py +0 -0
  23. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_alif/data/prefixed_double_filter.npy +0 -0
  24. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_alif/iterative_filtering.py +0 -0
  25. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_apmd/__init__.py +0 -0
  26. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_apmd/apmd.py +0 -0
  27. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/__init__.py +0 -0
  28. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/_find_extrema.py +0 -0
  29. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/_prepare_points.py +0 -0
  30. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/_splines.py +0 -0
  31. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/ceemdan.py +0 -0
  32. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/eemd.py +0 -0
  33. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/efd.py +0 -0
  34. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/emd.py +0 -0
  35. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/hht/__init__.py +0 -0
  36. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/hht/frequency.py +0 -0
  37. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/hht/hht.py +0 -0
  38. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/memd.py +0 -0
  39. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/remd.py +0 -0
  40. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd/tvf_emd.py +0 -0
  41. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd2d/__init__.py +0 -0
  42. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd2d/bemd.py +0 -0
  43. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd2d/bmemd.py +0 -0
  44. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_emd2d/emd2d.py +0 -0
  45. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_esmd/__init__.py +0 -0
  46. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_esmd/esmd.py +0 -0
  47. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_ewt/__init__.py +0 -0
  48. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_ewt/ewt.py +0 -0
  49. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_ewt/ewt2d.py +0 -0
  50. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_faemd/__init__.py +0 -0
  51. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_faemd/extrema.py +0 -0
  52. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_faemd/faemd.py +0 -0
  53. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_faemd/faemd2d.py +0 -0
  54. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_faemd/faemd3d.py +0 -0
  55. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_faemd/filter.py +0 -0
  56. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_fmd/__init__.py +0 -0
  57. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_fmd/fmd.py +0 -0
  58. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_fmd/nfmd.py +0 -0
  59. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_hvd/__init__.py +0 -0
  60. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_itd/__init__.py +0 -0
  61. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_itd/itd.py +0 -0
  62. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_lmd/__init__.py +0 -0
  63. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_lmd/lmd.py +0 -0
  64. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_osd/__init__.py +0 -0
  65. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_ssa/__init__.py +0 -0
  66. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_ssa/ssa.py +0 -0
  67. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/__init__.py +0 -0
  68. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/acmd.py +0 -0
  69. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/avmd.py +0 -0
  70. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/ba_acmd.py +0 -0
  71. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/base.py +0 -0
  72. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/mvmd.py +0 -0
  73. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/ovmd.py +0 -0
  74. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/svmd.py +0 -0
  75. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/vmd_c.py +0 -0
  76. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/vmd_f.py +0 -0
  77. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd/vme.py +0 -0
  78. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd2d/__init__.py +0 -0
  79. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd2d/cvmd2d.py +0 -0
  80. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vmd2d/vmd2d.py +0 -0
  81. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vncmd/__init__.py +0 -0
  82. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vncmd/avncmd.py +0 -0
  83. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vncmd/incmd.py +0 -0
  84. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vncmd/mncmd.py +0 -0
  85. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/_vncmd/vncmd.py +0 -0
  86. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/__init__.py +0 -0
  87. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/_add_noise.py +0 -0
  88. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/_cube.py +0 -0
  89. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/_generator.py +0 -0
  90. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/_image.py +0 -0
  91. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/_models.py +0 -0
  92. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/_test_univariate.py +0 -0
  93. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/_time_series.py +0 -0
  94. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/data/texture.txt +0 -0
  95. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/entropy/__init__.py +0 -0
  96. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/entropy/_approxiamte_entropy.py +0 -0
  97. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/entropy/_permutation_entropy.py +0 -0
  98. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/entropy/_sample_entropy.py +0 -0
  99. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/models/__init__.py +0 -0
  100. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/models/_base.py +0 -0
  101. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/models/_kmeans.py +0 -0
  102. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/models/_knn.py +0 -0
  103. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/models/_pca.py +0 -0
  104. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/plot/__init__.py +0 -0
  105. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/plot/_fourier_spectra.py +0 -0
  106. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/plot/_functions.py +0 -0
  107. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/plot/_plot_images.py +0 -0
  108. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/plot/_plot_imfs.py +0 -0
  109. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/plot/_plot_signal.py +0 -0
  110. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/__init__.py +0 -0
  111. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/data/__init__.py +0 -0
  112. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/data/test_generator_cube.py +0 -0
  113. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/data/test_generator_image.py +0 -0
  114. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/data/test_generator_signal.py +0 -0
  115. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/data/test_generator_univariate_signal.py +0 -0
  116. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/models/__init__.py +0 -0
  117. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/models/test_knn.py +0 -0
  118. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/models/test_pca.py +0 -0
  119. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/run_all.py +0 -0
  120. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_alif.py +0 -0
  121. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_apmd.py +0 -0
  122. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_avncmd.py +0 -0
  123. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_ceemdan.py +0 -0
  124. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_emd.py +0 -0
  125. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_ewt.py +0 -0
  126. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_faemd.py +0 -0
  127. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_faemd2d.py +0 -0
  128. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_faemd3d.py +0 -0
  129. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_itd.py +0 -0
  130. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_lmd.py +0 -0
  131. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_moving_decomp.py +0 -0
  132. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_ovmd.py +0 -0
  133. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_rlmd.py +0 -0
  134. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_stl.py +0 -0
  135. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_vmd.py +0 -0
  136. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tests/test_vmd2d.py +0 -0
  137. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tsa/__init__.py +0 -0
  138. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tsa/_dtw.py +0 -0
  139. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tsa/_moving_decomp.py +0 -0
  140. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tsa/_mstl.py +0 -0
  141. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/tsa/_stl.py +0 -0
  142. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/__init__.py +0 -0
  143. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_cite.py +0 -0
  144. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_correlation.py +0 -0
  145. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_diagnalization.py +0 -0
  146. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_differ.py +0 -0
  147. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_fft.py +0 -0
  148. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_function.py +0 -0
  149. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_hilbert.py +0 -0
  150. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_instantaneous.py +0 -0
  151. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_kernel_matrix.py +0 -0
  152. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_mirror.py +0 -0
  153. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_process.py +0 -0
  154. {pysdkit-0.4.28 → pysdkit-0.4.29}/pysdkit/utils/_smooth1d.py +0 -0
  155. {pysdkit-0.4.28 → pysdkit-0.4.29}/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.29
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,7 @@ 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
186
  | [`ESMD`]() (Extreme-Point Symmetric Mode Decomposition) | [[paper]](https://arxiv.org/abs/1303.6540) | [[code]](https://github.com/WuShichao/esmd) | ✖️ |
187
187
  | [`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
188
  | [`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.29
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,7 @@ 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
186
  | [`ESMD`]() (Extreme-Point Symmetric Mode Decomposition) | [[paper]](https://arxiv.org/abs/1303.6540) | [[code]](https://github.com/WuShichao/esmd) | ✖️ |
187
187
  | [`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
188
  | [`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,7 +48,6 @@ 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
@@ -115,6 +114,7 @@ pysdkit/tests/test_faemd.py
115
114
  pysdkit/tests/test_faemd2d.py
116
115
  pysdkit/tests/test_faemd3d.py
117
116
  pysdkit/tests/test_itd.py
117
+ pysdkit/tests/test_jmd.py
118
118
  pysdkit/tests/test_lmd.py
119
119
  pysdkit/tests/test_moving_decomp.py
120
120
  pysdkit/tests/test_ovmd.py
@@ -128,7 +128,7 @@ 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
132
  | [`ESMD`]() (Extreme-Point Symmetric Mode Decomposition) | [[paper]](https://arxiv.org/abs/1303.6540) | [[code]](https://github.com/WuShichao/esmd) | ✖️ |
133
133
  | [`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
134
  | [`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.29"
6
6
 
7
7
  # Empirical Mode Decomposition
8
8
  from ._emd import EMD
@@ -88,6 +88,9 @@ 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
+
91
94
  # Feature Mode Decomposition
92
95
  from ._fmd import FMD
93
96
 
@@ -151,6 +154,7 @@ Adaptive Local Iterative Filtering | ALIF
151
154
  Adaptive Polymorphic Mode Decomposition | APMD
152
155
  Empirical Wavelet Transform | EWT
153
156
  Jump Plus AM-FM Mode Decomposition | JMD
157
+ Multivariate Jump Plus AM-FM Mode Decomposition | MJMD
154
158
  Feature Mode Decomposition | FMD
155
159
  Moving Average Decomposition | Moving
156
160
  Seasonal-Trend decomposition using LOESS | STL
@@ -191,6 +195,7 @@ __all__ = [
191
195
  "ewt",
192
196
  "EWT",
193
197
  "JMD",
198
+ "MJMD",
194
199
  "FMD",
195
200
  "Moving_Decomp",
196
201
  "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,6 @@ 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
+
10
+ __all__ = ["JMD", "MJMD"]
@@ -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