对于EIgen数学计算库,官网介绍只需要包含头文件即可,无需编译成动态库,极大提高了多平台的可移植性。windows针对QNX系统有交叉编译工具链qcc,可以直接对c++文件进行编译。因此只需要将test.c文件放在eigen文件夹下直接进行编译即可。
以下内容可以解决移植过程中的报错。
‘abort’ was not declared in this scope · Issue #1 · captainigloo/spark-web-embd-rest-json
用户对问题"编译Eigen以在QNX 6上运行"的回答 - 问答 - 腾讯云开发者社区-腾讯云
#include
#include /* fopen, fputs, fclose, stderr */
#include /* abort, NULL */
#include
using std::expf;
#include
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::Vector3d;
int main()
{
MatrixXd m = MatrixXd::Random(3,3);
m = (m + MatrixXd::Constant(3,3,1.2)) * 50;
std::cout << "m =" << std::endl << m << std::endl;
// VectorXd v(3);
// v << 1, 2, 3;
// std::cout << "m * v =" << std::endl << m * v << std::endl;
Vector3d v(1,2,3);
std::cout << "m * v =" << std::endl << m * v << std::endl;
while(1);
}
报错:unfinded reference to sqrtf;
编译指令:gcc -I. test.cc -o test_eigen -lm
#include
#include /* fopen, fputs, fclose, stderr */
#include /* abort, NULL */
#include
using std::expf;
#include
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::Vector3d;
template <typename T>
static void matrix_mul_matrix(T* p1, int iRow1, int iCol1, T* p2, int iRow2, int iCol2, T* p3)
{
if (iRow1 != iRow2) return;
//列优先
//Eigen::Map< Eigen::Matrix > map1(p1, iRow1, iCol1);
//Eigen::Map< Eigen::Matrix > map2(p2, iRow2, iCol2);
//Eigen::Map< Eigen::Matrix > map3(p3, iCol1, iCol2);
//行优先
Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map1(p1, iRow1, iCol1);
Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map2(p2, iRow2, iCol2);
Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map3(p3, iCol1, iCol2);
map3 = map1 * map2;
}
int main(int argc, char* argv[])
{
//1. 矩阵的定义
Eigen::MatrixXd m(2, 2);
Eigen::Vector3d vec3d;
Eigen::Vector4d vec4d(1.0, 2.0, 3.0, 4.0);
//2. 动态矩阵、静态矩阵
Eigen::MatrixXd matrixXd;
Eigen::Matrix3d matrix3d;
//3. 矩阵元素的访问
m(0, 0) = 1;
m(0, 1) = 2;
m(1, 0) = m(0, 0) + 3;
m(1, 1) = m(0, 0) * m(0, 1);
std::cout << m << std::endl << std::endl;
//4. 设置矩阵的元素
m << -1.5, 2.4,
6.7, 2.0;
std::cout << m << std::endl << std::endl;
int row = 4;
int col = 5;
Eigen::MatrixXf matrixXf(row, col);
matrixXf << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20;
std::cout << matrixXf << std::endl << std::endl;
matrixXf << Eigen::MatrixXf::Identity(row, col);
std::cout << matrixXf << std::endl << std::endl;
//5. 重置矩阵大小
Eigen::MatrixXd matrixXd1(3, 3);
m = matrixXd1;
std::cout << m.rows() << " " << m.cols() << std::endl << std::endl;
//6. 矩阵运算
m << 1, 2, 7,
3, 4, 8,
5, 6, 9;
std::cout << m << std::endl;
matrixXd1 = Eigen::Matrix3d::Random();
m += matrixXd1;
std::cout << m << std::endl << std::endl;
m *= 2;
std::cout << m << std::endl << std::endl;
std::cout << -m << std::endl << std::endl;
std::cout << m << std::endl << std::endl;
//7. 求矩阵的转置、共轭矩阵、伴随矩阵
std::cout << m.transpose() << std::endl << std::endl;
std::cout << m.conjugate() << std::endl << std::endl;
std::cout << m.adjoint() << std::endl << std::endl;
std::cout << m << std::endl << std::endl;
m.transposeInPlace();
std::cout << m << std::endl << std::endl;
//8. 矩阵相乘、矩阵向量相乘
std::cout << m*m << std::endl << std::endl;
vec3d = Eigen::Vector3d(1, 2, 3);
std::cout << m * vec3d << std::endl << std::endl;
std::cout << vec3d.transpose()*m << std::endl << std::endl;
//9. 矩阵的块操作
std::cout << m << std::endl << std::endl;
std::cout << m.block(1, 1, 2, 2) << std::endl << std::endl;
std::cout << m.block<1, 2>(0, 0) << std::endl << std::endl;
std::cout << m.col(1) << std::endl << std::endl;
std::cout << m.row(0) << std::endl << std::endl;
//10. 向量的块操作
Eigen::ArrayXf arrayXf(10);
arrayXf << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
std::cout << vec3d << std::endl << std::endl;
std::cout << arrayXf << std::endl << std::endl;
std::cout << arrayXf.head(5) << std::endl << std::endl;
std::cout << arrayXf.tail(4) * 2 << std::endl << std::endl;
//11. 求解矩阵的特征值和特征向量
Eigen::Matrix2f matrix2f;
matrix2f << 1, 2, 3, 4;
Eigen::SelfAdjointEigenSolver<Eigen::Matrix2f> eigenSolver(matrix2f);
if (eigenSolver.info() == Eigen::Success) {
std::cout << eigenSolver.eigenvalues() << std::endl << std::endl;
std::cout << eigenSolver.eigenvectors() << std::endl << std::endl;
}
//12. 类Map及动态矩阵的使用
int array1[4] = { 1, 2, 3, 4 };
int array2[4] = { 5, 6, 7, 8 };
int array3[4] = { 0, 0, 0, 0};
matrix_mul_matrix(array1, 2, 2, array2, 2, 2, array3);
for (int i = 0; i < 4; i++)
std::cout << array3[i] << std::endl;
while (1)
{
/* code */
}
return 0;
}
运行简单的Eigen示例,虚拟机中计算矩阵求逆所需时间为3ms,工控机上应该快很多。
#include
#include /* fopen, fputs, fclose, stderr */
#include /* abort, NULL */
#include
using std::expf;
#include
#include
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::Vector3d;
#include
//
#include
#include
#include
#include
#include
#define MATRIX_SIZE 50
int main(int,char**)
{
uint64_t start_cyc,end_cyc;
uint64_t cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
// Eigen中所有的向量和矩阵都是Eigen::Matrix,
// 它是一个模板类。它是一个模板类。
// 它的前三个参数为数据类型,行,列
Eigen::Matrix<float,2,3> matrix_23;
// 同时,Eigen通过 typedef 提供了许多内置类型,不过底层仍是Eigen::Matrix
// 例如:Vector3d 实质上是Eigen::Matrix 即三维向量
Eigen::Vector3d v_3d;
Eigen::Matrix<float,3,1> vd_3d;
//Matrix3d 实质上时Eigen::Matrix
Eigen::Matrix3d matrix_33=Eigen::Matrix3d::Zero(); //初始化为零
//如果不确定矩阵大小,可以使用动态大小的矩阵
Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> matrix_dynamic;
//更简单的
Eigen::MatrixXd matrix_x;
//对Eigen阵的操作
//输入数据(初始化)
matrix_23<<1,2,3,4,2,5;
//输出
std::cout<<"matrix 2x3 :\n"<<matrix_23<<std::endl;
//使用()访问矩阵中的元素
std::cout<<"print maxtrix 2x3:"<<std::endl;
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
std::cout<<matrix_23(i,j)<<"\t";
}
std::cout<<std::endl;
}
//矩阵和向量相乘(实际上仍是矩阵和矩阵)
v_3d<<3,2,1;
vd_3d<<3,5,3;
//注:在Eigen中不能混合两种不同类型的矩阵,如下:
// Eigen::Matrix result_wrong_type=matrix_23*v_3d;
//应该进行显式类型转换
Eigen::Matrix<double,2,1>result=matrix_23.cast<double>()*v_3d;
std::cout<<"[1 2 3,4 2 5]*[3 2 1]:"<<result.transpose()<<std::endl;
Eigen::Matrix<float,2,1>result2=matrix_23*vd_3d;
std::cout<<"[1 2 3,4 2 5]*[3 5 3]:"<<result2.transpose()<<std::endl;
// 不能搞错矩阵维度,可尝试取消注释,看一下Eigen会报什么错
// Eigen::Matrixresult3=matrix_23*vd_3d;
//四则运算,直接用=-*/
matrix_33=Eigen::Matrix3d::Random();
std::cout<<"random matrix: \n"<<matrix_33<<std::endl;
std::cout<<"transpose: \n"<<matrix_33.transpose()<<std::endl;
std::cout<<"sum: "<<matrix_33.sum()<<std::endl;
std::cout<<"trace: "<<matrix_33.trace()<<std::endl;
std::cout<<"times 10: "<<10*matrix_33<<std::endl;
std::cout<<"inverse: "<<"\n"<<matrix_33.inverse()<<std::endl;
std::cout<<"det: "<<matrix_33.determinant()<<std::endl;
//特征值
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver(matrix_33.transpose()*matrix_33);
std::cout<<"Eigen value: \n"<<eigen_solver.eigenvalues()<<std::endl;
std::cout<<"Eigen Vector: \n"<<eigen_solver.eigenvectors()<<std::endl;
//解方程
//求解 matrix_NN * x=v_ND 方程
// N 的大小 在前面的宏已定义,它由随机数产生
//直接求逆自然是最直接的,但是运算量大
Eigen::Matrix<double,MATRIX_SIZE,MATRIX_SIZE> matrix_NN=
Eigen::MatrixXd::Random(MATRIX_SIZE,MATRIX_SIZE);
matrix_NN=matrix_NN*matrix_NN.transpose(); //保证半正定
Eigen::Matrix<double,MATRIX_SIZE,1> v_Nd=Eigen::MatrixXd::Random(MATRIX_SIZE,1);
// clock_t time_stt = clock(); //计时
start_cyc = ClockCycles();
//直接求逆
Eigen::Matrix<double,MATRIX_SIZE,1>x=matrix_NN.inverse()*v_Nd;
end_cyc = ClockCycles();
double tbs = (double) (end_cyc - start_cyc) / cps;
std::cout<<"time of normal inverse is:"<<tbs<<"s"<<std::endl;
std::cout<<"x= "<<x.transpose()<<std::endl;
//通常使用矩阵分解来求解,例如:QR 分解,速度会快很多
// time_stt=clock();
start_cyc = ClockCycles();
x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
end_cyc = ClockCycles();
tbs = (double) (end_cyc - start_cyc) / cps;
std::cout<<"time of Qr decomposition is : "<<tbs <<"ms"<<std::endl;
std::cout<<"x= "<<x.transpose()<<std::endl;
//对于正定矩阵,还可以用cholesky分解求解方程
// time_stt=clock();
start_cyc = ClockCycles();
x=matrix_NN.ldlt().solve(v_Nd);
end_cyc = ClockCycles();
tbs = (double) (end_cyc - start_cyc) / cps;
std::cout<<"time of ldlt decomposition is :"<<tbs <<"s"<<std::endl;
std::cout<<"x= "<<x.transpose()<<std::endl;
sleep(3);
return 0;
}
在IDE下编译仍存在报错。
make[2]: Entering directory `C:/Users/ronaldo/Desktop/QNET/test_eigen/x86/o-g'
C:/QNX641/host/win32/x86/usr/bin/qcc -Vgcc_ntox86 -c -Wc,-Wall -Wc,-Wno-parentheses -I. -IC:/Users/ronaldo/Desktop/QNET/test_eigen/x86/o -IC:/Users/ronaldo/Desktop/QNET/test_eigen/x86/o-g -IC:/Users/ronaldo/Desktop/QNET/test_eigen/x86 -IC:/Users/ronaldo/Desktop/QNET/test_eigen -IC:/QNX641/target/qnx6/usr/include -g -DVARIANT_g -DBUILDENV_qss C:/Users/ronaldo/Desktop/QNET/test_eigen/test_eigen.cc
C:/QNX641/host/win32/x86/usr/bin/rm -f C:/Users/ronaldo/Desktop/QNET/test_eigen/x86/o-g/test_eigen_g
C:/QNX641/host/win32/x86/usr/bin/qcc -Vgcc_ntox86 -lang-c++ -lang-c++ -oC:/Users/ronaldo/Desktop/QNET/test_eigen/x86/o-g/test_eigen_g test_eigen.o -L . -L C:/QNX641/target/qnx6/x86/lib -L C:/QNX641/target/qnx6/x86/usr/lib -Wl,--rpath-link . -Wl,--rpath-link C:/QNX641/target/qnx6/x86/lib -Wl,--rpath-link C:/QNX641/target/qnx6/x86/usr/lib -l-lm -g
C:\QNX641\host\win32\x86\usr\bin\ntox86-ld: cannot find -l-lm
cc: C:/QNX641/host/win32/x86/usr/bin/ntox86-ld caught signal 1
make[2]: *** [C:/Users/ronaldo/Desktop/QNET/test_eigen/x86/o-g/test_eigen_g] Error 1
make[2]: Target `all' not remade because of errors.
make[2]: Leaving directory `C:/Users/ronaldo/Desktop/QNET/test_eigen/x86/o-g'
make[1]: [all] Error 2 (ignored)
make[1]: Leaving directory `C:/Users/ronaldo/Desktop/QNET/test_eigen/x86'
报错:cannot find -l-lm,需要在IDE中加上编译条件”-lm“,如下所示。
在图中的”socket“改成”m“,即可实现在IDE编译。