wavelet-matrix 2.0.7__tar.gz → 2.0.9__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 (39) hide show
  1. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/.github/workflows/CI.yml +39 -40
  2. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/Cargo.lock +9 -9
  3. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/Cargo.toml +1 -1
  4. wavelet_matrix-2.0.9/PKG-INFO +212 -0
  5. wavelet_matrix-2.0.9/README.md +175 -0
  6. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/docs/wavelet_matrix.html +146 -472
  7. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/pyproject.toml +0 -4
  8. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/dynamic_wavelet_matrix/dynamic_bit_vector.rs +2 -2
  9. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/dynamic_wavelet_matrix/dynamic_wavelet_matrix.rs +18 -12
  10. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/lib.rs +1 -0
  11. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/python/dynamic_wavelet_matrix.rs +75 -221
  12. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/python/wavelet_matrix.rs +63 -154
  13. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/wavelet_matrix/bit_vector.rs +22 -6
  14. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/wavelet_matrix/wavelet_matrix.rs +18 -12
  15. wavelet_matrix-2.0.7/PKG-INFO +0 -255
  16. wavelet_matrix-2.0.7/README.md +0 -214
  17. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/.gitignore +0 -0
  18. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/LICENSE +0 -0
  19. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/benchmarks/__init__.py +0 -0
  20. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/benchmarks/bench_dynamic_wavelet_matrix.py +0 -0
  21. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/benchmarks/bench_wavelet_matrix.py +0 -0
  22. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/docs/index.html +0 -0
  23. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/dynamic_wavelet_matrix/mod.rs +0 -0
  24. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/python/mod.rs +0 -0
  25. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/bit_vector/bit_vector.rs +0 -0
  26. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/bit_vector/dynamic_bit_vector.rs +0 -0
  27. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/bit_vector/mod.rs +0 -0
  28. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/mod.rs +0 -0
  29. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/utils/bit_select.rs +0 -0
  30. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/utils/bit_width.rs +0 -0
  31. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/utils/mod.rs +0 -0
  32. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/wavelet_matrix/dynamic_wavelet_matrix.rs +0 -0
  33. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/wavelet_matrix/mod.rs +0 -0
  34. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/traits/wavelet_matrix/wavelet_matrix.rs +0 -0
  35. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/src/wavelet_matrix/mod.rs +0 -0
  36. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/tests/__init__.py +0 -0
  37. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/tests/test_dynamic_wavelet_matrix.py +0 -0
  38. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/tests/test_wavelet_matrix.py +0 -0
  39. {wavelet_matrix-2.0.7 → wavelet_matrix-2.0.9}/wavelet_matrix.pyi +0 -0
@@ -9,7 +9,6 @@ on:
9
9
  push:
10
10
  branches:
11
11
  - main
12
- - master
13
12
  tags:
14
13
  - '*'
15
14
  pull_request:
@@ -25,21 +24,21 @@ jobs:
25
24
  strategy:
26
25
  matrix:
27
26
  platform:
28
- - runner: ubuntu-22.04
27
+ - runner: ubuntu-latest
29
28
  target: x86_64
30
- - runner: ubuntu-22.04
29
+ - runner: ubuntu-latest
31
30
  target: x86
32
- - runner: ubuntu-22.04
31
+ - runner: ubuntu-latest
33
32
  target: aarch64
34
- - runner: ubuntu-22.04
33
+ - runner: ubuntu-latest
35
34
  target: armv7
36
- - runner: ubuntu-22.04
35
+ - runner: ubuntu-latest
37
36
  target: s390x
38
- - runner: ubuntu-22.04
37
+ - runner: ubuntu-latest
39
38
  target: ppc64le
40
39
  steps:
41
- - uses: actions/checkout@v4
42
- - uses: actions/setup-python@v5
40
+ - uses: actions/checkout@v6
41
+ - uses: actions/setup-python@v6
43
42
  with:
44
43
  python-version: 3.x
45
44
  - name: Build wheels
@@ -50,7 +49,7 @@ jobs:
50
49
  sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
51
50
  manylinux: auto
52
51
  - name: Upload wheels
53
- uses: actions/upload-artifact@v4
52
+ uses: actions/upload-artifact@v6
54
53
  with:
55
54
  name: wheels-linux-${{ matrix.platform.target }}
56
55
  path: dist
@@ -61,17 +60,17 @@ jobs:
61
60
  strategy:
62
61
  matrix:
63
62
  platform:
64
- - runner: ubuntu-22.04
63
+ - runner: ubuntu-latest
65
64
  target: x86_64
66
- - runner: ubuntu-22.04
65
+ - runner: ubuntu-latest
67
66
  target: x86
68
- - runner: ubuntu-22.04
67
+ - runner: ubuntu-latest
69
68
  target: aarch64
70
- - runner: ubuntu-22.04
69
+ - runner: ubuntu-latest
71
70
  target: armv7
72
71
  steps:
73
- - uses: actions/checkout@v4
74
- - uses: actions/setup-python@v5
72
+ - uses: actions/checkout@v6
73
+ - uses: actions/setup-python@v6
75
74
  with:
76
75
  python-version: 3.x
77
76
  - name: Build wheels
@@ -82,7 +81,7 @@ jobs:
82
81
  sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
83
82
  manylinux: musllinux_1_2
84
83
  - name: Upload wheels
85
- uses: actions/upload-artifact@v4
84
+ uses: actions/upload-artifact@v6
86
85
  with:
87
86
  name: wheels-musllinux-${{ matrix.platform.target }}
88
87
  path: dist
@@ -98,8 +97,8 @@ jobs:
98
97
  - runner: windows-latest
99
98
  target: x86
100
99
  steps:
101
- - uses: actions/checkout@v4
102
- - uses: actions/setup-python@v5
100
+ - uses: actions/checkout@v6
101
+ - uses: actions/setup-python@v6
103
102
  with:
104
103
  python-version: 3.x
105
104
  architecture: ${{ matrix.platform.target }}
@@ -110,7 +109,7 @@ jobs:
110
109
  args: --release --out dist --find-interpreter
111
110
  sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
112
111
  - name: Upload wheels
113
- uses: actions/upload-artifact@v4
112
+ uses: actions/upload-artifact@v6
114
113
  with:
115
114
  name: wheels-windows-${{ matrix.platform.target }}
116
115
  path: dist
@@ -121,13 +120,13 @@ jobs:
121
120
  strategy:
122
121
  matrix:
123
122
  platform:
124
- - runner: macos-14
123
+ - runner: macos-latest
125
124
  target: x86_64
126
- - runner: macos-14
125
+ - runner: macos-latest
127
126
  target: aarch64
128
127
  steps:
129
- - uses: actions/checkout@v4
130
- - uses: actions/setup-python@v5
128
+ - uses: actions/checkout@v6
129
+ - uses: actions/setup-python@v6
131
130
  with:
132
131
  python-version: 3.x
133
132
  - name: Build wheels
@@ -137,7 +136,7 @@ jobs:
137
136
  args: --release --out dist --find-interpreter
138
137
  sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
139
138
  - name: Upload wheels
140
- uses: actions/upload-artifact@v4
139
+ uses: actions/upload-artifact@v6
141
140
  with:
142
141
  name: wheels-macos-${{ matrix.platform.target }}
143
142
  path: dist
@@ -146,8 +145,8 @@ jobs:
146
145
  needs: [cargo-test, python-test]
147
146
  runs-on: ubuntu-latest
148
147
  steps:
149
- - uses: actions/checkout@v4
150
- - uses: actions/setup-python@v5
148
+ - uses: actions/checkout@v6
149
+ - uses: actions/setup-python@v6
151
150
  with:
152
151
  python-version: 3.x
153
152
  - name: Build sdist
@@ -156,15 +155,15 @@ jobs:
156
155
  command: sdist
157
156
  args: --out dist
158
157
  - name: Upload sdist
159
- uses: actions/upload-artifact@v4
158
+ uses: actions/upload-artifact@v6
160
159
  with:
161
160
  name: wheels-sdist
162
161
  path: dist
163
162
 
164
163
  cargo-test:
165
- runs-on: ubuntu-22.04
164
+ runs-on: ubuntu-latest
166
165
  steps:
167
- - uses: actions/checkout@v4
166
+ - uses: actions/checkout@v6
168
167
  - uses: dtolnay/rust-toolchain@stable
169
168
  with:
170
169
  components: clippy
@@ -188,14 +187,14 @@ jobs:
188
187
  token: ${{ secrets.CODECOV_TOKEN }}
189
188
 
190
189
  python-test:
191
- runs-on: ubuntu-22.04
190
+ runs-on: ubuntu-latest
192
191
  steps:
193
- - uses: actions/checkout@v4
194
- - uses: actions/setup-python@v5
192
+ - uses: actions/checkout@v6
193
+ - uses: actions/setup-python@v6
195
194
  with:
196
195
  python-version: 3.x
197
196
  - name: Install packages
198
- run: python -m pip install -e .[dev]
197
+ run: python -m pip install -e .[test,dev]
199
198
  - name: Run tests
200
199
  run: pytest --benchmark-skip
201
200
  - name: Docs check
@@ -205,7 +204,7 @@ jobs:
205
204
  --no-search \
206
205
  --no-show-source \
207
206
  --docformat markdown \
208
- --footer-text "© 2025 Koki Watanabe"
207
+ --footer-text "© 2026 Koki Watanabe"
209
208
  if ! git diff --exit-code -- docs; then
210
209
  echo "::error::Docs are out of date. Please run pdoc and commit generated docs."
211
210
  exit 1
@@ -214,7 +213,7 @@ jobs:
214
213
  run: ruff check
215
214
 
216
215
  python-benchmark:
217
- runs-on: ubuntu-22.04
216
+ runs-on: ubuntu-latest
218
217
  strategy:
219
218
  fail-fast: false
220
219
  matrix:
@@ -227,8 +226,8 @@ jobs:
227
226
  - "3.14"
228
227
  - "pypy3.11"
229
228
  steps:
230
- - uses: actions/checkout@v4
231
- - uses: actions/setup-python@v5
229
+ - uses: actions/checkout@v6
230
+ - uses: actions/setup-python@v6
232
231
  with:
233
232
  python-version: ${{ matrix.python }}
234
233
  - name: Install packages
@@ -251,9 +250,9 @@ jobs:
251
250
  # Used to generate artifact attestation
252
251
  attestations: write
253
252
  steps:
254
- - uses: actions/download-artifact@v4
253
+ - uses: actions/download-artifact@v7
255
254
  - name: Generate artifact attestation
256
- uses: actions/attest-build-provenance@v2
255
+ uses: actions/attest-build-provenance@v3
257
256
  with:
258
257
  subject-path: 'wheels-*/*'
259
258
  - name: Publish to PyPI
@@ -25,9 +25,9 @@ dependencies = [
25
25
 
26
26
  [[package]]
27
27
  name = "libc"
28
- version = "0.2.179"
28
+ version = "0.2.180"
29
29
  source = "registry+https://github.com/rust-lang/crates.io-index"
30
- checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f"
30
+ checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
31
31
 
32
32
  [[package]]
33
33
  name = "memoffset"
@@ -80,9 +80,9 @@ checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
80
80
 
81
81
  [[package]]
82
82
  name = "proc-macro2"
83
- version = "1.0.104"
83
+ version = "1.0.105"
84
84
  source = "registry+https://github.com/rust-lang/crates.io-index"
85
- checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
85
+ checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7"
86
86
  dependencies = [
87
87
  "unicode-ident",
88
88
  ]
@@ -152,9 +152,9 @@ dependencies = [
152
152
 
153
153
  [[package]]
154
154
  name = "quote"
155
- version = "1.0.42"
155
+ version = "1.0.43"
156
156
  source = "registry+https://github.com/rust-lang/crates.io-index"
157
- checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
157
+ checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
158
158
  dependencies = [
159
159
  "proc-macro2",
160
160
  ]
@@ -167,9 +167,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
167
167
 
168
168
  [[package]]
169
169
  name = "syn"
170
- version = "2.0.113"
170
+ version = "2.0.114"
171
171
  source = "registry+https://github.com/rust-lang/crates.io-index"
172
- checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4"
172
+ checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
173
173
  dependencies = [
174
174
  "proc-macro2",
175
175
  "quote",
@@ -196,7 +196,7 @@ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
196
196
 
197
197
  [[package]]
198
198
  name = "wavelet-matrix"
199
- version = "2.0.7"
199
+ version = "2.0.9"
200
200
  dependencies = [
201
201
  "num-bigint",
202
202
  "num-integer",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "wavelet-matrix"
3
- version = "2.0.7"
3
+ version = "2.0.9"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -0,0 +1,212 @@
1
+ Metadata-Version: 2.4
2
+ Name: wavelet-matrix
3
+ Version: 2.0.9
4
+ Classifier: Intended Audience :: Developers
5
+ Classifier: Intended Audience :: Science/Research
6
+ Classifier: Intended Audience :: Information Technology
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Programming Language :: Python :: Implementation :: CPython
16
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
19
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
20
+ Classifier: Typing :: Typed
21
+ Requires-Dist: pdoc>=16.0 ; extra == 'dev'
22
+ Requires-Dist: ruff>=0.14 ; extra == 'dev'
23
+ Requires-Dist: pytest>=7.0 ; extra == 'test'
24
+ Requires-Dist: pytest-benchmark>=4.0 ; extra == 'test'
25
+ Provides-Extra: dev
26
+ Provides-Extra: test
27
+ License-File: LICENSE
28
+ Summary: High-performance indexed sequence data structure powered by Rust, supporting fast rank/select and range queries.
29
+ Keywords: wavelet matrix,data structure,algorithm,sequence index,rank,select,quantile,top-k,range query,dynamic update,indexing,succinct
30
+ Author: Koki Watanabe
31
+ Requires-Python: >=3.9
32
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
33
+ Project-URL: documentation, https://math-hiyoko.github.io/wavelet-matrix
34
+ Project-URL: homepage, https://github.com/math-hiyoko/wavelet-matrix
35
+ Project-URL: repository, https://github.com/math-hiyoko/wavelet-matrix
36
+
37
+ # Wavelet Matrix
38
+
39
+ [![CI](https://github.com/math-hiyoko/wavelet-matrix/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/math-hiyoko/wavelet-matrix/actions/workflows/CI.yml)
40
+ [![codecov](https://codecov.io/gh/math-hiyoko/wavelet-matrix/graph/badge.svg?token=TXBR7MF2CP)](https://codecov.io/gh/math-hiyoko/wavelet-matrix)
41
+ ![PyPI - Version](https://img.shields.io/pypi/v/wavelet-matrix)
42
+ ![PyPI - License](https://img.shields.io/pypi/l/wavelet-matrix)
43
+ ![PyPI - PythonVersion](https://img.shields.io/pypi/pyversions/wavelet-matrix)
44
+ ![PyPI - Implementation](https://img.shields.io/pypi/implementation/wavelet-matrix)
45
+ ![PyPI - Types](https://img.shields.io/pypi/types/wavelet-matrix)
46
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/wavelet-matrix?period=total&units=INTERNATIONAL_SYSTEM&left_color=GRAY&right_color=GREEN&left_text=PyPI%20downloads)](https://pepy.tech/projects/wavelet-matrix)
47
+ ![PyPI - Format](https://img.shields.io/pypi/format/wavelet-matrix)
48
+ ![Rust](https://img.shields.io/badge/powered%20by-Rust-orange)
49
+ ![Unsafe](https://img.shields.io/badge/unsafe-0-success)
50
+
51
+
52
+ High-performance Wavelet Matrix implementation powered by Rust,
53
+ supporting fast rank / select / range queries over indexed sequences
54
+
55
+ - PyPI: https://pypi.org/project/wavelet-matrix
56
+ - Document: https://math-hiyoko.github.io/wavelet-matrix
57
+ - Repository: https://github.com/math-hiyoko/wavelet-matrix
58
+
59
+ ## Features:
60
+ - Fast rank, select, quantile
61
+ - Rich range queries (freq / sum / top-k / min / max)
62
+ - Optional dynamic updates (insert / remove / update)
63
+ - Safe Rust (no unsafe)
64
+
65
+ ## Installation
66
+ ```bash
67
+ pip install wavelet-matrix
68
+ ```
69
+
70
+ ## WaveletMatrix
71
+ WaveletMatrix indexes a static sequence of integers,
72
+ enabling fast queries where runtime depends on bit-width, not data size.
73
+ ```python
74
+ from wavelet_matrix import WaveletMatrix
75
+
76
+ data = [5, 4, 5, 5, 2, 1, 5, 6, 1, 3, 5, 0]
77
+ wm = WaveletMatrix(data)
78
+ ```
79
+
80
+ ### Frequency Queries
81
+ #### Count occurrences (rank)
82
+ ```python
83
+ wm.rank(value=5, end=9)
84
+ # 4
85
+ ```
86
+
87
+ #### Find position (select)
88
+ ```python
89
+ wm.select(value=5, kth=4)
90
+ # 6
91
+ ```
92
+
93
+ ### Order Statistics
94
+ #### k-th smallest value (quantile)
95
+ ```python
96
+ wm.quantile(start=2, end=12, kth=8)
97
+ # 5
98
+ ```
99
+
100
+ ### Range Aggregation
101
+ #### Sum values (range_sum)
102
+ ```python
103
+ wm.range_sum(start=2, end=8)
104
+ # 24
105
+ ```
106
+
107
+ #### Count values in [lower, upper) (range_freq)
108
+ ```python
109
+ wm.range_freq(start=1, end=9, lower=4, upper=6)
110
+ # 4
111
+ ```
112
+
113
+ #### List values with counts (range_list)
114
+ ```python
115
+ wm.range_list(start=1, end=9, lower=4, upper=6)
116
+ # [{'value': 4, 'count': 1}, {'value': 5, 'count': 3}]
117
+ ```
118
+
119
+ ### Top-K Queries
120
+ #### Most frequent values (topk)
121
+ ```python
122
+ wm.topk(start=1, end=10, k=2)
123
+ # [{'value': 5, 'count': 3}, {'value': 1, 'count': 2}]
124
+ ```
125
+
126
+ #### Extreme values (range_maxk / range_mink)
127
+ ```python
128
+ wm.range_maxk(start=1, end=9, k=2)
129
+ # [{'value': 6, 'count': 1}, {'value': 5, 'count': 3}]
130
+ wm.range_mink(start=1, end=9, k=2)
131
+ # [{'value': 1, 'count': 2}, {'value': 2, 'count': 1}]
132
+ ```
133
+
134
+ ### Boundary Queries
135
+ ```python
136
+ wm.prev_value(start=1, end=9, upper=7)
137
+ # 6
138
+ wm.next_value(start=1, end=9, lower=4)
139
+ # 4
140
+ ```
141
+
142
+ ## DynamicWaveletMatrix
143
+ DynamicWaveletMatrix supports mutable sequences with insert/remove/update.
144
+
145
+ ### Trade-off:
146
+ - Higher overhead
147
+ - Values must fit within max_bit
148
+
149
+ ```python
150
+ from wavelet_matrix import DynamicWaveletMatrix
151
+
152
+ dwm = DynamicWaveletMatrix(data, max_bit=4)
153
+ ```
154
+
155
+ ### Insert
156
+ ```python
157
+ dwm.insert(index=4, value=8)
158
+ ```
159
+
160
+ #### Remove
161
+ ```python
162
+ dwm.remove(index=4)
163
+ ```
164
+
165
+ #### Update
166
+ ```python
167
+ dwm.update(index=4, value=5)
168
+ # or dwm[4] = 5
169
+ ```
170
+
171
+ ## Safety
172
+ - Powered by safe Rust
173
+ - Memory-safe by design
174
+
175
+ ## Development
176
+
177
+ ### Running Tests
178
+
179
+ ```bash
180
+ pip install -e ".[test]"
181
+ cargo test --all --release
182
+ pytest
183
+ ```
184
+
185
+ ### Formating Code
186
+ ```bash
187
+ pip install -e ".[dev]"
188
+ cargo fmt
189
+ ruff format
190
+ ```
191
+
192
+ ### Generating Docs
193
+ ```bash
194
+ pdoc wavelet_matrix \
195
+ --output-directory docs \
196
+ --no-search \
197
+ --no-show-source \
198
+ --docformat markdown \
199
+ --footer-text "© 2026 Koki Watanabe"
200
+ ```
201
+
202
+ ## References
203
+
204
+ - Francisco Claude, Gonzalo Navarro, Alberto Ordóñez,
205
+ The wavelet matrix: An efficient wavelet tree for large alphabets,
206
+ Information Systems,
207
+ Volume 47,
208
+ 2015,
209
+ Pages 15-32,
210
+ ISSN 0306-4379,
211
+ https://doi.org/10.1016/j.is.2014.06.002.
212
+
@@ -0,0 +1,175 @@
1
+ # Wavelet Matrix
2
+
3
+ [![CI](https://github.com/math-hiyoko/wavelet-matrix/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/math-hiyoko/wavelet-matrix/actions/workflows/CI.yml)
4
+ [![codecov](https://codecov.io/gh/math-hiyoko/wavelet-matrix/graph/badge.svg?token=TXBR7MF2CP)](https://codecov.io/gh/math-hiyoko/wavelet-matrix)
5
+ ![PyPI - Version](https://img.shields.io/pypi/v/wavelet-matrix)
6
+ ![PyPI - License](https://img.shields.io/pypi/l/wavelet-matrix)
7
+ ![PyPI - PythonVersion](https://img.shields.io/pypi/pyversions/wavelet-matrix)
8
+ ![PyPI - Implementation](https://img.shields.io/pypi/implementation/wavelet-matrix)
9
+ ![PyPI - Types](https://img.shields.io/pypi/types/wavelet-matrix)
10
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/wavelet-matrix?period=total&units=INTERNATIONAL_SYSTEM&left_color=GRAY&right_color=GREEN&left_text=PyPI%20downloads)](https://pepy.tech/projects/wavelet-matrix)
11
+ ![PyPI - Format](https://img.shields.io/pypi/format/wavelet-matrix)
12
+ ![Rust](https://img.shields.io/badge/powered%20by-Rust-orange)
13
+ ![Unsafe](https://img.shields.io/badge/unsafe-0-success)
14
+
15
+
16
+ High-performance Wavelet Matrix implementation powered by Rust,
17
+ supporting fast rank / select / range queries over indexed sequences
18
+
19
+ - PyPI: https://pypi.org/project/wavelet-matrix
20
+ - Document: https://math-hiyoko.github.io/wavelet-matrix
21
+ - Repository: https://github.com/math-hiyoko/wavelet-matrix
22
+
23
+ ## Features:
24
+ - Fast rank, select, quantile
25
+ - Rich range queries (freq / sum / top-k / min / max)
26
+ - Optional dynamic updates (insert / remove / update)
27
+ - Safe Rust (no unsafe)
28
+
29
+ ## Installation
30
+ ```bash
31
+ pip install wavelet-matrix
32
+ ```
33
+
34
+ ## WaveletMatrix
35
+ WaveletMatrix indexes a static sequence of integers,
36
+ enabling fast queries where runtime depends on bit-width, not data size.
37
+ ```python
38
+ from wavelet_matrix import WaveletMatrix
39
+
40
+ data = [5, 4, 5, 5, 2, 1, 5, 6, 1, 3, 5, 0]
41
+ wm = WaveletMatrix(data)
42
+ ```
43
+
44
+ ### Frequency Queries
45
+ #### Count occurrences (rank)
46
+ ```python
47
+ wm.rank(value=5, end=9)
48
+ # 4
49
+ ```
50
+
51
+ #### Find position (select)
52
+ ```python
53
+ wm.select(value=5, kth=4)
54
+ # 6
55
+ ```
56
+
57
+ ### Order Statistics
58
+ #### k-th smallest value (quantile)
59
+ ```python
60
+ wm.quantile(start=2, end=12, kth=8)
61
+ # 5
62
+ ```
63
+
64
+ ### Range Aggregation
65
+ #### Sum values (range_sum)
66
+ ```python
67
+ wm.range_sum(start=2, end=8)
68
+ # 24
69
+ ```
70
+
71
+ #### Count values in [lower, upper) (range_freq)
72
+ ```python
73
+ wm.range_freq(start=1, end=9, lower=4, upper=6)
74
+ # 4
75
+ ```
76
+
77
+ #### List values with counts (range_list)
78
+ ```python
79
+ wm.range_list(start=1, end=9, lower=4, upper=6)
80
+ # [{'value': 4, 'count': 1}, {'value': 5, 'count': 3}]
81
+ ```
82
+
83
+ ### Top-K Queries
84
+ #### Most frequent values (topk)
85
+ ```python
86
+ wm.topk(start=1, end=10, k=2)
87
+ # [{'value': 5, 'count': 3}, {'value': 1, 'count': 2}]
88
+ ```
89
+
90
+ #### Extreme values (range_maxk / range_mink)
91
+ ```python
92
+ wm.range_maxk(start=1, end=9, k=2)
93
+ # [{'value': 6, 'count': 1}, {'value': 5, 'count': 3}]
94
+ wm.range_mink(start=1, end=9, k=2)
95
+ # [{'value': 1, 'count': 2}, {'value': 2, 'count': 1}]
96
+ ```
97
+
98
+ ### Boundary Queries
99
+ ```python
100
+ wm.prev_value(start=1, end=9, upper=7)
101
+ # 6
102
+ wm.next_value(start=1, end=9, lower=4)
103
+ # 4
104
+ ```
105
+
106
+ ## DynamicWaveletMatrix
107
+ DynamicWaveletMatrix supports mutable sequences with insert/remove/update.
108
+
109
+ ### Trade-off:
110
+ - Higher overhead
111
+ - Values must fit within max_bit
112
+
113
+ ```python
114
+ from wavelet_matrix import DynamicWaveletMatrix
115
+
116
+ dwm = DynamicWaveletMatrix(data, max_bit=4)
117
+ ```
118
+
119
+ ### Insert
120
+ ```python
121
+ dwm.insert(index=4, value=8)
122
+ ```
123
+
124
+ #### Remove
125
+ ```python
126
+ dwm.remove(index=4)
127
+ ```
128
+
129
+ #### Update
130
+ ```python
131
+ dwm.update(index=4, value=5)
132
+ # or dwm[4] = 5
133
+ ```
134
+
135
+ ## Safety
136
+ - Powered by safe Rust
137
+ - Memory-safe by design
138
+
139
+ ## Development
140
+
141
+ ### Running Tests
142
+
143
+ ```bash
144
+ pip install -e ".[test]"
145
+ cargo test --all --release
146
+ pytest
147
+ ```
148
+
149
+ ### Formating Code
150
+ ```bash
151
+ pip install -e ".[dev]"
152
+ cargo fmt
153
+ ruff format
154
+ ```
155
+
156
+ ### Generating Docs
157
+ ```bash
158
+ pdoc wavelet_matrix \
159
+ --output-directory docs \
160
+ --no-search \
161
+ --no-show-source \
162
+ --docformat markdown \
163
+ --footer-text "© 2026 Koki Watanabe"
164
+ ```
165
+
166
+ ## References
167
+
168
+ - Francisco Claude, Gonzalo Navarro, Alberto Ordóñez,
169
+ The wavelet matrix: An efficient wavelet tree for large alphabets,
170
+ Information Systems,
171
+ Volume 47,
172
+ 2015,
173
+ Pages 15-32,
174
+ ISSN 0306-4379,
175
+ https://doi.org/10.1016/j.is.2014.06.002.