pywavelet 0.2.5__tar.gz → 0.2.6__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.
- {pywavelet-0.2.5 → pywavelet-0.2.6}/.github/workflows/ci.yml +1 -1
- {pywavelet-0.2.5 → pywavelet-0.2.6}/.github/workflows/docs.yml +1 -1
- {pywavelet-0.2.5 → pywavelet-0.2.6}/.github/workflows/pypi.yml +1 -1
- {pywavelet-0.2.5 → pywavelet-0.2.6}/.pre-commit-config.yaml +5 -8
- {pywavelet-0.2.5 → pywavelet-0.2.6}/CHANGELOG.rst +166 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/PKG-INFO +16 -5
- {pywavelet-0.2.5 → pywavelet-0.2.6}/README.rst +8 -2
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/_toc.yml +1 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/example.ipynb +8 -1
- pywavelet-0.2.6/docs/runtime.ipynb +201 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/pyproject.toml +5 -1
- pywavelet-0.2.6/src/pywavelet/__init__.py +27 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/_version.py +9 -4
- pywavelet-0.2.6/src/pywavelet/backend.py +53 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/__init__.py +10 -4
- pywavelet-0.2.6/src/pywavelet/transforms/cupy/__init__.py +12 -0
- pywavelet-0.2.6/src/pywavelet/transforms/cupy/forward/from_freq.py +92 -0
- pywavelet-0.2.6/src/pywavelet/transforms/cupy/forward/from_time.py +50 -0
- pywavelet-0.2.6/src/pywavelet/transforms/cupy/forward/main.py +106 -0
- {pywavelet-0.2.5/src/pywavelet/transforms/jax → pywavelet-0.2.6/src/pywavelet/transforms/cupy}/inverse/main.py +3 -4
- pywavelet-0.2.6/src/pywavelet/transforms/cupy/inverse/to_freq.py +62 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/forward/from_freq.py +6 -0
- pywavelet-0.2.6/src/pywavelet/transforms/jax/inverse/main.py +66 -0
- pywavelet-0.2.6/src/pywavelet/transforms/jax/inverse/to_freq.py +88 -0
- pywavelet-0.2.6/src/pywavelet/transforms/numpy/forward/__init__.py +3 -0
- pywavelet-0.2.6/src/pywavelet/transforms/numpy/forward/from_freq.py +146 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/forward/main.py +0 -1
- pywavelet-0.2.6/src/pywavelet/transforms/numpy/inverse/__init__.py +3 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/inverse/main.py +2 -4
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/inverse/to_freq.py +64 -1
- pywavelet-0.2.6/src/pywavelet/transforms/phi_computer.py +130 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/plotting.py +14 -5
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/wavelet.py +6 -6
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/PKG-INFO +16 -5
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/SOURCES.txt +14 -1
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/requires.txt +6 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/conftest.py +26 -12
- pywavelet-0.2.6/tests/ollie_example.py +32 -0
- pywavelet-0.2.6/tests/test_backends.py +136 -0
- pywavelet-0.2.6/tests/test_data/roundtrip_chirp_freq.npz +0 -0
- pywavelet-0.2.6/tests/test_data/roundtrip_sine_freq.npz +0 -0
- pywavelet-0.2.6/tests/test_data/roundtrip_sine_time.npz +0 -0
- pywavelet-0.2.6/tests/test_docs.py +46 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_phi.py +23 -15
- pywavelet-0.2.6/tests/test_roundtrip_conversion.py +167 -0
- pywavelet-0.2.6/tests/utils/__init__.py +4 -0
- pywavelet-0.2.6/tests/utils/conversions.py +23 -0
- pywavelet-0.2.6/tests/utils/cupy_check.py +14 -0
- pywavelet-0.2.6/tests/utils/generate_data.py +32 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/utils/plotting.py +87 -28
- pywavelet-0.2.5/src/pywavelet/__init__.py +0 -5
- pywavelet-0.2.5/src/pywavelet/backend.py +0 -31
- pywavelet-0.2.5/src/pywavelet/transforms/jax/inverse/to_freq.py +0 -74
- pywavelet-0.2.5/src/pywavelet/transforms/numpy/forward/from_freq.py +0 -88
- pywavelet-0.2.5/src/pywavelet/transforms/phi_computer.py +0 -142
- pywavelet-0.2.5/tests/test_data/roundtrip_chirp_freq.npz +0 -0
- pywavelet-0.2.5/tests/test_data/roundtrip_sine_freq.npz +0 -0
- pywavelet-0.2.5/tests/test_data/roundtrip_sine_time.npz +0 -0
- pywavelet-0.2.5/tests/test_jax.py +0 -105
- pywavelet-0.2.5/tests/test_roundtrip_conversion.py +0 -124
- pywavelet-0.2.5/tests/utils/__init__.py +0 -2
- pywavelet-0.2.5/tests/utils/generate_data.py +0 -59
- {pywavelet-0.2.5 → pywavelet-0.2.6}/.gitignore +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/CITATION.cff +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/_config.yml +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/_static/demo.gif +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/api.rst +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/index.rst +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/logo.png +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/roundtrip_freq.png +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/roundtrip_time.png +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/setup.cfg +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/logger.py +0 -0
- {pywavelet-0.2.5/src/pywavelet/transforms/jax → pywavelet-0.2.6/src/pywavelet/transforms/cupy}/forward/__init__.py +0 -0
- {pywavelet-0.2.5/src/pywavelet/transforms/jax → pywavelet-0.2.6/src/pywavelet/transforms/cupy}/inverse/__init__.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/__init__.py +0 -0
- {pywavelet-0.2.5/src/pywavelet/transforms/numpy → pywavelet-0.2.6/src/pywavelet/transforms/jax}/forward/__init__.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/forward/from_time.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/forward/main.py +0 -0
- {pywavelet-0.2.5/src/pywavelet/transforms/numpy → pywavelet-0.2.6/src/pywavelet/transforms/jax}/inverse/__init__.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/__init__.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/forward/from_time.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/inverse/to_time.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/__init__.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/common.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/frequencyseries.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/timeseries.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/wavelet_bins.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/utils.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/dependency_links.txt +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/top_level.txt +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_data/roundtrip_chirp_time.npz +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_data/roundtrip_pure_f0_freq.npz +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_lnl.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_mask.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_psd.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_snr.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_timefreq_type.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_version.py +0 -0
- {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_wavelet_plot.py +0 -0
@@ -1,22 +1,19 @@
|
|
1
1
|
repos:
|
2
2
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
3
|
-
rev:
|
3
|
+
rev: v5.0.0
|
4
4
|
hooks:
|
5
5
|
- id: trailing-whitespace
|
6
6
|
- id: end-of-file-fixer
|
7
7
|
- id: check-merge-conflict
|
8
8
|
- id: check-yaml
|
9
9
|
args: [ --unsafe ]
|
10
|
-
- repo: https://github.com/
|
11
|
-
rev:
|
10
|
+
- repo: https://github.com/PyCQA/isort
|
11
|
+
rev: 6.0.1
|
12
12
|
hooks:
|
13
13
|
- id: isort
|
14
14
|
args: ["--profile", "black"]
|
15
|
-
- repo: https://github.com/ambv/black
|
16
|
-
rev: 23.10.0
|
17
|
-
hooks:
|
18
|
-
- id: black
|
19
15
|
- repo: https://github.com/psf/black
|
20
|
-
rev:
|
16
|
+
rev: 25.1.0
|
21
17
|
hooks:
|
18
|
+
- id: black
|
22
19
|
- id: black-jupyter
|
@@ -5,6 +5,166 @@ CHANGELOG
|
|
5
5
|
=========
|
6
6
|
|
7
7
|
|
8
|
+
.. _changelog-v0.2.6:
|
9
|
+
|
10
|
+
v0.2.6 (2025-03-24)
|
11
|
+
===================
|
12
|
+
|
13
|
+
Bug Fixes
|
14
|
+
---------
|
15
|
+
|
16
|
+
* fix: add note in readme about JAX and cupy (`d3cd8d9`_)
|
17
|
+
|
18
|
+
Unknown
|
19
|
+
-------
|
20
|
+
|
21
|
+
* add runtimes (`6cdfb28`_)
|
22
|
+
|
23
|
+
* add runtime plot (`14b250b`_)
|
24
|
+
|
25
|
+
* add runtime doc (`3d8b4cd`_)
|
26
|
+
|
27
|
+
* add runtime doc (`7230f92`_)
|
28
|
+
|
29
|
+
* add more tests and runtime doc (`b8dce3f`_)
|
30
|
+
|
31
|
+
* add roundtrip comparisons (`81d6fc7`_)
|
32
|
+
|
33
|
+
* remove dt (`d78b4b3`_)
|
34
|
+
|
35
|
+
* remove mult (`b5ab983`_)
|
36
|
+
|
37
|
+
* add corrected sinewave for roundtrip test, remove incorrect f0 test (`e2f8317`_)
|
38
|
+
|
39
|
+
* add WDM amplitude tests (`b99fc0d`_)
|
40
|
+
|
41
|
+
* add various transforms (`7d97420`_)
|
42
|
+
|
43
|
+
* fix cupy inverse (`b1f7dfa`_)
|
44
|
+
|
45
|
+
* add plotting (`b0ad4fa`_)
|
46
|
+
|
47
|
+
* add more tests (`aaeae9b`_)
|
48
|
+
|
49
|
+
* add more tests (`6627e03`_)
|
50
|
+
|
51
|
+
* add backend test (`ccb1193`_)
|
52
|
+
|
53
|
+
* add more logging (`f2d6541`_)
|
54
|
+
|
55
|
+
* add more logs (`0828947`_)
|
56
|
+
|
57
|
+
* add more tests (`8c80929`_)
|
58
|
+
|
59
|
+
* add more tests (`d1cb636`_)
|
60
|
+
|
61
|
+
* Merge branch 'main' of github.com:pywavelet/pywavelet (`ab6ba0e`_)
|
62
|
+
|
63
|
+
* Update __init__.py (`b607ae9`_)
|
64
|
+
|
65
|
+
* add more logs (`60e9525`_)
|
66
|
+
|
67
|
+
* add notes (`83e4ff6`_)
|
68
|
+
|
69
|
+
* increase the py version (`0d6568b`_)
|
70
|
+
|
71
|
+
* setup testing framework for cupy (`5009d79`_)
|
72
|
+
|
73
|
+
* add typing for phi (`16ef510`_)
|
74
|
+
|
75
|
+
* Check which backend (`f17fe1b`_)
|
76
|
+
|
77
|
+
* Check which backend (`196141c`_)
|
78
|
+
|
79
|
+
* add typing libs (beartype + Jaxtyping) (`3bffe6a`_)
|
80
|
+
|
81
|
+
* Add support for more backends (`dadf161`_)
|
82
|
+
|
83
|
+
* Adding cupy methods (`9fe44ab`_)
|
84
|
+
|
85
|
+
* Remove unnecessary beta(d,d,1) (`19b6d8e`_)
|
86
|
+
|
87
|
+
* Remove unused imports (`a2b42c8`_)
|
88
|
+
|
89
|
+
* run formatters (`380fba8`_)
|
90
|
+
|
91
|
+
* begin adding cupy (`93e0123`_)
|
92
|
+
|
93
|
+
* add more tests (`a91f509`_)
|
94
|
+
|
95
|
+
* Merge branch 'main' of github.com:avivajpeyi/pywavelet into main (`a149dc4`_)
|
96
|
+
|
97
|
+
* [pre-commit.ci] pre-commit autoupdate (#21)
|
98
|
+
|
99
|
+
* [pre-commit.ci] pre-commit autoupdate
|
100
|
+
|
101
|
+
updates:
|
102
|
+
- [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v5.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v5.0.0)
|
103
|
+
- https://github.com/pre-commit/mirrors-isort → https://github.com/PyCQA/isort
|
104
|
+
- [github.com/PyCQA/isort: v5.10.1 → 6.0.1](https://github.com/PyCQA/isort/compare/v5.10.1...6.0.1)
|
105
|
+
- https://github.com/ambv/black → https://github.com/psf/black
|
106
|
+
- [github.com/psf/black: 23.10.0 → 25.1.0](https://github.com/psf/black/compare/23.10.0...25.1.0)
|
107
|
+
- [github.com/psf/black: 23.10.0 → 25.1.0](https://github.com/psf/black/compare/23.10.0...25.1.0)
|
108
|
+
|
109
|
+
* [pre-commit.ci] auto fixes from pre-commit.com hooks
|
110
|
+
|
111
|
+
for more information, see https://pre-commit.ci
|
112
|
+
|
113
|
+
---------
|
114
|
+
|
115
|
+
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> (`6623f65`_)
|
116
|
+
|
117
|
+
* add check for vmin > vmax (`2d6eec3`_)
|
118
|
+
|
119
|
+
* more plotting for phi (`b124dc7`_)
|
120
|
+
|
121
|
+
* add additional JAX tests (`c0d8396`_)
|
122
|
+
|
123
|
+
.. _d3cd8d9: https://github.com/pywavelet/pywavelet/commit/d3cd8d92b5e6cf398ff3a4948b911533abe842f1
|
124
|
+
.. _6cdfb28: https://github.com/pywavelet/pywavelet/commit/6cdfb28b152a7f7ad499f0b6ba6ef69da9284c57
|
125
|
+
.. _14b250b: https://github.com/pywavelet/pywavelet/commit/14b250b55dbea88c3b7c22b5faca531113d34477
|
126
|
+
.. _3d8b4cd: https://github.com/pywavelet/pywavelet/commit/3d8b4cdc8dea6af33b08985cb97f0897984838fc
|
127
|
+
.. _7230f92: https://github.com/pywavelet/pywavelet/commit/7230f92dee98cea0e402111ad279f78c6134d565
|
128
|
+
.. _b8dce3f: https://github.com/pywavelet/pywavelet/commit/b8dce3fdf2f0b1261b6a74aa8af03465c87017ff
|
129
|
+
.. _81d6fc7: https://github.com/pywavelet/pywavelet/commit/81d6fc73ec9c37d7e5990f7008f1a468490b17ea
|
130
|
+
.. _d78b4b3: https://github.com/pywavelet/pywavelet/commit/d78b4b32b81b1b2e8bc6c4808c088df140f316dd
|
131
|
+
.. _b5ab983: https://github.com/pywavelet/pywavelet/commit/b5ab983f88a4dc5f6b7e75aa9c974f1c0c601d03
|
132
|
+
.. _e2f8317: https://github.com/pywavelet/pywavelet/commit/e2f8317f980927f34fc447e3b093ca43e2f8f3c2
|
133
|
+
.. _b99fc0d: https://github.com/pywavelet/pywavelet/commit/b99fc0d3a29b8c741c92e6a1cae9eabc409d1fbc
|
134
|
+
.. _7d97420: https://github.com/pywavelet/pywavelet/commit/7d97420b945dd8abb4dd9e201246719d39c4bc4c
|
135
|
+
.. _b1f7dfa: https://github.com/pywavelet/pywavelet/commit/b1f7dfa17df3215260150e41c0cf84e76a354d1b
|
136
|
+
.. _b0ad4fa: https://github.com/pywavelet/pywavelet/commit/b0ad4fad4537bf3375bb100f6b5be3042291e31e
|
137
|
+
.. _aaeae9b: https://github.com/pywavelet/pywavelet/commit/aaeae9b232e4328bfa2a566c7438f41f2dca0e31
|
138
|
+
.. _6627e03: https://github.com/pywavelet/pywavelet/commit/6627e0353d539b358e8bc6e786d3442a2b2b8072
|
139
|
+
.. _ccb1193: https://github.com/pywavelet/pywavelet/commit/ccb1193e968c9617ed866318326421fb2ae80645
|
140
|
+
.. _f2d6541: https://github.com/pywavelet/pywavelet/commit/f2d6541caa41f171a19abd5cfdb3e132fc831b8b
|
141
|
+
.. _0828947: https://github.com/pywavelet/pywavelet/commit/082894710eaa2f4a485a86524917068e3098b0c4
|
142
|
+
.. _8c80929: https://github.com/pywavelet/pywavelet/commit/8c80929e35211d482d15845fd9ef0cca62704b4b
|
143
|
+
.. _d1cb636: https://github.com/pywavelet/pywavelet/commit/d1cb636fb92fbec238de89129729a70f7fa33bb6
|
144
|
+
.. _ab6ba0e: https://github.com/pywavelet/pywavelet/commit/ab6ba0ed98a6597c9c8aef524a2f03b1b6fbd13e
|
145
|
+
.. _b607ae9: https://github.com/pywavelet/pywavelet/commit/b607ae971f1b04870f41bbaee95a2a30eef628d4
|
146
|
+
.. _60e9525: https://github.com/pywavelet/pywavelet/commit/60e952536a2812f474a2845f81dee52884b1685b
|
147
|
+
.. _83e4ff6: https://github.com/pywavelet/pywavelet/commit/83e4ff6e5ac5ee1fd51970a73c0401106cff453a
|
148
|
+
.. _0d6568b: https://github.com/pywavelet/pywavelet/commit/0d6568bc305d85ac7f5733365e50e51538d45329
|
149
|
+
.. _5009d79: https://github.com/pywavelet/pywavelet/commit/5009d7957d9d796a9e2258659e2815a35354a7a5
|
150
|
+
.. _16ef510: https://github.com/pywavelet/pywavelet/commit/16ef51086b1ba10db0d4f252caf3a560fee4f06b
|
151
|
+
.. _f17fe1b: https://github.com/pywavelet/pywavelet/commit/f17fe1b0cddb4376bdb18a092d6f83bc48dd9498
|
152
|
+
.. _196141c: https://github.com/pywavelet/pywavelet/commit/196141ce52946228a92aa1f4b0c14fdc66cb44a1
|
153
|
+
.. _3bffe6a: https://github.com/pywavelet/pywavelet/commit/3bffe6a7af4000b1bcece2e2fb1c56487980dd15
|
154
|
+
.. _dadf161: https://github.com/pywavelet/pywavelet/commit/dadf161bed6c049c8c24716f475f94b9d6e9fabf
|
155
|
+
.. _9fe44ab: https://github.com/pywavelet/pywavelet/commit/9fe44ab0d0862110137e02d746e1af1591373c66
|
156
|
+
.. _19b6d8e: https://github.com/pywavelet/pywavelet/commit/19b6d8e169c87f780afe809863762574a9a6334b
|
157
|
+
.. _a2b42c8: https://github.com/pywavelet/pywavelet/commit/a2b42c885dd248a2787b6ce7ae549f3d15044af3
|
158
|
+
.. _380fba8: https://github.com/pywavelet/pywavelet/commit/380fba8f074d7fbe9bc4ed51461688c45dfc7b0a
|
159
|
+
.. _93e0123: https://github.com/pywavelet/pywavelet/commit/93e0123dce8f4bf44249489a55a84865ef989592
|
160
|
+
.. _a91f509: https://github.com/pywavelet/pywavelet/commit/a91f509c1c7e18d75c6ceeff22242b1e463f4191
|
161
|
+
.. _a149dc4: https://github.com/pywavelet/pywavelet/commit/a149dc4178581f26745b0725346ad469f4aed8d6
|
162
|
+
.. _6623f65: https://github.com/pywavelet/pywavelet/commit/6623f65aa13a020120d52363c2bb7b6dd425845f
|
163
|
+
.. _2d6eec3: https://github.com/pywavelet/pywavelet/commit/2d6eec342676c1dadb5ce7318edf781572dde5c4
|
164
|
+
.. _b124dc7: https://github.com/pywavelet/pywavelet/commit/b124dc75c13540a946b665e0bbb70de43ffe16fd
|
165
|
+
.. _c0d8396: https://github.com/pywavelet/pywavelet/commit/c0d8396587737ac9d9559e79c175a043273b8ce6
|
166
|
+
|
167
|
+
|
8
168
|
.. _changelog-v0.2.5:
|
9
169
|
|
10
170
|
v0.2.5 (2025-01-28)
|
@@ -25,7 +185,13 @@ for more information, see https://pre-commit.ci
|
|
25
185
|
|
26
186
|
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> (`3228f7b`_)
|
27
187
|
|
188
|
+
Chores
|
189
|
+
------
|
190
|
+
|
191
|
+
* chore(release): 0.2.5 (`34b18c7`_)
|
192
|
+
|
28
193
|
.. _3228f7b: https://github.com/pywavelet/pywavelet/commit/3228f7be0d7efb48812920e822a14e795ebac57f
|
194
|
+
.. _34b18c7: https://github.com/pywavelet/pywavelet/commit/34b18c7d4074992d6c1ce75806efb3edab5ce49b
|
29
195
|
|
30
196
|
|
31
197
|
.. _changelog-v0.2.4:
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: pywavelet
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.6
|
4
4
|
Summary: WDM wavelet transform your time/freq series!
|
5
5
|
Author-email: Pywavelet Team <avi.vajpeyi@gmail.com>
|
6
6
|
Project-URL: Homepage, https://pywavelet.github.io/pywavelet/
|
@@ -11,7 +11,7 @@ Classifier: Intended Audience :: Science/Research
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
12
12
|
Classifier: Operating System :: OS Independent
|
13
13
|
Classifier: Programming Language :: Python :: 3.8
|
14
|
-
Requires-Python: >=3.
|
14
|
+
Requires-Python: >=3.10
|
15
15
|
Description-Content-Type: text/x-rst
|
16
16
|
Requires-Dist: numpy
|
17
17
|
Requires-Dist: numba
|
@@ -21,8 +21,12 @@ Requires-Dist: tqdm
|
|
21
21
|
Requires-Dist: rich
|
22
22
|
Requires-Dist: rocket-fft
|
23
23
|
Requires-Dist: astropy>=5.2.1
|
24
|
+
Requires-Dist: jaxtyping
|
25
|
+
Requires-Dist: beartype
|
24
26
|
Provides-Extra: jax
|
25
27
|
Requires-Dist: jax; extra == "jax"
|
28
|
+
Provides-Extra: cupy
|
29
|
+
Requires-Dist: cupy; extra == "cupy"
|
26
30
|
Provides-Extra: dev
|
27
31
|
Requires-Dist: pytest>=6.0; extra == "dev"
|
28
32
|
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
@@ -34,6 +38,7 @@ Requires-Dist: isort; extra == "dev"
|
|
34
38
|
Requires-Dist: mypy; extra == "dev"
|
35
39
|
Requires-Dist: jupyter-book; extra == "dev"
|
36
40
|
Requires-Dist: GitPython; extra == "dev"
|
41
|
+
Requires-Dist: nbconvert; extra == "dev"
|
37
42
|
|
38
43
|
pywavelet
|
39
44
|
#########
|
@@ -59,17 +64,23 @@ pywavelet is available on PyPI and can be installed with `pip <https://pip.pypa.
|
|
59
64
|
|
60
65
|
$ pip install pywavelet
|
61
66
|
|
67
|
+
|
68
|
+
Note: We have transforms availible in numpy, JAX and Cupy.
|
69
|
+
|
70
|
+
|
62
71
|
For developers
|
63
72
|
--------------
|
64
73
|
|
65
|
-
First set up a conda environment with
|
74
|
+
First set up a conda environment with python 3.10
|
66
75
|
|
67
76
|
.. code-block::
|
68
77
|
|
69
|
-
$
|
78
|
+
$ mamba create -n pywavelet python=3.10
|
70
79
|
|
71
80
|
.. code-block::
|
72
81
|
|
82
|
+
$ CONDA_OVERRIDE_CUDA=12.4 mamba install "jaxlib=*=*cuda*" jax -c conda-forge
|
83
|
+
$ CONDA_OVERRIDE_CUDA=12.4 conda install -c conda-forge cupy-core
|
73
84
|
$ pip install -e ".[dev]"
|
74
85
|
$ pre-commit install
|
75
86
|
|
@@ -22,17 +22,23 @@ pywavelet is available on PyPI and can be installed with `pip <https://pip.pypa.
|
|
22
22
|
|
23
23
|
$ pip install pywavelet
|
24
24
|
|
25
|
+
|
26
|
+
Note: We have transforms availible in numpy, JAX and Cupy.
|
27
|
+
|
28
|
+
|
25
29
|
For developers
|
26
30
|
--------------
|
27
31
|
|
28
|
-
First set up a conda environment with
|
32
|
+
First set up a conda environment with python 3.10
|
29
33
|
|
30
34
|
.. code-block::
|
31
35
|
|
32
|
-
$
|
36
|
+
$ mamba create -n pywavelet python=3.10
|
33
37
|
|
34
38
|
.. code-block::
|
35
39
|
|
40
|
+
$ CONDA_OVERRIDE_CUDA=12.4 mamba install "jaxlib=*=*cuda*" jax -c conda-forge
|
41
|
+
$ CONDA_OVERRIDE_CUDA=12.4 conda install -c conda-forge cupy-core
|
36
42
|
$ pip install -e ".[dev]"
|
37
43
|
$ pre-commit install
|
38
44
|
|
@@ -4,7 +4,14 @@
|
|
4
4
|
"cell_type": "markdown",
|
5
5
|
"metadata": {},
|
6
6
|
"source": [
|
7
|
-
"
|
7
|
+
"<a target=\"_blank\" href=\"https://colab.research.google.com/github/pywavelet/pywavelet/blob/main/docs/example.ipynb\">\n",
|
8
|
+
" <img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/>\n",
|
9
|
+
"</a>\n",
|
10
|
+
"\n",
|
11
|
+
"# Example\n",
|
12
|
+
"\n",
|
13
|
+
"\n",
|
14
|
+
"\n",
|
8
15
|
"## Time to Wavelet\n",
|
9
16
|
"\n",
|
10
17
|
"\n",
|
@@ -0,0 +1,201 @@
|
|
1
|
+
{
|
2
|
+
"cells": [
|
3
|
+
{
|
4
|
+
"metadata": {},
|
5
|
+
"cell_type": "markdown",
|
6
|
+
"source": [
|
7
|
+
"<a target=\"_blank\" href=\"https://colab.research.google.com/github/pywavelet/pywavelet/blob/main/docs/runtime.ipynb\">\n",
|
8
|
+
" <img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/>\n",
|
9
|
+
"</a>\n",
|
10
|
+
"\n",
|
11
|
+
"\n",
|
12
|
+
"# Runtime Comparisons"
|
13
|
+
],
|
14
|
+
"id": "9df79fd10b46e463"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"cell_type": "code",
|
18
|
+
"id": "initial_id",
|
19
|
+
"metadata": {
|
20
|
+
"collapsed": true,
|
21
|
+
"ExecuteTime": {
|
22
|
+
"end_time": "2025-03-24T03:51:57.891463Z",
|
23
|
+
"start_time": "2025-03-24T03:51:48.904827Z"
|
24
|
+
}
|
25
|
+
},
|
26
|
+
"source": [
|
27
|
+
"import importlib\n",
|
28
|
+
"import numpy as np\n",
|
29
|
+
"import jax.numpy as jnp\n",
|
30
|
+
"from numba.cuda import runtime\n",
|
31
|
+
"from tqdm.auto import tqdm\n",
|
32
|
+
"from pywavelet.types import FrequencySeries\n",
|
33
|
+
"from pywavelet.transforms.phi_computer import phitilde_vec_norm\n",
|
34
|
+
"from timeit import repeat as timing_repeat\n",
|
35
|
+
"import matplotlib.pyplot as plt\n",
|
36
|
+
"\n",
|
37
|
+
"\n",
|
38
|
+
"cupy_available = importlib.util.find_spec(\"cupy\") is not None\n",
|
39
|
+
"\n",
|
40
|
+
"if cupy_available:\n",
|
41
|
+
" import cupy as cp\n",
|
42
|
+
"\n",
|
43
|
+
"\n",
|
44
|
+
"def generate_freq_domain_signal(\n",
|
45
|
+
" ND, f0=20.0, dt=0.0125, A=2\n",
|
46
|
+
") -> FrequencySeries:\n",
|
47
|
+
" \"\"\"\n",
|
48
|
+
" Generates a frequency domain signal.\n",
|
49
|
+
"\n",
|
50
|
+
" Parameters:\n",
|
51
|
+
" ND (int): Number of data points.\n",
|
52
|
+
" f0 (float): Frequency of the signal. Default is 20.0.\n",
|
53
|
+
" dt (float): Time step. Default is 0.0125.\n",
|
54
|
+
" A (float): Amplitude of the signal. Default is 2.\n",
|
55
|
+
"\n",
|
56
|
+
" Returns:\n",
|
57
|
+
" FrequencySeries: The generated frequency domain signal.\n",
|
58
|
+
" \"\"\"\n",
|
59
|
+
" ts = np.arange(0, ND) * dt\n",
|
60
|
+
" y = A * np.sin(2 * np.pi * f0 * ts)\n",
|
61
|
+
" yf = FrequencySeries(y, ts)\n",
|
62
|
+
" return yf\n",
|
63
|
+
"\n",
|
64
|
+
"\n",
|
65
|
+
"def generate_func_args(ND, backend=\"numpy\"):\n",
|
66
|
+
" Nf = Nt = int(np.sqrt(ND))\n",
|
67
|
+
" yf = generate_freq_domain_signal(ND).data\n",
|
68
|
+
" phif = phitilde_vec_norm(Nf, Nt, d=4.0)\n",
|
69
|
+
" if backend == \"jax\":\n",
|
70
|
+
" yf = jnp.array(yf)\n",
|
71
|
+
" phif = jnp.array(phif)\n",
|
72
|
+
" if backend == \"cupy\" and cupy_available:\n",
|
73
|
+
" yf = cp.array(yf)\n",
|
74
|
+
" phif = cp.array(phif)\n",
|
75
|
+
" return yf, Nf, Nt, phif\n",
|
76
|
+
"\n",
|
77
|
+
"\n",
|
78
|
+
"def collect_runtime(\n",
|
79
|
+
" func, func_args, n=5, nreps=5\n",
|
80
|
+
"):\n",
|
81
|
+
" func(*func_args) # Warm up run\n",
|
82
|
+
" times = timing_repeat(\n",
|
83
|
+
" lambda: func(*func_args),\n",
|
84
|
+
" number=n,\n",
|
85
|
+
" repeat=nreps\n",
|
86
|
+
" )\n",
|
87
|
+
"\n",
|
88
|
+
" return (np.median(times), (np.std(times)))\n",
|
89
|
+
"\n",
|
90
|
+
"\n",
|
91
|
+
"def collect_runtimes(func, backend, NF_values, number=5, repeat=5):\n",
|
92
|
+
" results = {}\n",
|
93
|
+
" bar = tqdm(NF_values, desc=\"Running\")\n",
|
94
|
+
" for Nf in bar:\n",
|
95
|
+
" ND = Nf * Nf\n",
|
96
|
+
" bar.set_postfix(ND=f\"2**{int(np.log2(ND))}\")\n",
|
97
|
+
" func_args = generate_func_args(ND, backend)\n",
|
98
|
+
" results[ND] = collect_runtime(func, func_args, number, repeat)\n",
|
99
|
+
" return results\n",
|
100
|
+
"\n",
|
101
|
+
"\n",
|
102
|
+
"def run_transforms():\n",
|
103
|
+
" from pywavelet.transforms.jax.forward.from_freq import transform_wavelet_freq_helper as jax_transform\n",
|
104
|
+
" from pywavelet.transforms.numpy.forward.from_freq import transform_wavelet_freq_helper as np_transform\n",
|
105
|
+
"\n",
|
106
|
+
" min_pow2 = 2\n",
|
107
|
+
" max_pow2 = 12\n",
|
108
|
+
" NF = [2 ** i for i in range(min_pow2, max_pow2)]\n",
|
109
|
+
"\n",
|
110
|
+
" runtimes = {}\n",
|
111
|
+
" runtimes[\"numpy\"] = collect_runtimes(np_transform, \"numpy\", NF, number=5, repeat=5)\n",
|
112
|
+
" runtimes[\"jax\"] = collect_runtimes(jax_transform, \"jax\", NF, number=5, repeat=5)\n",
|
113
|
+
"\n",
|
114
|
+
" if cupy_available:\n",
|
115
|
+
" from pywavelet.transforms.cupy.forward.from_freq import transform_wavelet_freq_helper as cp_transform\n",
|
116
|
+
" runtimes['cupy'] = collect_runtimes(cp_transform, \"cupy\", NF, number=10, repeat=10)\n",
|
117
|
+
" \n",
|
118
|
+
" \n",
|
119
|
+
" return runtimes\n",
|
120
|
+
"\n",
|
121
|
+
"\n",
|
122
|
+
"def plot(runtimes):\n",
|
123
|
+
" fig, ax = plt.subplots(figsize=(4, 3.5))\n",
|
124
|
+
" for i, backend in enumerate(runtimes.keys()):\n",
|
125
|
+
" _plot_backend_runtime(ax, runtimes[backend], backend, f\"C{i}\")\n",
|
126
|
+
" ax.set_yscale(\"log\")\n",
|
127
|
+
" ax.set_xscale(\"log\")\n",
|
128
|
+
" ax.set_xlabel(\"Number of Data Points\")\n",
|
129
|
+
" ax.set_ylabel(\"Runtime (s)\")\n",
|
130
|
+
" ax.legend(frameon=False)\n",
|
131
|
+
" return fig\n",
|
132
|
+
"\n",
|
133
|
+
"\n",
|
134
|
+
"def _plot_backend_runtime(ax, runtimes, backend, color):\n",
|
135
|
+
" NDs = list(runtimes.keys())\n",
|
136
|
+
" times = [runtimes[ND][0] for ND in NDs]\n",
|
137
|
+
" stds = [runtimes[ND][1] for ND in NDs]\n",
|
138
|
+
" # plot a band around the median runtime\n",
|
139
|
+
" ax.fill_between(NDs, np.array(times) - np.array(stds), np.array(times) + np.array(stds), alpha=0.3, color=color)\n",
|
140
|
+
" ax.plot(NDs, times, label=f\"{backend}\", color=color)\n",
|
141
|
+
" ax.set_xlim(min(NDs), max(NDs))\n",
|
142
|
+
"\n",
|
143
|
+
"\n",
|
144
|
+
"runtimes = run_transforms()\n",
|
145
|
+
"fig = plot(runtimes)\n",
|
146
|
+
"fig.savefig(\"runtime.png\", bbox_inches=\"tight\")\n",
|
147
|
+
"\n"
|
148
|
+
],
|
149
|
+
"outputs": [
|
150
|
+
{
|
151
|
+
"name": "stderr",
|
152
|
+
"output_type": "stream",
|
153
|
+
"text": [
|
154
|
+
"Running: 100%|██████████| 10/10 [00:05<00:00, 1.95it/s, ND=2**22]\n",
|
155
|
+
"Running: 100%|██████████| 10/10 [00:00<00:00, 14.41it/s, ND=2**22]\n"
|
156
|
+
]
|
157
|
+
},
|
158
|
+
{
|
159
|
+
"data": {
|
160
|
+
"text/plain": [
|
161
|
+
"<Figure size 400x350 with 1 Axes>"
|
162
|
+
],
|
163
|
+
"image/png": "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"
|
164
|
+
},
|
165
|
+
"metadata": {},
|
166
|
+
"output_type": "display_data"
|
167
|
+
}
|
168
|
+
],
|
169
|
+
"execution_count": 20
|
170
|
+
},
|
171
|
+
{
|
172
|
+
"metadata": {},
|
173
|
+
"cell_type": "code",
|
174
|
+
"outputs": [],
|
175
|
+
"execution_count": null,
|
176
|
+
"source": "",
|
177
|
+
"id": "7b1a6e9fd3a1955d"
|
178
|
+
}
|
179
|
+
],
|
180
|
+
"metadata": {
|
181
|
+
"kernelspec": {
|
182
|
+
"display_name": "Python 3",
|
183
|
+
"language": "python",
|
184
|
+
"name": "python3"
|
185
|
+
},
|
186
|
+
"language_info": {
|
187
|
+
"codemirror_mode": {
|
188
|
+
"name": "ipython",
|
189
|
+
"version": 2
|
190
|
+
},
|
191
|
+
"file_extension": ".py",
|
192
|
+
"mimetype": "text/x-python",
|
193
|
+
"name": "python",
|
194
|
+
"nbconvert_exporter": "python",
|
195
|
+
"pygments_lexer": "ipython2",
|
196
|
+
"version": "2.7.6"
|
197
|
+
}
|
198
|
+
},
|
199
|
+
"nbformat": 4,
|
200
|
+
"nbformat_minor": 5
|
201
|
+
}
|