[ANN] ChenSignatures.jl β€” Path signatures in Julia

Path signatures in Julia

I am excited to share ChenSignatures.jl, a Julia package for computing path signatures and log-signatures.

What are signatures? The signature of a path X : [0,T] \to \mathbb{R}^d is the sequence of iterated integrals:

S(X)_m = \left(1, \int_0^T dX_{t_1}, \int_0^T \int_0^{t_2} dX_{t_1} \otimes dX_{t_2}, \ldots, \int_0^T \int_0^{t_m} \cdots \int_0^{t_2} dX_{t_1} \otimes \cdots \otimes dX_{t_m}\right)

The k-th level is a tensor S^k(X) \in (\mathbb{R}^d)^{\otimes k} with components:

S^k(X)^{i_1 \ldots i_k} = \int_{0 < t_1 < \cdots < t_k < T} dX^{i_1}_{t_1} \cdots dX^{i_k}_{t_k}

This object uniquely characterizes the path up to tree-like equivalence and has applications in machine learning (time series classification, generative models) and mathematical finance (rough path pricing, expected signatures).

I got interested in signatures while working on derivatives pricing, where they provide a natural way to encode path-dependent payoffs. When I looked for Julia implementations, I found the ecosystem lacking β€” so I decided to build one.

Why another implementation?

Julia’s ecosystem lacked an actively maintained option β€” PathSignatures.jl has been dormant for 5 years. ChenSignatures.jl aims to fill this gap with:

  • Native Julia implementation with attention to performance (SIMD, StaticArrays)
  • AD support via Enzyme and ForwardDiff
  • Python interop through the chen-signatures wrapper

Benchmarks

Comparison against iisignature and pysiglib on signature computation:

Config (N, d, m) iisignature pysiglib ChenSignatures.jl chen-signatures (Python wrapper)
(200, 2, 4) 0.04 ms 0.12 ms 0.013 ms 0.07 ms
(1000, 2, 6) 0.62 ms 0.26 ms 0.19 ms 0.31 ms
(200, 10, 4) 6.2 ms 0.93 ms 0.57 ms 0.73 ms
(1000, 10, 4) 32 ms 3.2 ms 2.1 ms 3.1 ms
(1000, 10, 6) 8.1 s 1.0 s 0.83 s 0.94 s

N = path length, d = dimension, m = truncation depth.

Methodology: Each configuration was run twice with 5 repeats per measurement on the same machine. Times shown are conservative (slower of the two runs). Full results and scripts available at github.com/aleCombi/sig-benchmarks.

Quick start

using ChenSignatures, StaticArrays

# Path as vector of SVectors (recommended for performance)
path = [SVector(sin(t), cos(t)) for t in 0:0.01:1]

sig = signature(path, 4)      # Truncation depth 4
logsig = logsignature(path, 4)

Current status

  • Dense signatures and log-signatures (flattened vector representation): optimized and tested
  • Cross-validated against iisignature
  • AD support via Enzyme and ForwardDiff: tested on Julia 1.10 LTS
  • AD on Julia 1.12: experimental (Enzyme ecosystem still stabilizing)
  • Sparse tensors: experimental
  • Known issue: log-signature memory blowup at high depths in Python wrapper β€” investigating

Contributions

I am not accepting PRs at the moment (I have too many new features and ideas to test), but issues and discussions are welcome!

Links: Documentation Β· GitHub Β· Benchmarks

3 Likes