一、前言:什么是 TooN?
在C++机器人、SLAM、姿态解算、视觉标定等轻量化高精度数值场景中,开发者常面临困境:Eigen体量偏大、编译模板膨胀;uBLAS语法老旧、性能一般;Blitz++侧重数组迭代、缺少线性代数求解;MTL4依赖Boost、配置繁琐。
TooN 是一款极致轻量、纯头文件、零依赖、专为小维度矩阵优化 的工业级C++线性代数库,全称 Toolkit Of Numerics ,由牛津大学研发,是 SLAM、机器人姿态解算、卡尔曼滤波、三维几何计算 的事实标准库。
TooN 核心定位:小维度、高精度、零开销、语法极简 ,不做大尺度稀疏矩阵,专注 2D/3D/4D/6D 几何与姿态运算,是四矩阵库中嵌入式、机器人场景最优解。
TooN 核心特点(区别于前三库)
-
纯头文件零依赖:无需编译、无需链接、无第三方依赖,下载头文件直接引入即用
-
静态维度极致优化:编译期固定维度,运行期零开销,速度碾压动态矩阵库
-
几何运算原生支持:向量点积、叉积、旋转矩阵、四元数、姿态变换原生API
-
精度极高:浮点误差控制优秀,适合标定、滤波、高精度拟合场景
-
语法极简干净:无冗余API、无奇葩运算符重载,贴近数学公式
-
机器人生态标配:广泛用于SLAM、视觉里程计、机器人控制、传感器融合
二、环境配置(全网最简单、开箱即用)
TooN 是纯头文件库,全平台通用,无需 cmake、无需编译、无需链接库。
1. 安装方式(全平台统一)
# Ubuntu/Debian 一键安装
sudo apt-get install libtoon-dev
# 手动安装(全平台通用)
git clone https://github.com/edrosten/TooN.git
cd TooN
sudo cp -r ./TooN /usr/include/
2. 核心头文件与命名空间
一行引入全覆盖向量、矩阵、线性求解、几何运算:
#include <TooN/TooN.h>
// 工程必加,简化所有API
using namespace TooN;
3. 编译命令
纯头文件,无任何链接需求,编译命令极简:
g++ main.cpp -o toon_demo -std=c++11
三、核心数据结构(向量+静态矩阵+动态矩阵)
TooN 核心优势:区分静态维度与动态维度,小维度静态矩阵编译期优化,大维度使用动态矩阵,兼顾性能与灵活性。
核心模板:Vector<维度, 类型>、Matrix<行,列,类型>
1. 一维向量 Vector(几何计算核心)
#include <iostream>
#include <TooN/TooN.h>
using namespace TooN;
int main()
{
// 静态3维浮点向量
Vector<3, double> vec;
// 下标赋值
vec[0] = 1.0;
vec[1] = 2.0;
vec[2] = 3.0;
// 流式初始化(TooN招牌极简写法)
Vector<3, double> vec2 = makeVector(4.0,5.0,6.0);
// 遍历打印
for(int i=0;i<3;i++)
std::cout << vec[i] << " ";
std::cout << std::endl;
return 0;
}
2. 二维矩阵 Matrix(静态固定维度)
机器人开发99%场景使用静态矩阵,性能最优:
int main()
{
// 2行2列静态矩阵
Matrix<2,2,double> mat;
// 逐元素赋值 mat(行,列)
mat(0,0)=1; mat(0,1)=2;
mat(1,0)=3; mat(1,1)=4;
// 极简批量初始化
Matrix<2,2,double> mat2 = makeMatrix(1.0,2.0,
3.0,4.0);
// 遍历打印
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
std::cout << mat(i,j) << " ";
std::cout << std::endl;
}
return 0;
}
3. 动态矩阵(适配未知维度)
维度不确定时,使用 -1 标识动态维度,用法灵活:
// 动态行列矩阵
Matrix<-1,-1,double> dyn_mat(3,3);
dyn_mat = 1,2,3,
4,5,6,
7,8,9;
核心API释义
-
mat.num_rows():获取行数 -
mat.num_cols():获取列数 -
vec.size():获取向量维度 -
静态维度编译期校验,杜绝维度越界
四、基础运算(加减乘、点积、叉积、转置)
TooN 原生重载全部算数运算符,矩阵乘法、点积、三维叉积原生支持,完美适配几何运算。
1. 向量基础运算(点积+叉积重点)
int main()
{
Vector<3,double> v1 = makeVector(1,2,3);
Vector<3,double> v2 = makeVector(4,5,6);
// 向量加减、数乘
Vector<3,double> v_add = v1 + v2;
Vector<3,double> v_mul = v1 * 2.0;
// 向量点积(原生API)
double dot = v1 * v2;
// 三维向量叉积(SLAM、姿态计算核心)
Vector<3,double> cross_val = cross(v1, v2);
std::cout << "点积:" << dot << std::endl;
std::cout << "叉积结果:" << cross_val << std::endl;
return 0;
}
2. 矩阵基础运算
int main()
{
Matrix<2,2,double> A = makeMatrix(1,2,3,4);
Matrix<2,2,double> B = makeMatrix(2,2,2,2);
// 矩阵加减、数乘
Matrix<2,2,double> C = A + B;
Matrix<2,2,double> D = A * 1.5;
// 标准矩阵乘法(原生支持,直接*)
Matrix<2,2,double> E = A * B;
std::cout << "A*B矩阵乘法结果:\n" << E << std::endl;
return 0;
}
四库对比亮点 :TooN
A*B直接标准矩阵乘法,和MTL4一致,比uBLAS简洁、比Blitz++规范,新手零学习成本。
3. 矩阵转置
int main()
{
Matrix<2,3,double> mat = makeMatrix(1,2,3,4,5,6);
Matrix<3,2,double> mat_t = mat.T();
std::cout << "转置矩阵:\n" << mat_t << std::endl;
return 0;
}
五、高阶核心功能(行列式、求逆、线性方程组求解)
TooN 针对小维度矩阵深度优化,原生支持行列式、逆矩阵、线性方程组求解,精度极高。
1. 行列式 + 矩阵求逆
#include <cmath>
int main()
{
Matrix<2,2,double> A = makeMatrix(1,2,3,4);
// 行列式
double det = determinant(A);
std::cout << "行列式:" << det << std::endl;
// 矩阵求逆
if(fabs(det) > 1e-6)
{
Matrix<2,2,double> A_inv = inverse(A);
std::cout << "逆矩阵:\n" << A_inv << std::endl;
}
return 0;
}
2. 线性方程组 Ax=b 求解
int main()
{
Matrix<3,3,double> A = makeMatrix(
2, 1, -1,
-3,-1, 2,
-2, 1, 2
);
Vector<3,double> b = makeVector(1, -8, -3);
// 一行求解方程组
Vector<3,double> x = solve(A, b);
std::cout << "方程组解:" << x << std::endl;
return 0;
}
六、完整基础可运行Demo
#include <iostream>
#include <cmath>
#include <TooN/TooN.h>
using namespace TooN;
void print_mat(const Matrix<-1,-1,double>& mat)
{
for(int i=0;i<mat.num_rows();i++)
{
for(int j=0;j<mat.num_cols();j++)
{
printf("%8.4f ", mat(i,j));
}
printf("\n");
}
}
int main()
{
// 初始化矩阵
Matrix<2,2,double> A = makeMatrix(1,2,3,4);
std::cout << "原始矩阵A:\n";
print_mat(A);
// 行列式
double det = determinant(A);
std::cout << "行列式:" << det << "\n\n";
// 逆矩阵
Matrix<2,2,double> A_inv = inverse(A);
std::cout << "逆矩阵:\n";
print_mat(A_inv);
// 矩阵乘法
Matrix<2,2,double> B = A * A_inv;
std::cout << "A*A_inv 单位矩阵:\n";
print_mat(B);
return 0;
}
七、TooN 高阶独家用法(SLAM/机器人专属)
本节为 TooN 区别于前三库的独家高阶能力,三维几何、姿态变换、矩阵分块、行列删除、向量归一化,是SLAM开发核心刚需。
1. 向量归一化、模长计算
int main()
{
Vector<3,double> v = makeVector(3,4,0);
// 模长
double len = norm(v);
// 单位化
Vector<3,double> unit_v = unit(v);
std::cout << "模长:" << len << std::endl;
std::cout << "单位向量:" << unit_v << std::endl;
return 0;
}
2. 矩阵分块、截取子矩阵
int main()
{
Matrix<4,4,double> m;
m = 1,1,1,1,
2,2,2,2,
3,3,3,3,
4,4,4,4;
// 截取 2行2列子矩阵
Matrix<2,2,double> sub = m.slice(1,1,2,2);
std::cout << "子矩阵:\n" << sub << std::endl;
return 0;
}
3. 删除指定行/列(工程高频)
int main()
{
Matrix<3,3,double> m = makeMatrix(1,2,3,4,5,6,7,8,9);
// 删除第0行
auto m2 = m.del_row(0);
// 删除第1列
auto m3 = m2.del_col(1);
std::cout << "删除行列后矩阵:\n" << m3 << std::endl;
return 0;
}
4. 零矩阵、单位矩阵快速生成
// 2阶单位矩阵
Matrix<2,2,double> eye = Identity;
// 3阶零矩阵
Matrix<3,3,double> zero = Zeros;
八、新手高频踩坑总结
-
静态维度不可变 :静态矩阵维度编译期固定,运行期无法修改,动态计算必须用
-1动态维度 -
维度严格校验:向量矩阵维度不匹配直接编译报错,提前规避运行期崩溃
-
仅适合小维度:不适合千阶万阶超大矩阵,优势在于小维度高精度几何运算
-
初始化格式:makeMatrix 按行填充,注意行列顺序
九、四大C++矩阵库横向对比(终极选型指南)
| 库名称 | 核心优势 | 短板 | 最佳适用场景 |
|---|---|---|---|
| Boost.uBLAS | Boost生态、零依赖、标准线性代数 | 语法老旧、无几何运算、性能一般 | 通用小型矩阵计算、传统工程 |
| Blitz++ | 数组迭代性能极强、高维数组友好 | 无原生矩阵乘法、无线性求解 | 大规模数组迭代、科学仿真遍历 |
| MTL4 | 稠密+稀疏双支持、求解器丰富 | 依赖Boost、配置复杂 | 有限元、稀疏方程组、大规模求解 |
| TooN | 零依赖、小维度极致性能、几何姿态最强 | 不支持超大矩阵、无稀疏矩阵 | SLAM、机器人、姿态解算、嵌入式 |
十、全文总结
本文严格对齐前三篇系列教程结构,完整讲解了 TooN 从环境搭建、核心数据结构、基础运算、高阶 矩阵 求解、机器人专属高阶几何用法、踩坑避坑、四库横向选型全套内容。
TooN 是四款轻量级矩阵库中嵌入式、机器人、SLAM、三维几何场景的绝对最优解,纯头文件、零依赖、高精度、零开销,是轻量化高精度数值计算的首选库。