Release 4.3a2
Pre-releaseGTSAM 4.3a2
GTSAM 4.3a2 is a substantial alpha release that expands continuous-time estimation, constrained and certifiable optimization, hybrid inference, navigation, parallel solvers, and GPU acceleration. It also brings extensive improvements to documentation, notebooks, language wrappers, build tooling, and Python wheel publishing.
The API is not stable for these new additions. Esp. the GPU acceleration and certifiable optimization are still in flux. Once those settle down, we aim to cut a 4.3 release.
Highlights
Continuous-time Gaussian processes
This release introduces a comprehensive continuous-time Gaussian-process framework based on white-noise-on-acceleration (WNOA) models. It includes continuous-time factors, trajectory interpolation, factor-graph construction, Python bindings, and worked notebooks and examples.
The new framework supports continuous-time trajectory estimation while integrating naturally with GTSAM’s nonlinear factor graphs.
Constrained, QCQP, and certifiable optimization
The constrained optimization framework now includes linear programs (LP), quadratic programs (QP), and quadratically constrained quadratic programs (QCQP), together with Python wrappers, examples, and documentation.
QCQP factor-graph conversion provides an intermediate representation for constructing monolithic and chordal semidefinite relaxations. This forms the beginning of a broader certifiable-optimization capability in GTSAM. A new certifiable module adds lifted SDP problems and a Riemannian Staircase solver, with optional MOSEK integration and wrapping.
Hybrid and discrete inference
Hybrid inference received substantial implementation, wrapping, and documentation improvements. These include expanded hybrid documentation and notebooks, improvements to hybrid factors and inference, Python wrapping for DCSAM, and cleanup of the accompanying examples.
The discrete documentation and tutorials were also expanded, including a new discrete-series example tutorial.
Parallel multifrontal inference and performance
A major body of work introduces new linear and nonlinear multifrontal solvers, parallel clique processing, bottom-up clique merging, task and priority schedulers, and TBB-based separator updates.
Related performance work improves nonlinear graph error evaluation, Jacobian-factor operations, Levenberg–Marquardt elimination, covariance recovery, ISAM2 reordering, marginal caching, and batch-factor operations.
Navigation, filtering, and GNSS
Navigation gained new equivariant filtering infrastructure, group actions, EqVIO foundations and filtering, EKF reset support, extended-pose Lie groups, and four-legged state-estimation capabilities.
GNSS support now includes pseudorange, differential pseudorange, carrier-phase, RTK double-difference, PPP, lever-arm, and GNSS/IMU coupling factors. The release also adds a GlobalPositioner and improves trajectory alignment, IMU handling, and navigation documentation.
CUDA-accelerated bundle adjustment
This release introduces an experimental CUDA SFM bundle-adjustment optimizer and CUDA-backed GNC optimization. The CUDA GNC implementation uses the CUDA SFM Levenberg–Marquardt solver as its inner optimizer and demonstrated substantial speedups over the CPU implementation.
Geometry, robustness, and covariance recovery
Geometry additions include PowerLieGroup, variable-dimension product groups, extended poses, improved SL4, Cayley-chart Jacobians for Rot3, SphericalCamera bindings, and self-calibration support.
Robust estimation gained TLS loss functions, René Vidal’s TLS formulation, broader GNC factor support, and improvements to GNC trajectory alignment. Covariance recovery now uses Steiner-tree queries integrated into GaussianBayesTree and exposed through ISAM2.
Documentation, notebooks, and wrappers
Documentation was expanded across hybrid inference, basis functions, constrained optimization, navigation, marginals, and continuous-time Gaussian processes. Numerous Python examples were migrated to standardized notebooks.
Python and MATLAB support gained new wrappers, custom-factor support, numerical derivatives, copy-free matrix views, improved return policies, broader factor coverage, and updated wrapper-generation infrastructure.
Build and packaging improvements include production PyPI publishing, Python 3.14 wheels, faster and more reliable wheel builds, improved Windows Python support, modernized CMake and vcpkg integration, and reduced Boost dependencies.
New Contributors
- @ethanmusser made their first contribution in #2308
- @dvorak0 made their first contribution in #2313
- @yluo5820 made their first contribution in #2323
- @tzvist made their first contribution in #2355
- @masoug made their first contribution in #2369
- @aminoh made their first contribution in #2402
- @hkhanuja made their first contribution in #2410
- @inuex35 made their first contribution in #2446
- @jashshah999 made their first contribution in #2456
- @kathirgounder made their first contribution in #2495
- @holmesco made their first contribution in #2411
- @SchmidL made their first contribution in #2507
- @ChiyunNoh made their first contribution in #2515
- @kshaji3 made their first contribution in #2528
- @mvanhorn made their first contribution in #2534
- @zhexin1904 made their first contribution in #2541
- @zcjhao made their first contribution in #2546
- @SidArora29 made their first contribution in #2554
- @wyf027 made their first contribution in #2566
- @thatdudegrantt made their first contribution in #2571
- @leolrg made their first contribution in #2581
- @avinashresearch1 made their first contribution in #2549
- @hz2 made their first contribution in #2590
- @admin123-abc made their first contribution in #2600
- @mjelen2 made their first contribution in #2607
- @bboyack made their first contribution in #2599
Comprehensive Change List
- Added discrete series example tutorial by @Robert-Jia00129 in #2290
- Use doublecross instead of cross(Cross(a, b)) in NavState by @scottiyio in #2287
- Update version to 4.3a1 by @dellaert in #2303
- Fix macOS 26 Xcode compilation by @ProfFan in #2305
- Remove-macos-13-ci by @dellaert in #2304
- Remove absolute paths in configuration installs by @ethanmusser in #2308
- Fix CMake complaining about Boost by @varunagrawal in #2309
- [2/N] Change NoiseModelFactorN to be an alias to NoiseModelFactorT by @ProfFan in #2302
- Fix Matlab wrapper by @varunagrawal in #2310
- New docs: hybrid by @p-zach in #2120
- [1/N] Split the NoiseModelFactorN to individual header by @ProfFan in #2301
- add python exports for SmartStereoProjectionFactor by @dvorak0 in #2313
- Various filter changes by @dellaert in #2315
- Added PowerLieGroup by @dellaert in #2316
- Added BayesTree cache clearing for Marginals by @travisdriver in #2318
- Fix mathematically incorrect determinant sign handling in SL4::Expmap by @dellaert with @Copilot in #2319
- Remove try-catch from large tangent vector tests by @dellaert with @Copilot in #2320
- Fix SL4 determinant normalization numerical instability by @dellaert with @Copilot in #2321
- EquivariantFilter and GroupAction by @jenniferoum in #2197
- Fix/sl4 by @yluo5820 in #2323
- Fix SL4 to determinant issue by @dellaert in #2317
- Clean up Ordering + headers by @dellaert in #2068
- Address code review comments: documentation and naming conventions by @dellaert with @Copilot in #2328
- MultifrontalSolver by @dellaert in #2327
- Bottom-up clique merging and TBB by @dellaert in #2330
- Fix eigen3 v5.0.1 compilation errors. by @talregev in #2331
- Deprecate NonlinearEquality and Fix Constrained Covariances by @dellaert in #2335
- Handle noise and NonlinearEquality constraints by @dellaert in #2332
- Fix parsing issue on MacOS by @dellaert in #2338
- TBB for solve by @dellaert in #2336
- Cache optimization by @dellaert in #2339
- JacobianFactor now compute the error more efficiently by first assembling the X vector by @ProfFan in #2329
- Address code review feedback for PriorityScheduler and ForestTraversal by @dellaert with @Copilot in #2344
- Jacobian implementations for sim3 transformFrom by @akshay-krishnan in #2341
- Two Schedulers - One very fast Solver by @dellaert in #2345
- Scheduled MultifrontalSolver by @dellaert in #2343
- range/bearing for NavState and Gal3 by @dellaert in #2346
- Task scheduler and ForestTraversal by @dellaert in #2342
- Parallel separator update in MFSolver by @dellaert in #2347
- Minor fixes by @varunagrawal in #2348
- Minimize the number of workflows by @varunagrawal in #2349
- Address code review feedback for TrajectoryAlignerSim3 by @dellaert with @Copilot in #2352
- Sampler updates by @dellaert in #2353
- Class for Pose3 trajectory alignment using Sim3 by @akshay-krishnan in #2351
- Quick fix for readme and cvpkg by @dellaert in #2357
- perf: parallelize NonlinearFactorGraph::error computation. by @tzvist in #2355
- Tiny perf improvements by @dellaert in #2358
- deltaError replaces 2 error calls by @dellaert in #2361
- Default noise models and TranslationRecovery patch by @dellaert in #2363
- Fix all noise models by @dellaert in #2364
- switch Hat/Vee to orthonormal sl(4) basis and update adjoint/tests by @yluo5820 in #2360
- Nonlinear multifrontal solver by @dellaert in #2362
- Add vcpkg mkl by @talregev in #2359
- Revert linear solver type to MULTIFRONTAL_CHOLESKY by @akshay-krishnan in #2365
- sccache for all os in vcpkg by @talregev in #2367
- Run Windows CI workflow on push by @Gold856 in #2370
- EKF Reset by @dellaert in #2373
- Simple GNSS Pseudorange Factor by @masoug in #2369
- Docs for basis by @dellaert in #2375
- Remove all Cephes source files except those needed for igami by @Gold856 in #2371
- Small issues in examples by @dellaert in #2376
- Expose EqF Python bindings (ABC), template on N, modify/add examples by @rohan-bansal in #2368
- Standardize on KeySet by @dellaert in #2377
- Fix mac install by @dellaert in #2378
- Fix segfault in constraint by @dellaert in #2379
- Fix Eigen issue in PseudorangeFactor by @varunagrawal in #2380
- Some docs + translationRecovery fix by @dellaert in #2381
- Fix issue in optimizer by @dellaert in #2382
- Add continuous benchmarking workflow by @ProfFan in #2385
- perf: TBB with memory growth control. by @tzvist in #2356
- Introducing DifferentialPseudorangeFactor by @masoug in #2383
- Fix a deadlock under Windows by @ProfFan in #2393
- Constrained docs by @dellaert in #2394
- Fix docs by @dellaert in #2395
- NavState docs by @dellaert in #2398
- Update SFMBAL benchmark script by @ProfFan in #2397
- Fix wrap w/o boost by @dellaert in #2403
- Clean up and speed up CI by @Gold856 in #2400
- Clean up Boost dependencies by @Gold856 in #2399
- removed unnecessary DiscreteKeys constructor by @aminoh in #2402
- Use vcpkg manifest by @Gold856 in #2388
- Remove macOS 14 from CI by @Gold856 in #2406
- Optimize cibuildwheel build times by @Gold856 in #2407
- Allowing Non Noise Model Factors for Gnc by @hkhanuja in #2410
- Optimize Levenberg Marquardt elimination by caching JunctionTree. by @tzvist in #2340
- Add Lie group capabilities to NavState by @varunagrawal in #1613
- Weight update in Gnc GM through static function in LossFunctions by @hkhanuja in #2415
- Address PR #2418 review feedback: SWIG Jacobians, trait-based dim, AdjointMap perf note by @dellaert with @Copilot in #2419
- Harmonize Ad/ad by @dellaert in #2418
- Extended Pose SE_k(3) by @dellaert in #2416
- TLS loss and Rene Vidal TLS implementation by @hkhanuja in #2417
- TrajectoryAlignerSim3 - add point3 constraints if available, optionally use GNC by @akshay-krishnan in #2445
- iSAM2 Updates to Support riSAM Implementation by @DanMcGann in #2408
- Add SphericalCamera Python bindings by @inuex35 in #2446
- variable dimension product groups by @dellaert in #2450
- Add BAL SmartFactor example by @dvorak0 in #2449
- Reduce wheel CI flakiness by @dellaert in #2452
- Remove benchmark caching by @ProfFan in #2451
- Fix published notebook/doc links to website routes by @dellaert in #2457
- Use internal MyST links in published docs by @dellaert in #2458
- Fix enforceConsistency_ in BatchFixedLagSmoother by @jashshah999 in #2456
- Reject negative sigma values in noise model constructors by @jashshah999 in #2465
- Move free functions definitions to
GncOptimizer.cppby @varunagrawal in #2461 - Fix LinearContainerFactor::rekey() segfault without linearization point by @jashshah999 in #2467
- Fix incorrect key in cheirality error message for PPP/PPPC factors by @jashshah999 in #2463
- Fix tMin_ reset when an iteration has zero duration by @jashshah999 in #2464
- 4 legged state estimators by @dellaert in #2470
- Add PseudorangeFactorArm and DifferentialPseudorangeFactorArm by @inuex35 in #2447
- Add EqVIO Group, Manifold Foundation by @rohan-bansal in #2455
- Fix IncrementalFixedLagSmoother with factor removal by @Ellon in #2474
- Rename Python reserved keywords in wrapper interface files by @jashshah999 in #2471
- Steiner trees for Covariance Recovery by @dellaert in #2476
- Simplify Marginals and add docs by @dellaert in #2482
- Add optional ecef_T_nav to PseudorangeFactorArm for GNSS/IMU coupling by @inuex35 in #2477
- [codex] Move covariance recovery into GaussianBayesTree and expose ISAM2 queries by @dellaert in #2486
- Fix/normalization by @dellaert in #2487
- Fix matlab wrapper by @dellaert in #2490
- MATLAB CustomFactor by @dellaert in #2491
- numerical derivatives in MATLAB by @dellaert in #2493
- Wrap DCSAM class and remove hybrid examples by @varunagrawal in #2454
- Add missing templates in wrapper by @dellaert in #2496
- [codex] Refactor RangeFactor to remove expression overhead by @dellaert in #2497
- Simplify SAM factors by @dellaert in #2498
- Generalize AttitudeFactor by @dellaert in #2499
- New CustomFactor examples by @dellaert in #2501
- Fix AttitudeFactor Wrapping by @dellaert in #2500
- Geometry enhancements by @dellaert in #2503
- Hybrid improvements by @varunagrawal in #2459
- Added GlobalPositioner Class by @kathirgounder in #2495
- Continuous-Time Gaussian Process Factors (Factors and Interpolation) by @holmesco in #2411
- Add python wrapper and test for LocalOrientedPlane3Factor by @SchmidL in #2507
- EqVIO Filter Implementation by @rohan-bansal in #2475
- feat: double difference factor for rtk gnss by @inuex35 in #2502
- Continuous Time GP Factor Graph by @holmesco in #2514
- navigation: honor configured IMU bias in LeggedFixedLagSmoother by @ChiyunNoh in #2515
- Images from ChatGpt by @dellaert in #2518
- feat(isam2): adaptive variable reordering triggered by fill-in growth by @jashshah999 in #2509
- fix(geometry): implement Cayley chart Jacobians for Rot3 by @jashshah999 in #2511
- perf(linear): compute JacobianFactor::gradient() directly, skip HessianFactor conversion by @jashshah999 in #2510
- LP and QP by @dellaert in #2525
- Add QCQP by @dellaert in #2526
- LP/QP/QCQP wrapper and examples by @dellaert in #2527
- WNOA CT-GP Bindings and Example by @holmesco in #2523
- Fix Continuous-Time GP Notebook by @holmesco in #2529
- Use sccache for Windows Python jobs by @Gold856 in #2530
- Factor for yaw in Pose2, with bias by @truher in #2524
- Remove unused Boost dependencies by @Gold856 in #2532
- Fixes to Eigen's SSE vectorizer patterns from GCC/G++ 14/15 by @kshaji3 in #2528
- fix: publish release wheels to production PyPI in prod-cibw.yml by @mvanhorn in #2534
- More edits for gcc 13 by @kshaji3 in #2538
- Fix Chebyshev2 IntegrationMatrix to be exact by @dellaert in #2540
- Modify for QCQP support for the BM methods. by @zhexin1904 in #2541
- cmake: disable Boost by default when building inside colcon (ROS 2) by @jlblancoc in #2543
- [Python] Add venv setup instructions for PEP 668 systems in README by @zcjhao in #2546
- [Python] Fix python-unstable-stubs using bare pybind11-stubgen command by @zcjhao in #2545
- Add FromQcqpValue (Rot2/Rot3) and ExtractQcqpValues helpers in feature/convert_to_QCQP by @zhexin1904 in #2548
- Copy-free matrix views for wrapped batch APIs by @dellaert in #2551
- DecisionTree::dot(name, ...): skip system() shellout on iOS by @ShuangLiu1992 in #2547
- [Python] Fix Pose3 sigma ordering in test_Pose3SLAMExample by @zcjhao in #2555
- feat(python): Expose BetweenFactor to Python wrapper by @SidArora29 in #2554
- perf(python): return references from optimizer to avoid deep-copying Values by @jashshah999 in #2520
- test: fix asymmetric loss zero checks by @wyf027 in #2566
- Fix/copilot instructions wrap 3rdparty by @thatdudegrantt in #2571
- [Python] Add batch triangulateSafe supporting incomplete tracks by @zcjhao in #2573
- navigation: route undifferenced GNSS factors through Sagnac-corrected geodist (#2563) by @inuex35 in #2574
- Remove aligned operator new macro by @Gold856 in #2579
- Add compiler hash to vcpkg cache key by @Gold856 in #2577
- Fix GCC 15 warnings by @Gold856 in #2580
- Add SelfCalibrationFactor for closed-form focal-length self-calibration by @kathirgounder in #2568
- [codex] Automate PyPI develop cleanup by @dellaert in #2583
- Fix(python/windows): fix DLL load failure on Windows for Python wrapper by @thatdudegrantt in #2584
- Clean up headers/includes and refresh precompiled headers by @Gold856 in #2578
- BatchFactor by @dellaert in #2586
- Optimize compile times by @Gold856 in #2561
- Add experimental CUDA SFM bundle adjustment optimizer by @leolrg in #2581
- feat(python): expose PriorFactor to Python wrapper by @SidArora29 in #2562
- Sync/update wrap subtree by @thatdudegrantt in #2587
- navigation: add undifferenced (PPP) pseudorange and carrier-phase factors by @inuex35 in #2575
- Clarify JointMarginal::at()/operator() indexing semantics (Key, not position) by @thatdudegrantt in #2592
- fix: remove AmbientDim from QCQP conversion by @dellaert in #2596
- WIP: add homogenization term to D = 1 lifting to QCQP factor by @avinashresearch1 in #2549
- Fix PartialPriorFactor instantiation for vector-space types like Point3 by @jashshah999 in #2597
- Link cephes-gtsam against libm by @hz2 in #2590
- fix: change to direct formulation of FrobeniusPrior to QCQP lift by @avinashresearch1 in #2598
- Add QCQP factor graph conversion by @dellaert in #2550
- Avoid recursive separator marginal caching for deep Bayes trees by @admin123-abc in #2600
- Add pragmas for GCC 16 warnings by @mjelen2 in #2607
- Implements monolithic and chordal SDP from QCQP intermediate by @avinashresearch1 in #2606
- Add certifiable module and Riemannian Staircase solver by @dellaert in #2608
- CUDA GNC: run GncOptimizer with the CUDA SFM LM inner solver, ~20x over CPU GNC by @leolrg in #2593
- Fix Python 3.14 manylinux wheel builds by @dellaert in #2610
- Modernize installation and repository guidance by @dellaert in #2611
- New wrap and MOSEK wrapping by @dellaert in #2612
- Fix 8-dimensional matrix and vector constants by @ProfFan in #2615
- fix: stop -Werror from propagating to downstream consumer builds by @mvanhorn in #2560
- Speed up geometry by @dellaert in #2617
- Fixed lag and python by @bboyack in #2599
- Notebooks by @zcjhao in #2604
Full Changelog: 4.3a1...4.3a2