High-performance trajectory distance calculations in Rust with Python bindings
Project description
traj-dist-rs
A high-performance Rust implementation of trajectory distance algorithms with Python bindings, offering significant speed improvements over the original traj-dist library.
📖 About
traj-dist-rs is a high-performance trajectory distance calculation library written in Rust, providing both native Rust APIs and Python bindings via PyO3. It is a complete rewrite of the original traj-dist library, focusing on performance optimization and modern language features.
Why traj-dist-rs?
- 🚀 Performance: ~73x faster than Python implementation and ~2.7x faster than Cython implementation on average
- 🔒 Safety: Rust's memory safety guarantees eliminate common runtime errors
- 📦 Cross-platform: Supports Linux, macOS, and Windows with native binaries
- 🔗 Dual API: Use it from Python or Rust with minimal overhead
- 🎯 Accuracy: All algorithms verified against original implementation with < 1e-8 error margin
✨ Features
Supported Distance Algorithms
- SSPD - Symmetric Segment-Path Distance
- DTW - Dynamic Time Warping (with optional matrix return)
- Discret Frechet - Discrete Fréchet Distance
- Hausdorff - Hausdorff Distance
- LCSS - Longest Common Subsequence
- EDR - Edit Distance on Real sequence
- ERP - Edit distance with Real Penalty (standard & traj-dist compatible)
Distance Types
- Euclidean - 2D Euclidean distance
- Spherical - Haversine distance for geographic coordinates
Additional Features
- Matrix return for DP-based algorithms (DTW, LCSS, EDR, ERP, Discret Frechet)
- Precomputed distance matrix support for efficient batch computations
- Comprehensive error handling for invalid inputs
- Full Python type hints for better IDE support
🚀 Quick Start
Python
import traj_dist_rs
import numpy as np
# Define trajectories as list of [x, y] coordinates or numpy arrays
traj1 = [[0.0, 0.0], [1.0, 1.0], [2.0, 2.0]]
traj2 = [[0.1, 0.1], [1.1, 1.1], [2.1, 2.1]]
# Calculate SSPD distance
distance = traj_dist_rs.sspd(traj1, traj2, dist_type="euclidean")
print(f"SSPD distance: {distance}")
# Calculate DTW distance (returns DpResult with distance and optional matrix)
result = traj_dist_rs.dtw(traj1, traj2, dist_type="euclidean", use_full_matrix=False)
print(f"DTW distance: {result.distance}")
# Calculate Hausdorff distance
distance = traj_dist_rs.hausdorff(traj1, traj2, dist_type="spherical")
print(f"Hausdorff distance: {distance}")
Rust
use traj_dist_rs::distance::sspd::sspd;
use traj_dist_rs::distance::dtw::dtw;
use traj_dist_rs::distance::base::TrajectoryCalculator;
use traj_dist_rs::distance::distance_type::DistanceType;
fn main() {
let traj1 = vec![[0.0, 0.0], [1.0, 1.0], [2.0, 2.0]];
let traj2 = vec![[0.1, 0.1], [1.1, 1.1], [2.1, 2.1]];
// Calculate SSPD distance
let dist = sspd(&traj1, &traj2, DistanceType::Euclidean);
println!("SSPD distance: {}", dist);
// Calculate DTW distance
let calculator = TrajectoryCalculator::new(&traj1, &traj2, DistanceType::Euclidean);
let result = dtw(&calculator, false);
println!("DTW distance: {}", result.distance);
}
📦 Installation
From PyPI (Python)
pip install traj-dist-rs
From Source
Prerequisites:
- Rust 1.70 or later
- Python 3.10, 3.11, 3.12, or 3.13
- maturin
Build and install:
# Clone the repository
git clone <repository-url>
cd traj-dist-rs
# Install development dependencies
pip install maturin
# Build and install in development mode
maturin develop
# Or build a release wheel
maturin build --release
pip install target/wheels/*.whl
Rust-only build:
cargo build --release
📊 Performance
Compared to the original traj-dist implementation (based on median values from K=1000 trajectory pairs):
Overall Performance
| Implementation | Average Speedup |
|---|---|
| Rust vs Python | ~73x faster |
| Rust vs Cython | ~2.7x faster |
By Distance Type
Euclidean Distance:
- Rust vs Python: ~389x faster (range: 187x - 595x)
- Rust vs Cython: ~10x faster (range: 6x - 16x)
Spherical Distance:
- Rust vs Python: ~76x faster (range: 41x - 167x)
- Rust vs Cython: ~2.7x faster (range: 1.6x - 5.2x)
Best Performing Algorithms
Rust vs Cython (Euclidean):
- SSPD: 16.13x faster
- Hausdorff: 14.07x faster
- ERP: 12.03x faster
Rust vs Python (Euclidean):
- DTW: 595x faster
- Discret Frechet: 554x faster
- LCSS: 381x faster
For detailed performance analysis with statistics, see docs/performance.md.
📚 Documentation
- Installation Guide: docs/installation.md
- Usage Examples: docs/usage.md
- Python API: docs/api.md
- Rust API: docs/user_guide_rust.md
- Algorithm Details: docs/algorithms.md
- Performance Report: docs/performance.md
🧪 Testing
Python Tests
cd traj-dist-rs
pip install pytest numpy polars pyarrow
pytest py_tests/
Rust Tests
cd traj-dist-rs
cargo test
Integration Tests
Run comprehensive integration tests:
bash scripts/pre_build.sh
🤝 Contributing
We welcome contributions! Please see our contributing guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and ensure they pass
- Format your code (
cargo fmtfor Rust,blackfor Python) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Workflow
For daily development, use the pre-build script:
bash scripts/pre_build.sh
This script will:
- Format Rust and Python code
- Run linting (clippy, ruff)
- Run all tests (Rust + Python)
- Generate Python stub files
- Build Python bindings
🔧 Project Structure
traj-dist-rs/
├── src/
│ ├── distance/ # Distance algorithm implementations
│ ├── binding/ # Python bindings (PyO3)
│ └── lib.rs # Library entry point
├── tests/ # Rust integration tests
├── py_tests/ # Python integration tests
├── python/ # Python package source
├── docs/ # Documentation
└── scripts/ # Build and utility scripts
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Original traj-dist library for algorithm reference
- PyO3 for Python bindings
- The Rust community for excellent tooling and libraries
📮 Support
- Issues: Report bugs and request features via GitHub Issues
- Discussions: Join discussions about usage and development
- Documentation: Check the docs directory for detailed guides
🗺️ Roadmap
For information about upcoming features and releases, see roadmap_0.1.0a1.md.
Version: 0.1.0-alpha.1
Last Updated: 2026-02-05
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file traj_dist_rs-0.1.0a2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: traj_dist_rs-0.1.0a2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 392.5 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8daf5bf226855d34e6b50450aca4fc94c3f0b5af6b6acdffbb90feb310660a8
|
|
| MD5 |
d7db01dbca992d3845bde33c3911e804
|
|
| BLAKE2b-256 |
394974c6ad459b660112182f1767d4c124661056532c0b6e0775c4ef256825ec
|
File details
Details for the file traj_dist_rs-0.1.0a2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: traj_dist_rs-0.1.0a2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 392.9 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fde1fd2039f7e373af1579199dd80fa07775d66a802e9027895d10671911dc0e
|
|
| MD5 |
e2f1c7839513a72e7b66fcc7d497ce78
|
|
| BLAKE2b-256 |
8b75e4b1d84c8c227be0e4e6635f68cbe6614c610181c4e684849bb1951e9ffe
|
File details
Details for the file traj_dist_rs-0.1.0a2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: traj_dist_rs-0.1.0a2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 395.0 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f9dcb17f797eae386b0645e27fb70ff1360dd906f32f29321719424cd166d5e
|
|
| MD5 |
7a7db45c53b646e761ed41174419d4ea
|
|
| BLAKE2b-256 |
7a81213bd2c53cea180b315805120faca6d262c7a8db0404ec69cd86936547cc
|
File details
Details for the file traj_dist_rs-0.1.0a2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: traj_dist_rs-0.1.0a2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 394.1 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92ab489886d50d8fa62ebb37ead071e83b405dea159480162183f7b64bd2b1c5
|
|
| MD5 |
9bfc1344dcf66cb809d30b1c11b9635a
|
|
| BLAKE2b-256 |
c5df45016e4efd21d0e9d8b4553bd00fbeb175bb78e361ab0d0f0871be2ce3fc
|