工作中遇到一个问题,发到hmi的车辆引导线为斜的,有一说一,仔细看下这段代码,发现用到了Eigen库用来多项式曲线拟合,线性回归,矩阵向量计算等。
#include <iostream>
#include <vector>
#include <eigen3/Eigen/Dense>
int main()
{
Eigen::MatrixXd matrix_a;
matrix_a.resize(2,2);
Eigen::IOFormat fmt;
fmt.rowPrefix='[';
fmt.rowSuffix=']';
fmt.coeffSeparator=',';
matrix_a(0,0)=1;
matrix_a(0,1)=2;
matrix_a(1,0)=3;
matrix_a(1,1)=4;
std::cout<<matrix_a.format(fmt)<<std::endl;
std::cout<<"矩阵转置"<<std::endl;
std::cout<<matrix_a.transpose().format(fmt)<<std::endl;
std::cout<<"逆矩阵"<<std::endl;
std::cout<<matrix_a.inverse().format(fmt)<<std::endl;
return 0;
}
/*输出
[1,2]
[3,4]
矩阵转置
[1,3]
[2,4]
逆矩阵
[ -2, 1]
[ 1.5,-0.5]
如下图,通过一系列点拟合一元三次方程,表示轨迹线:
利用 Eigen库完成计算,开始想着直接调用 inverse 接口不就行了?试着改了下代码,直接报错了,看提示是 Assertion `rows() == cols()' failed.
哦,忘记方阵才有逆矩阵了,既然拟合的点数量与方程阶数不一定对应,所以不能直接求 X 的逆矩阵,借用转置矩阵来计算。
(设拟合点数量为n)
下面的函数用于求得 Y=XC中Y(n阶向量)与X(n行3列矩阵)
void XYTrajectoryPoly(const std::vector<Point>& traj, unsigned int order, Eigen::MatrixXd& Xs,Eigen::VectorXd& Ys) {
Xs.resize(traj.size(), order + 1);
Ys.resize(traj.size());
for (uint32_t i = 0; i < traj.size(); ++i) {
for (uint32_t j = 0; j < order + 1; ++j) {
Xs(i, j) = std::pow(traj[i].x, j);
}
Ys(i) = traj[i].y;
}
}
下面的函数,接收Y与X,返回由方程的系数组成的向量,transpose返回转置矩阵,inverse返回逆矩阵
void LinearRegression(const Eigen::MatrixXd& Xs,const Eigen::VectorXd& Ys,
Eigen::VectorXd& Ck) {
Eigen::MatrixXd Pk;
Pk = (Xs.transpose() * Xs).inverse();
Ck = Pk * Xs.transpose() * Ys;
}
Eigen::VectorXd 的读取,下列代码输出-15
Eigen::VectorXd Ck;
Ck.resize(3);
Ck(0)=10;
Ck(1)=15;
Ck(2)=3;
std::cout<<-Ck(1)<<std::endl;