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.
Files changed (100) hide show
  1. {pywavelet-0.2.5 → pywavelet-0.2.6}/.github/workflows/ci.yml +1 -1
  2. {pywavelet-0.2.5 → pywavelet-0.2.6}/.github/workflows/docs.yml +1 -1
  3. {pywavelet-0.2.5 → pywavelet-0.2.6}/.github/workflows/pypi.yml +1 -1
  4. {pywavelet-0.2.5 → pywavelet-0.2.6}/.pre-commit-config.yaml +5 -8
  5. {pywavelet-0.2.5 → pywavelet-0.2.6}/CHANGELOG.rst +166 -0
  6. {pywavelet-0.2.5 → pywavelet-0.2.6}/PKG-INFO +16 -5
  7. {pywavelet-0.2.5 → pywavelet-0.2.6}/README.rst +8 -2
  8. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/_toc.yml +1 -0
  9. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/example.ipynb +8 -1
  10. pywavelet-0.2.6/docs/runtime.ipynb +201 -0
  11. {pywavelet-0.2.5 → pywavelet-0.2.6}/pyproject.toml +5 -1
  12. pywavelet-0.2.6/src/pywavelet/__init__.py +27 -0
  13. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/_version.py +9 -4
  14. pywavelet-0.2.6/src/pywavelet/backend.py +53 -0
  15. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/__init__.py +10 -4
  16. pywavelet-0.2.6/src/pywavelet/transforms/cupy/__init__.py +12 -0
  17. pywavelet-0.2.6/src/pywavelet/transforms/cupy/forward/from_freq.py +92 -0
  18. pywavelet-0.2.6/src/pywavelet/transforms/cupy/forward/from_time.py +50 -0
  19. pywavelet-0.2.6/src/pywavelet/transforms/cupy/forward/main.py +106 -0
  20. {pywavelet-0.2.5/src/pywavelet/transforms/jax → pywavelet-0.2.6/src/pywavelet/transforms/cupy}/inverse/main.py +3 -4
  21. pywavelet-0.2.6/src/pywavelet/transforms/cupy/inverse/to_freq.py +62 -0
  22. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/forward/from_freq.py +6 -0
  23. pywavelet-0.2.6/src/pywavelet/transforms/jax/inverse/main.py +66 -0
  24. pywavelet-0.2.6/src/pywavelet/transforms/jax/inverse/to_freq.py +88 -0
  25. pywavelet-0.2.6/src/pywavelet/transforms/numpy/forward/__init__.py +3 -0
  26. pywavelet-0.2.6/src/pywavelet/transforms/numpy/forward/from_freq.py +146 -0
  27. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/forward/main.py +0 -1
  28. pywavelet-0.2.6/src/pywavelet/transforms/numpy/inverse/__init__.py +3 -0
  29. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/inverse/main.py +2 -4
  30. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/inverse/to_freq.py +64 -1
  31. pywavelet-0.2.6/src/pywavelet/transforms/phi_computer.py +130 -0
  32. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/plotting.py +14 -5
  33. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/wavelet.py +6 -6
  34. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/PKG-INFO +16 -5
  35. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/SOURCES.txt +14 -1
  36. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/requires.txt +6 -0
  37. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/conftest.py +26 -12
  38. pywavelet-0.2.6/tests/ollie_example.py +32 -0
  39. pywavelet-0.2.6/tests/test_backends.py +136 -0
  40. pywavelet-0.2.6/tests/test_data/roundtrip_chirp_freq.npz +0 -0
  41. pywavelet-0.2.6/tests/test_data/roundtrip_sine_freq.npz +0 -0
  42. pywavelet-0.2.6/tests/test_data/roundtrip_sine_time.npz +0 -0
  43. pywavelet-0.2.6/tests/test_docs.py +46 -0
  44. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_phi.py +23 -15
  45. pywavelet-0.2.6/tests/test_roundtrip_conversion.py +167 -0
  46. pywavelet-0.2.6/tests/utils/__init__.py +4 -0
  47. pywavelet-0.2.6/tests/utils/conversions.py +23 -0
  48. pywavelet-0.2.6/tests/utils/cupy_check.py +14 -0
  49. pywavelet-0.2.6/tests/utils/generate_data.py +32 -0
  50. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/utils/plotting.py +87 -28
  51. pywavelet-0.2.5/src/pywavelet/__init__.py +0 -5
  52. pywavelet-0.2.5/src/pywavelet/backend.py +0 -31
  53. pywavelet-0.2.5/src/pywavelet/transforms/jax/inverse/to_freq.py +0 -74
  54. pywavelet-0.2.5/src/pywavelet/transforms/numpy/forward/from_freq.py +0 -88
  55. pywavelet-0.2.5/src/pywavelet/transforms/phi_computer.py +0 -142
  56. pywavelet-0.2.5/tests/test_data/roundtrip_chirp_freq.npz +0 -0
  57. pywavelet-0.2.5/tests/test_data/roundtrip_sine_freq.npz +0 -0
  58. pywavelet-0.2.5/tests/test_data/roundtrip_sine_time.npz +0 -0
  59. pywavelet-0.2.5/tests/test_jax.py +0 -105
  60. pywavelet-0.2.5/tests/test_roundtrip_conversion.py +0 -124
  61. pywavelet-0.2.5/tests/utils/__init__.py +0 -2
  62. pywavelet-0.2.5/tests/utils/generate_data.py +0 -59
  63. {pywavelet-0.2.5 → pywavelet-0.2.6}/.gitignore +0 -0
  64. {pywavelet-0.2.5 → pywavelet-0.2.6}/CITATION.cff +0 -0
  65. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/_config.yml +0 -0
  66. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/_static/demo.gif +0 -0
  67. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/api.rst +0 -0
  68. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/index.rst +0 -0
  69. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/logo.png +0 -0
  70. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/roundtrip_freq.png +0 -0
  71. {pywavelet-0.2.5 → pywavelet-0.2.6}/docs/roundtrip_time.png +0 -0
  72. {pywavelet-0.2.5 → pywavelet-0.2.6}/setup.cfg +0 -0
  73. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/logger.py +0 -0
  74. {pywavelet-0.2.5/src/pywavelet/transforms/jax → pywavelet-0.2.6/src/pywavelet/transforms/cupy}/forward/__init__.py +0 -0
  75. {pywavelet-0.2.5/src/pywavelet/transforms/jax → pywavelet-0.2.6/src/pywavelet/transforms/cupy}/inverse/__init__.py +0 -0
  76. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/__init__.py +0 -0
  77. {pywavelet-0.2.5/src/pywavelet/transforms/numpy → pywavelet-0.2.6/src/pywavelet/transforms/jax}/forward/__init__.py +0 -0
  78. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/forward/from_time.py +0 -0
  79. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/jax/forward/main.py +0 -0
  80. {pywavelet-0.2.5/src/pywavelet/transforms/numpy → pywavelet-0.2.6/src/pywavelet/transforms/jax}/inverse/__init__.py +0 -0
  81. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/__init__.py +0 -0
  82. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/forward/from_time.py +0 -0
  83. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/transforms/numpy/inverse/to_time.py +0 -0
  84. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/__init__.py +0 -0
  85. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/common.py +0 -0
  86. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/frequencyseries.py +0 -0
  87. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/timeseries.py +0 -0
  88. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/types/wavelet_bins.py +0 -0
  89. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet/utils.py +0 -0
  90. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/dependency_links.txt +0 -0
  91. {pywavelet-0.2.5 → pywavelet-0.2.6}/src/pywavelet.egg-info/top_level.txt +0 -0
  92. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_data/roundtrip_chirp_time.npz +0 -0
  93. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_data/roundtrip_pure_f0_freq.npz +0 -0
  94. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_lnl.py +0 -0
  95. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_mask.py +0 -0
  96. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_psd.py +0 -0
  97. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_snr.py +0 -0
  98. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_timefreq_type.py +0 -0
  99. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_version.py +0 -0
  100. {pywavelet-0.2.5 → pywavelet-0.2.6}/tests/test_wavelet_plot.py +0 -0
@@ -20,7 +20,7 @@ jobs:
20
20
 
21
21
  - uses: actions/setup-python@v5
22
22
  with:
23
- python-version: '3.8'
23
+ python-version: '3.10'
24
24
  cache: 'pip' # Enable caching for pip dependencies
25
25
 
26
26
 
@@ -21,7 +21,7 @@ jobs:
21
21
 
22
22
  - uses: actions/setup-python@v5
23
23
  with:
24
- python-version: '3.8'
24
+ python-version: '3.10'
25
25
  cache: 'pip' # Enable caching for pip dependencies
26
26
 
27
27
  - run: python -m pip install -e .[dev]
@@ -27,7 +27,7 @@ jobs:
27
27
 
28
28
  - uses: actions/setup-python@v5
29
29
  with:
30
- python-version: '3.8'
30
+ python-version: '3.10'
31
31
  cache: 'pip' # Enable caching for pip dependencies
32
32
 
33
33
 
@@ -1,22 +1,19 @@
1
1
  repos:
2
2
  - repo: https://github.com/pre-commit/pre-commit-hooks
3
- rev: v4.5.0
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/pre-commit/mirrors-isort
11
- rev: v5.10.1
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: "23.10.0"
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
1
+ Metadata-Version: 2.4
2
2
  Name: pywavelet
3
- Version: 0.2.5
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.8
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 the latest version of python.
74
+ First set up a conda environment with python 3.10
66
75
 
67
76
  .. code-block::
68
77
 
69
- $ conda create -n pywavelet -c conda-forge python=3.12
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 the latest version of python.
32
+ First set up a conda environment with python 3.10
29
33
 
30
34
  .. code-block::
31
35
 
32
- $ conda create -n pywavelet -c conda-forge python=3.12
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
 
@@ -8,6 +8,7 @@ parts:
8
8
  chapters:
9
9
  - file: api.rst
10
10
  - file: example.ipynb
11
+ - file: runtime.ipynb
11
12
  - caption: Case Studies
12
13
  chapters:
13
14
  - url: https://www.youtube.com/watch?v=dQw4w9WgXcQ&themeRefresh=1
@@ -4,7 +4,14 @@
4
4
  "cell_type": "markdown",
5
5
  "metadata": {},
6
6
  "source": [
7
- "# Examples \n",
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
+ }