sig-light 0.2.4__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.
@@ -0,0 +1,52 @@
1
+ name: CICD
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ id-token: write
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
21
+ with:
22
+ persist-credentials: false
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+ enable-cache: true
29
+ cache-dependency-glob: |
30
+ **/pyproject.toml
31
+ **/uv.lock
32
+
33
+ - name: Install dependencies
34
+ run: uv sync --all-extras --group dev
35
+
36
+ - name: Lint
37
+ run: uv run ruff check .
38
+
39
+ - name: Format check
40
+ run: uv run ruff format --check .
41
+
42
+ - name: Type check
43
+ run: uv run ty check
44
+
45
+ - name: Run tests with coverage
46
+ run: uv run pytest -v --cov=src --cov-report=term-missing --cov-report=xml tests/
47
+
48
+ - name: Upload coverage reports to Codecov
49
+ if: matrix.python-version == '3.14'
50
+ uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
51
+ with:
52
+ token: ${{ secrets.CODECOV_TOKEN }}
@@ -0,0 +1,37 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v*
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ environment: pypi
12
+ permissions:
13
+ id-token: write
14
+ contents: read
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
18
+ with:
19
+ persist-credentials: false
20
+
21
+ - name: Install uv
22
+ uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
23
+ with:
24
+ python-version: "3.13"
25
+ enable-cache: false
26
+
27
+ - name: Build
28
+ run: uv build
29
+
30
+ - name: Smoke test (wheel)
31
+ run: uv run --isolated --no-project --with dist/*.whl -- python -c "import sig_light; print(sig_light.version())"
32
+
33
+ - name: Smoke test (sdist)
34
+ run: uv run --isolated --no-project --with dist/*.tar.gz -- python -c "import sig_light; print(sig_light.version())"
35
+
36
+ - name: Publish
37
+ run: uv publish
@@ -0,0 +1,185 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+ .python-version
29
+
30
+ # PyInstaller
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+ .coverage
43
+ .coverage.*
44
+ .cache
45
+ nosetests.xml
46
+ coverage.xml
47
+ *.cover
48
+ *.py.cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+ cover/
52
+
53
+ # Translations
54
+ *.mo
55
+ *.pot
56
+
57
+ # Django stuff:
58
+ *.log
59
+ local_settings.py
60
+ db.sqlite3
61
+ db.sqlite3-journal
62
+
63
+ # Flask stuff:
64
+ instance/
65
+ .webassets-cache
66
+
67
+ # Scrapy stuff:
68
+ .scrapy
69
+
70
+ # Sphinx documentation
71
+ docs/_build/
72
+
73
+ # PyBuilder
74
+ .pybuilder/
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ # .python-version
86
+
87
+ # pipenv
88
+ # Pipfile.lock
89
+
90
+ # UV
91
+ # uv.lock
92
+
93
+ # poetry
94
+ # poetry.lock
95
+ # poetry.toml
96
+
97
+ # pdm
98
+ # pdm.lock
99
+ # pdm.toml
100
+ .pdm-python
101
+ .pdm-build/
102
+
103
+ # pixi
104
+ # pixi.lock
105
+ .pixi
106
+
107
+ # PEP 582
108
+ __pypackages__/
109
+
110
+ # Celery stuff
111
+ celerybeat-schedule
112
+ celerybeat.pid
113
+
114
+ # Redis
115
+ *.rdb
116
+ *.aof
117
+ *.pid
118
+
119
+ # RabbitMQ
120
+ mnesia/
121
+ rabbitmq/
122
+ rabbitmq-data/
123
+
124
+ # ActiveMQ
125
+ activemq-data/
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .envrc
133
+ .venv
134
+ env/
135
+ venv/
136
+ ENV/
137
+ env.bak/
138
+ venv.bak/
139
+
140
+ # Spyder project settings
141
+ .spyderproject
142
+ .spyproject
143
+
144
+ # Rope project settings
145
+ .ropeproject
146
+
147
+ # mkdocs documentation
148
+ /site
149
+
150
+ # mypy
151
+ .mypy_cache/
152
+ .dmypy.json
153
+ dmypy.json
154
+
155
+ # Pyre type checker
156
+ .pyre/
157
+
158
+ # pytype static type analyzer
159
+ .pytype/
160
+
161
+ # Cython debug symbols
162
+ cython_debug/
163
+
164
+ # PyCharm
165
+ # .idea/
166
+
167
+ # Abstra
168
+ .abstra/
169
+
170
+ # Visual Studio Code
171
+ # .vscode/
172
+
173
+ # Ruff stuff:
174
+ .ruff_cache/
175
+
176
+ # PyPI configuration file
177
+ .pypirc
178
+
179
+ # Marimo
180
+ marimo/_static/
181
+ marimo/_lsp/
182
+ __marimo__/
183
+
184
+ # Streamlit
185
+ .streamlit/secrets.toml
@@ -0,0 +1,58 @@
1
+ # CLAUDE.md
2
+
3
+ ## Project Overview
4
+
5
+ sig-light is a pure-Python library for computing path signatures and log signatures of multidimensional time series. It mirrors the iisignature API using Chen's identity over piecewise-linear paths with truncated tensor algebra operations. No C extensions — numpy only.
6
+
7
+ ## Key Commands
8
+
9
+ ```bash
10
+ just sync # Install dependencies
11
+ just test # Run all tests
12
+ just test-cov # Run tests with coverage
13
+ just check # Run all code quality checks (lint + format + typecheck)
14
+ just lint # Run ruff check
15
+ just format # Auto-format code
16
+ just typecheck # Run ty check
17
+ just bench # Run benchmark
18
+ ```
19
+
20
+ ## Architecture
21
+
22
+ ### Core Algorithm
23
+
24
+ - Signature via Chen's identity: segment signatures (truncated exp) composed via tensor multiplication
25
+ - Log signature via "S" method: compute signature, take tensor logarithm, project to Lyndon basis
26
+ - Backpropagation via adjoint operations on tensor algebra primitives
27
+ - All tensor algebra operations work on "level-lists": list of m arrays, level[k] has shape (d^(k+1),)
28
+ - Batched operations use einsum for vectorized computation across segments
29
+
30
+ ### File Structure
31
+
32
+ ```
33
+ src/sig_light/
34
+ __init__.py # Public API re-exports, version()
35
+ algebra.py # Tensor algebra: multiply, exp, log, adjoints, batched ops
36
+ signature.py # sig(), siglength(), sigcombine(), format=2, batching
37
+ logsignature.py # logsig(), logsiglength(), prepare(), basis(), batching
38
+ backprop.py # sigbackprop(), sigjacobian(), logsigbackprop()
39
+ transforms.py # sigjoin(), sigscale() + backprop variants
40
+ lyndon.py # Lyndon word generation, bracketing, basis construction
41
+ rotational.py # rotinv2d functions for 2D rotation-invariant features
42
+ ```
43
+
44
+ ### Key Types
45
+
46
+ - **Level-list**: `list[NDArray]` of length m, representing truncated tensor algebra element (implicit 1 or 0 at level 0 depending on context)
47
+ - **PreparedData**: frozen dataclass from `prepare()`, holds precomputed Lyndon basis info
48
+ - **RotInv2DPreparedData**: frozen dataclass for rotation invariant computation
49
+ - **Flat signature**: 1D ndarray of length `siglength(d, m)`, levels 1..m concatenated
50
+
51
+ ## Dependencies
52
+
53
+ - numpy >= 2.0 (core computation)
54
+ - Dev: ruff, ty, pytest, pytest-cov
55
+
56
+ ## API Compatibility
57
+
58
+ Mirrors iisignature API. Signature does NOT include level 0 ("1") — starts from level 1, matching iisignature convention. All public functions support batching via extra leading dimensions.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yousif Toama
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: sig-light
3
+ Version: 0.2.4
4
+ Summary: Pure-Python path signature and log signature computation
5
+ License-Expression: MIT
6
+ License-File: LICENSE.md
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: numpy>=2.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ # sig-light
12
+
13
+ [![CICD](https://github.com/yousif-toama/sig-light/actions/workflows/cicd.yml/badge.svg)](https://github.com/yousif-toama/sig-light/actions/workflows/cicd.yml)
14
+ [![codecov](https://codecov.io/gh/yousif-toama/sig-light/graph/badge.svg)](https://codecov.io/gh/yousif-toama/sig-light)
15
+
16
+ Pure-Python path signature and log signature computation, mirroring the [iisignature](https://github.com/bottler/iisignature) API.
17
+
18
+ sig-light computes signatures and log signatures of multidimensional piecewise-linear paths using Chen's identity and truncated tensor algebra operations. No C extensions or compilation required — just numpy.
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install sig-light
24
+ ```
25
+
26
+ Or with uv:
27
+
28
+ ```bash
29
+ uv add sig-light
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```python
35
+ import numpy as np
36
+ import sig_light
37
+
38
+ # Define a 2D path
39
+ path = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]])
40
+
41
+ # Compute signature at depth 3
42
+ signature = sig_light.sig(path, 3)
43
+
44
+ # Compute log signature
45
+ s = sig_light.prepare(2, 3)
46
+ log_signature = sig_light.logsig(path, s)
47
+
48
+ # Backpropagation
49
+ deriv = np.ones_like(signature)
50
+ grad = sig_light.sigbackprop(deriv, path, 3) # gradient w.r.t. path
51
+
52
+ # Batching: process multiple paths at once
53
+ paths = np.random.randn(10, 50, 2) # 10 paths, 50 points, 2D
54
+ sigs = sig_light.sig(paths, 3) # shape (10, siglength(2, 3))
55
+ ```
56
+
57
+ ## API Reference
58
+
59
+ ### Signature
60
+
61
+ #### `sig(path, m, format=0)`
62
+
63
+ Compute the signature of a path truncated at depth `m`.
64
+
65
+ - **path**: numpy array of shape `(..., n, d)`. Extra leading dims are batched.
66
+ - **m**: truncation depth (positive integer).
67
+ - **format**: output format.
68
+ - `0`: flat array of shape `(..., siglength(d, m))`.
69
+ - `1`: list of `m` arrays, one per level.
70
+ - `2`: cumulative prefix signatures, shape `(..., n-1, siglength(d, m))`.
71
+ - **Returns**: the path signature, excluding the level-0 term (always 1).
72
+
73
+ #### `siglength(d, m)`
74
+
75
+ Length of the signature output: `d + d^2 + ... + d^m`.
76
+
77
+ #### `sigcombine(sig1, sig2, d, m)`
78
+
79
+ Combine two signatures via Chen's identity. Supports batching.
80
+
81
+ ### Backpropagation
82
+
83
+ #### `sigbackprop(deriv, path, m)`
84
+
85
+ Compute gradient of a loss w.r.t. the path, given gradient w.r.t. the signature.
86
+
87
+ - **deriv**: shape `(..., siglength(d, m))`.
88
+ - **path**: shape `(..., n, d)`.
89
+ - **Returns**: shape `(..., n, d)`.
90
+
91
+ #### `sigjacobian(path, m)`
92
+
93
+ Full Jacobian matrix of `sig()` w.r.t. the path.
94
+
95
+ - **Returns**: shape `(n, d, siglength(d, m))`.
96
+
97
+ #### `logsigbackprop(deriv, path, s)`
98
+
99
+ Compute gradient of a loss w.r.t. the path, given gradient w.r.t. the log signature.
100
+
101
+ - **deriv**: shape `(..., logsiglength(d, m))`.
102
+ - **path**: shape `(..., n, d)`.
103
+ - **s**: prepared data from `prepare(d, m)`.
104
+ - **Returns**: shape `(..., n, d)`.
105
+
106
+ ### Log Signature
107
+
108
+ #### `prepare(d, m)`
109
+
110
+ Precompute data for log signature computation.
111
+
112
+ #### `logsig(path, s)`
113
+
114
+ Compute the log signature in the Lyndon basis. Supports batching.
115
+
116
+ #### `logsig_expanded(path, s)`
117
+
118
+ Compute the log signature in the full tensor expansion. Supports batching.
119
+
120
+ #### `logsiglength(d, m)`
121
+
122
+ Length of the log signature output (Witt's formula).
123
+
124
+ #### `basis(s)`
125
+
126
+ Get the Lyndon bracket labels for the log signature basis elements.
127
+
128
+ ### Transforms
129
+
130
+ #### `sigjoin(sig, segment, d, m, fixedLast=nan)`
131
+
132
+ Extend a signature by appending a linear segment. Equivalent to `sigcombine(sig, sig_of_segment(segment), d, m)`.
133
+
134
+ #### `sigjoinbackprop(deriv, sig, segment, d, m, fixedLast=nan)`
135
+
136
+ Gradient through `sigjoin`. Returns `(dsig, dsegment)` or `(dsig, dsegment, dfixedLast)`.
137
+
138
+ #### `sigscale(sig, scales, d, m)`
139
+
140
+ Rescale a signature as if each path dimension were multiplied by a factor. At level k, the multi-index `(i1,...,ik)` component is multiplied by `scales[i1] * ... * scales[ik]`.
141
+
142
+ #### `sigscalebackprop(deriv, sig, scales, d, m)`
143
+
144
+ Gradient through `sigscale`. Returns `(dsig, dscales)`.
145
+
146
+ ### Rotation Invariants (2D paths)
147
+
148
+ #### `rotinv2dprepare(m, type="a")`
149
+
150
+ Precompute rotation-invariant features for 2D paths.
151
+
152
+ - **m**: depth (should be even).
153
+ - **type**: `"a"` for all invariants.
154
+
155
+ #### `rotinv2d(path, s)`
156
+
157
+ Compute rotation-invariant features of a 2D path signature.
158
+
159
+ #### `rotinv2dlength(s)` / `rotinv2dcoeffs(s)`
160
+
161
+ Get the number of invariants and their coefficient matrices.
162
+
163
+ ### Utility
164
+
165
+ #### `version()`
166
+
167
+ Return the sig-light version string.
168
+
169
+ ## Algorithm
170
+
171
+ sig-light uses the standard approach for computing signatures of piecewise-linear paths:
172
+
173
+ 1. **Segment signature**: for each linear segment with displacement `h`, the signature is the truncated exponential `exp(h) = 1 + h + h^2/2! + h^3/3! + ...` in the tensor algebra.
174
+
175
+ 2. **Chen's identity**: the signature of a concatenated path equals the tensor product of the individual segment signatures: `S(path) = S(seg_1) * S(seg_2) * ... * S(seg_n)`.
176
+
177
+ 3. **Log signature**: computed by taking the tensor logarithm `log(S) = (S-1) - (S-1)^2/2 + (S-1)^3/3 - ...` and projecting onto the Lyndon word basis.
178
+
179
+ 4. **Backpropagation**: reverse-mode differentiation through the Chen's identity chain using adjoint operations on the tensor algebra.
180
+
181
+ This approach is exact for piecewise-linear paths (no numerical approximation from ODE solvers).
182
+
183
+ ## Comparison with iisignature
184
+
185
+ | Feature | sig-light | iisignature |
186
+ |---|---|---|
187
+ | Language | Pure Python + numpy | C++ with Python bindings |
188
+ | Installation | `pip install` (no compilation) | Requires C++ compiler |
189
+ | Performance | Slower (~7-25x for sig) | Faster |
190
+ | API | Full parity | Full |
191
+ | Backpropagation | Yes | Yes |
192
+ | Batching | Yes | Yes |
193
+ | Rotation invariants | Yes (type "a") | Yes (types a/s/q/k) |
194
+
195
+ sig-light implements the full iisignature API with an identical interface. It trades performance for portability and simplicity.
196
+
197
+ ## Development
198
+
199
+ Requires [just](https://github.com/casey/just) for task running.
200
+
201
+ ```bash
202
+ # Clone and install
203
+ git clone https://github.com/yousif-toama/sig-light.git
204
+ cd sig-light
205
+ just sync
206
+
207
+ # Run tests
208
+ just test
209
+
210
+ # Code quality (lint + format check + type check)
211
+ just check
212
+
213
+ # Run tests with coverage
214
+ just test-cov
215
+
216
+ # Run benchmark
217
+ just bench
218
+
219
+ # Install iisignature for cross-validation testing (requires C++ compiler)
220
+ uv pip install setuptools
221
+ uv pip install iisignature --no-build-isolation
222
+ uv run pytest tests/test_api_compat.py
223
+ ```
224
+
225
+ ## License
226
+
227
+ MIT