apex-solver 1.3.0

High-performance nonlinear least squares optimization with Lie group support for SLAM and bundle adjustment
Documentation
# Performance Benchmarks

**Hardware**: Apple Mac Mini M4, 64GB RAM  
**Methodology**: Average over multiple runs

## Pose Graph Optimization

Performance comparison across 6 optimization libraries on standard pose graph datasets. All benchmarks use Levenberg-Marquardt algorithm with consistent parameters (max_iterations=100, cost_tolerance=1e-4).

**Metrics**: Wall-clock time (ms), iterations, initial/final cost, convergence status

### 2D Datasets (SE2)

| Dataset | Solver | Lang | Time (ms) | Iters | Init Cost | Final Cost | Improve % | Conv |
|---------|--------|------|-----------|-------|-----------|------------|-----------|------|
| **intel** (1228 vertices, 1483 edges) |
| | apex-solver | Rust | 28.5 | 12 | 3.68e4 | 3.89e-1 | 100.00 ||
| | factrs | Rust | 2.9 | - | 3.68e4 | 8.65e3 | 76.47 ||
| | tiny-solver | Rust | 87.9 | - | 1.97e4 | 4.56e3 | 76.91 ||
| | Ceres | C++ | 9.0 | 13 | 3.68e4 | 2.34e2 | 99.36 ||
| | g2o | C++ | 74.0 | 100 | 3.68e4 | 3.15e0 | 99.99 ||
| | GTSAM | C++ | 39.0 | 11 | 3.68e4 | 3.89e-1 | 100.00 ||
| **mit** (808 vertices, 827 edges) |
| | apex-solver | Rust | 140.7 | 107 | 1.63e5 | 1.10e2 | 99.93 ||
| | factrs | Rust | 3.5 | - | 1.63e5 | 1.48e4 | 90.91 ||
| | tiny-solver | Rust | 5.7 | - | 5.78e4 | 1.19e4 | 79.34 ||
| | Ceres | C++ | 11.0 | 29 | 1.63e5 | 3.49e2 | 99.79 ||
| | g2o | C++ | 46.0 | 100 | 1.63e5 | 1.26e3 | 99.23 ||
| | GTSAM | C++ | 39.0 | 4 | 1.63e5 | 8.33e4 | 48.94 ||
| **M3500** (3500 vertices, 5453 edges) |
| | apex-solver | Rust | 103.5 | 10 | 2.86e4 | 1.51e0 | 99.99 ||
| | factrs | Rust | 62.6 | - | 2.86e4 | 1.52e0 | 99.99 ||
| | tiny-solver | Rust | 200.1 | - | 3.65e4 | 2.86e4 | 21.67 ||
| | Ceres | C++ | 77.0 | 18 | 2.86e4 | 4.54e3 | 84.14 ||
| | g2o | C++ | 108.0 | 33 | 2.86e4 | 1.51e0 | 99.99 ||
| | GTSAM | C++ | 67.0 | 6 | 2.86e4 | 1.51e0 | 99.99 ||
| **ring** (434 vertices, 459 edges) |
| | apex-solver | Rust | 8.5 | 10 | 1.02e4 | 2.22e-2 | 100.00 ||
| | factrs | Rust | 4.8 | - | 1.02e4 | 3.02e-2 | 100.00 ||
| | tiny-solver | Rust | 21.0 | - | 3.17e3 | 9.87e2 | 68.81 ||
| | Ceres | C++ | 3.0 | 14 | 1.02e4 | 2.22e-2 | 100.00 ||
| | g2o | C++ | 6.0 | 34 | 1.02e4 | 2.22e-2 | 100.00 ||
| | GTSAM | C++ | 10.0 | 6 | 1.02e4 | 2.22e-2 | 100.00 ||

### 3D Datasets (SE3)

| Dataset | Solver | Lang | Time (ms) | Iters | Init Cost | Final Cost | Improve % | Conv |
|---------|--------|------|-----------|-------|-----------|------------|-----------|------|
| **sphere2500** (2500 vertices, 4949 edges) |
| | apex-solver | Rust | 176.3 | 5 | 1.28e5 | 2.13e1 | 99.98 ||
| | factrs | Rust | 334.8 | - | 1.28e5 | 3.49e1 | 99.97 ||
| | tiny-solver | Rust | 2020.3 | - | 4.08e4 | 4.06e4 | 0.48 ||
| | Ceres | C++ | 1447.0 | 101 | 8.26e7 | 8.25e5 | 99.00 ||
| | g2o | C++ | 10919.0 | 84 | 8.26e7 | 3.89e3 | 100.00 ||
| | GTSAM | C++ | 138.0 | 7 | 8.26e7 | 1.01e4 | 99.99 ||
| **parking-garage** (1661 vertices, 6275 edges) |
| | apex-solver | Rust | 153.1 | 6 | 8.36e3 | 6.24e-1 | 99.99 ||
| | factrs | Rust | 453.1 | - | 8.36e3 | 6.28e-1 | 99.99 ||
| | tiny-solver | Rust | 849.2 | - | 1.21e5 | 1.21e5 | -0.05 ||
| | Ceres | C++ | 344.0 | 36 | 1.22e8 | 4.84e5 | 99.60 ||
| | g2o | C++ | 635.0 | 56 | 1.22e8 | 2.82e6 | 97.70 ||
| | GTSAM | C++ | 31.0 | 3 | 1.22e8 | 4.79e6 | 96.08 ||
| **torus3D** (5000 vertices, 9048 edges) |
| | apex-solver | Rust | 1780.5 | 27 | 1.91e4 | 1.20e2 | 99.37 ||
| | factrs | Rust | - | - | - | - | - ||
| | tiny-solver | Rust | - | - | - | - | - ||
| | Ceres | C++ | 1063.0 | 34 | 2.30e5 | 3.85e4 | 83.25 ||
| | g2o | C++ | 31279.0 | 96 | 2.30e5 | 1.52e5 | 34.04 ||
| | GTSAM | C++ | 647.0 | 12 | 2.30e5 | 3.10e5 | -34.88 ||
| **cubicle** (5750 vertices, 16869 edges) |
| | apex-solver | Rust | 512.0 | 5 | 3.19e4 | 5.38e0 | 99.98 ||
| | factrs | Rust | - | - | - | - | - ||
| | tiny-solver | Rust | 1975.8 | - | 1.14e4 | 9.92e3 | 12.62 ||
| | Ceres | C++ | 1457.0 | 36 | 8.41e6 | 1.95e4 | 99.77 ||
| | g2o | C++ | 8533.0 | 47 | 8.41e6 | 2.17e5 | 97.42 ||
| | GTSAM | C++ | 558.0 | 5 | 8.41e6 | 7.52e5 | 91.05 ||

**Key Observations**:
- **apex-solver**: 100% convergence rate (8/8 datasets), most reliable Rust solver
- **Ceres/g2o**: 100% convergence but often slower (especially g2o)
- **GTSAM**: Fast when it converges, but diverged on torus3D (87.5% rate)
- **factrs**: Fast on 2D but panics on large 3D problems (62.5% rate)
- **tiny-solver**: Convergence issues on several datasets (75% rate)

---

## Bundle Adjustment (Self-Calibration)

Large-scale bundle adjustment benchmarks optimizing **camera poses, 3D landmarks, and camera intrinsics simultaneously**. Tests self-calibration capability on real-world structure-from-motion datasets from the Bundle Adjustment in the Large (BAL) collection.

| Dataset | Solver | Lang | Cameras | Landmarks | Observations | Init RMSE | Final RMSE | Time (s) | Iters | Status |
|---------|--------|------|---------|-----------|--------------|-----------|------------|----------|-------|--------|
| **Dubrovnik** |
| | Apex-Iterative | Rust | 356 | 226,730 | 1,255,268 | 2.043 | 0.533 | 47.16 | 9 ||
| | Ceres | C++ | 356 | 226,730 | 1,255,268 | 12.975 | 1.004 | 2879.23 | 101 ||
| | GTSAM | C++ | 356 | 226,730 | 1,255,268 | 2.812 | 0.562 | 196.72 | 31 ||
| | g2o | C++ | 356 | 226,730 | 1,255,268 | 12.975 | 12.168 | 34.67 | 20 ||
| **Ladybug** |
| | Apex-Iterative | Rust | 1,723 | 156,502 | 678,718 | 1.382 | 0.537 | 146.69 | 30 ||
| | Ceres | C++ | 1,723 | 156,502 | 678,718 | 13.518 | 1.168 | 17.53 | 101 ||
| | GTSAM | C++ | 1,723 | 156,502 | 678,718 | 1.857 | 0.981 | 95.46 | 2 ||
| | g2o | C++ | 1,723 | 156,502 | 678,718 | 13.518 | 13.507 | 150.46 | 20 ||
| **Trafalgar** |
| | Apex-Iterative | Rust | 257 | 65,132 | 225,911 | 2.033 | 0.679 | 10.39 | 14 ||
| | Ceres | C++ | 257 | 65,132 | 225,911 | 14.753 | 1.320 | 44.14 | 101 ||
| | GTSAM | C++ | 257 | 65,132 | 225,911 | 2.798 | 0.626 | 77.64 | 100 ||
| | g2o | C++ | 257 | 65,132 | 225,911 | 14.753 | 8.151 | 16.11 | 20 ||
| **Venice** (Largest) |
| | Apex-Iterative | Rust | 1,778 | 993,923 | 5,001,946 | 1.676 | 0.458 | 83.17 | 2 ||
| | Ceres | C++ | 1,778 | 993,923 | 5,001,946 | - | - | TIMEOUT | - ||
| | GTSAM | C++ | 1,778 | 993,923 | 5,001,946 | - | - | TIMEOUT | - ||
| | g2o | C++ | 1,778 | 993,923 | 5,001,946 | 10.128 | 10.126 | 252.17 | 20 ||

**Key Results**:
- **Apex-Iterative**: 100% convergence rate (4/4 datasets), handles up to 5M observations efficiently
- **Superior scalability**: Only solver alongside g2o to complete Venice dataset; Ceres and GTSAM timeout after 10 minutes
- **Best accuracy on largest dataset**: Achieves 0.458 RMSE on Venice (5M observations) in only 2 iterations
- **Speed advantage**: 61x faster than Ceres on Dubrovnik, 4x faster on Trafalgar (where Ceres converged)

---

*Back to [README](../README.md)*