5 视觉SLAM十四讲读书笔记P40-P52( 六 )


是Eigen库中的一个类 , 表示动态大小的矩阵 , 即行数和列数可以在运行时确定 。其构造函数的形式为(rows,cols) , 其中rows和cols表示矩阵的行数和列数 。使用可以方便地定义任意大小的矩阵 。
::(, )创建一个 x 的矩阵 , 其中每个元素都是一个[-1, 1]之间的随机数 。
的值为 50 。
一个
实矩阵A被称为半正定矩阵 , 如果对于任意n维非零实向量x , 都有
。其中 , 
表示矩阵的转置 。
半正定矩阵具有以下性质:
半正定矩阵的特征值均为非负实数 。
半正定矩阵可以被分解成
的形式 , 其中L是一个下三角矩阵 。
半正定矩阵是一类非常重要的矩阵 , 它们在统计学、机器学习和优化等领域有着广泛的应用 , 例如用于协方差矩阵的估计、二次规划问题的求解等等 。
设A是一个矩阵 , 则
是一个对称矩阵 , 因为
。又因为对于任意非零向量x , 有
 , 所以
是半正定矩阵 。
clock_t time_stt = clock(); // 计时// 直接求逆Matrix x = matrix_NN.inverse() * v_Nd;cout << "time of normal inverse is "<< 1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC << "ms" << endl;cout << "x = " << x.transpose() << endl;
这段代码是对矩阵求逆并求解方程 Ax=b , 其中 A是半正定矩阵 , b是列向量 。
矩阵求逆的方法是使用 () 函数 。然而 , 这种方法在计算量大的时候效率比较低 。
第二行代码的作用是求解线性方程组 Ax=b , 其中 A是 nxn的矩阵 , b是nx1 的列向量 , x是 nx1的列向量 , 即求解 x满足 Ax=b 。在这里 , A 是半正定矩阵 , 使用求逆的方式来求解线性方程组 。
1000 * (clock() - ) / ()是一个计算程序运行时间的表达式 。在这个表达式中 , clock()函数返回从程序开始运行到调用该函数时为止的CPU时钟周期数 , 单位为“时钟打点” 。表示CPU每秒运行的时钟打点数 。因此 , (clock() - ) / () 的结果就是程序运行的CPU时间(秒) , 乘以1000即可转换为毫秒 。
// 通常用矩阵分解来求 , 例如QR分解 , 速度会快很多time_stt = clock();x = matrix_NN.colPivHouseholderQr().solve(v_Nd);cout << "time of Qr decomposition is "<< 1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC << "ms" << endl;cout << "x = " << x.transpose() << endl;
这部分代码使用QR分解的方法来求解方程组 , 使用了矩阵库中的 () 函数对系数矩阵进行QR分解 , 然后使用 solve() 函数对分解后的矩阵和向量进行求解 。
具体来说 , QR分解是将一个矩阵分解为一个正交矩阵和一个上三角矩阵的乘积 , 即A=QR , 其中Q为正交矩阵 , R为上三角矩阵 。对于一个满秩矩阵A , 我们可以通过QR分解来求解线性方程组Ax=b 。首先将系数矩阵A进行QR分解 , 即A=QR , 然后将方程组变为
 , 再通过回带求解即可得到x的解 。
相比直接求逆的方法 , QR分解方法具有更高的求解效率和更好的数值稳定性 。
// 对于正定矩阵 , 还可以用cholesky分解来解方程time_stt = clock();x = matrix_NN.ldlt().solve(v_Nd);cout << "time of ldlt decomposition is "<< 1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC