矩阵计算库eigen在QNX上的移植
eigen在QNX上的移植
对于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 50int 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编译。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
