Skip to main content

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.

License: MIT Python Version Rust Version

📖 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

🧪 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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests and ensure they pass
  5. Format your code (cargo fmt for Rust, black for Python)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

traj_dist_rs-0.1.0a2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (392.5 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

traj_dist_rs-0.1.0a2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (392.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

traj_dist_rs-0.1.0a2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (395.0 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

traj_dist_rs-0.1.0a2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (394.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

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

File hashes

Hashes for traj_dist_rs-0.1.0a2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d8daf5bf226855d34e6b50450aca4fc94c3f0b5af6b6acdffbb90feb310660a8
MD5 d7db01dbca992d3845bde33c3911e804
BLAKE2b-256 394974c6ad459b660112182f1767d4c124661056532c0b6e0775c4ef256825ec

See more details on using hashes here.

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

File hashes

Hashes for traj_dist_rs-0.1.0a2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fde1fd2039f7e373af1579199dd80fa07775d66a802e9027895d10671911dc0e
MD5 e2f1c7839513a72e7b66fcc7d497ce78
BLAKE2b-256 8b75e4b1d84c8c227be0e4e6635f68cbe6614c610181c4e684849bb1951e9ffe

See more details on using hashes here.

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

File hashes

Hashes for traj_dist_rs-0.1.0a2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4f9dcb17f797eae386b0645e27fb70ff1360dd906f32f29321719424cd166d5e
MD5 7a7db45c53b646e761ed41174419d4ea
BLAKE2b-256 7a81213bd2c53cea180b315805120faca6d262c7a8db0404ec69cd86936547cc

See more details on using hashes here.

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

File hashes

Hashes for traj_dist_rs-0.1.0a2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 92ab489886d50d8fa62ebb37ead071e83b405dea159480162183f7b64bd2b1c5
MD5 9bfc1344dcf66cb809d30b1c11b9635a
BLAKE2b-256 c5df45016e4efd21d0e9d8b4553bd00fbeb175bb78e361ab0d0f0871be2ce3fc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page