通过SVD分解求逆的参考博客
之前在看机器人微分逆运动学时,看到有博主提出用svd分解求逆来代替inverse方法可加速计算,下面特意验证一下:
取一个100行100列的矩阵,分别使用Eigen的SVD分解法再计算逆矩阵和直接用Eigen的inverse方法做个对比
#include <iostream>
#include<algorithm>
#include<Eigen/Dense>
#include<chrono>
int main(int, char**){
constexpr int row=100;
constexpr int col=100;
Eigen::Matrix<double,row,col> jac=Eigen::Matrix<double,row,col>::Random();
//svd
auto svd_start=std::chrono::system_clock::now();
double esp=1e-8;
int k=std::min(row,col);
Eigen::JacobiSVD<Eigen::Matrix<double,row,col>> svd(jac,Eigen::ComputeFullU|Eigen::ComputeFullV);
Eigen::MatrixXd singular_value=svd.singularValues();
Eigen::MatrixXd singular_value_inv=Eigen::MatrixXd::Zero(col,row);
for(int i=0;i<k;i++)
{
if(singular_value(i)>esp)
{
singular_value_inv(i,i)=1/singular_value(i);
}
else
{
singular_value_inv(i,i)=0;
}
}
auto jac_inv_svd=svd.matrixV()*singular_value_inv*svd.matrixU().transpose();
// std::cout<<"jac_inv calculated with svd:\n"<<jac_inv_svd<<std::endl;
auto svd_end=std::chrono::system_clock::now();
auto svd_duration= std::chrono::duration_cast<std::chrono::nanoseconds>(svd_end-svd_start);
std::cout<<"svd inverse cost time:\n"<<svd_duration.count()<<std::endl;
auto inv_start=std::chrono::system_clock::now();
auto jac_inv=jac.inverse();
// std::cout<<"jac_inv calculated with inverse():\n"<<jac_inv<<std::endl;
auto inv_end=std::chrono::system_clock::now();
auto inv_duration=std::chrono::duration_cast<std::chrono::nanoseconds>(inv_end-inv_start);
std::cout<<"inv inverse cost time:\n"<<inv_duration.count()<<std::endl;
}
运行结果
inverse爆杀SVD后再求逆矩阵。