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.
- {pysdkit-0.4.28 → pysdkit-0.4.30}/PKG-INFO +3 -2
- {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/PKG-INFO +3 -2
- {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/SOURCES.txt +3 -1
- {pysdkit-0.4.28 → pysdkit-0.4.30}/README.md +2 -1
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/__init__.py +12 -1
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_hvd/hvd.py +1 -1
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_jmd/__init__.py +4 -0
- pysdkit-0.4.30/pysdkit/_jmd/jmd.py +288 -0
- pysdkit-0.4.30/pysdkit/_jmd/mjmd.py +302 -0
- pysdkit-0.4.30/pysdkit/_jmd/sjmd.py +464 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_lmd/rlmd.py +2 -2
- pysdkit-0.4.30/pysdkit/tests/test_jmd.py +108 -0
- pysdkit-0.4.30/pysdkit/tests/test_sjmd.py +160 -0
- pysdkit-0.4.28/pysdkit/_ifd/__init__.py +0 -7
- pysdkit-0.4.28/pysdkit/_jmd/jmd.py +0 -395
- pysdkit-0.4.28/pysdkit/_jmd/mjmd.py +0 -34
- {pysdkit-0.4.28 → pysdkit-0.4.30}/LICENSE +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/dependency_links.txt +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/requires.txt +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/PySDKit.egg-info/top_level.txt +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pyproject.toml +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/alif.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/data/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/data/prefixed_double_filter.npy +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_alif/iterative_filtering.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_apmd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_apmd/apmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/_find_extrema.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/_prepare_points.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/_splines.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/ceemdan.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/eemd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/efd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/emd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/hht/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/hht/frequency.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/hht/hht.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/memd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/remd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd/tvf_emd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/bemd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/bmemd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_emd2d/emd2d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_esmd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_esmd/esmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ewt/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ewt/ewt.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ewt/ewt2d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/extrema.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/faemd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/faemd2d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/faemd3d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_faemd/filter.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_fmd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_fmd/fmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_fmd/nfmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_hvd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_itd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_itd/itd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_lmd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_lmd/lmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_osd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ssa/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_ssa/ssa.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/acmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/avmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/ba_acmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/base.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/mvmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/ovmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/svmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/vmd_c.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/vmd_f.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd/vme.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd2d/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd2d/cvmd2d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vmd2d/vmd2d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/avncmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/incmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/mncmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/_vncmd/vncmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_add_noise.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_cube.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_generator.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_image.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_models.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_test_univariate.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/_time_series.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/data/texture.txt +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/_approxiamte_entropy.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/_permutation_entropy.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/entropy/_sample_entropy.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_base.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_kmeans.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_knn.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/models/_pca.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_fourier_spectra.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_functions.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_plot_images.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_plot_imfs.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/plot/_plot_signal.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_cube.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_image.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_signal.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/data/test_generator_univariate_signal.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/models/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/models/test_knn.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/models/test_pca.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/run_all.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_alif.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_apmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_avncmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_ceemdan.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_emd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_ewt.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_faemd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_faemd2d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_faemd3d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_itd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_lmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_moving_decomp.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_ovmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_rlmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_stl.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_vmd.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tests/test_vmd2d.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_dtw.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_moving_decomp.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_mstl.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/tsa/_stl.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/__init__.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_cite.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_correlation.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_diagnalization.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_differ.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_fft.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_function.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_hilbert.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_instantaneous.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_kernel_matrix.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_mirror.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_process.py +0 -0
- {pysdkit-0.4.28 → pysdkit-0.4.30}/pysdkit/utils/_smooth1d.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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",
|
|
@@ -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
|