eigen库_eigen库配置 - CSDN
  • Eigen库的简单使用

    千次阅读 2019-09-21 21:34:58
    Eigen是一个C++开源线性代数。提供有关矩阵的的线性代数运算,解方程等功能。 官方的文档在此,本文是简单的使用,快速入门。 http://eigen.tuxfamily.org/dox/classEigen_1_1Transform.html 一、Ubantu安装...

    Eigen是一个C++开源线性代数库。提供有关矩阵的的线性代数运算,解方程等功能。
    官方的文档在此,本文是简单的使用,以SLAM十四讲代码阅读,快速入门。
    http://eigen.tuxfamily.org/dox/classEigen_1_1Transform.html

    一、Ubantu安装eigen

    $ sudo apt-get install libeigen3-dev

    二、eigen的主要模块 Header Contents

    Module contents
    #include <Eigen/Core> Matrix and Array classes, basic linear algebra (including triangular and selfadjoint products), array manipulation
    #include <Eigen/Geometry> Transform, Translation, Scaling, Rotation2D and 3D rotations (Quaternion, AngleAxis)
    #include <Eigen/LU> Inverse, determinant, LU decompositions with solver (FullPivLU, PartialPivLU)
    #include <Eigen/Cholesky> LLT and LDLT Cholesky factorization with solver
    #include <Eigen/Householder> Householder transformations; this module is used by several linear algebra modules
    #include <Eigen/SVD> SVD decompositions with least-squares solver (JacobiSVD, BDCSVD)
    #include <Eigen/QR> QR decomposition with solver (HouseholderQR, ColPivHouseholderQR, FullPivHouseholderQR)
    #include <Eigen/Eigenvalues> Eigenvalue, eigenvector decompositions (EigenSolver, SelfAdjointEigenSolver, ComplexEigenSolver)
    #include <Eigen/Sparse> Sparse matrix storage and related basic linear algebra (SparseMatrix, SparseVector)
    #include <Eigen/Dense> Includes Core, Geometry, LU, Cholesky, SVD, QR, and Eigenvalues header files
    #include <Eigen/Eigen> Includes Dense and Sparse header files (the whole Eigen library)

    三、数组、矩阵、向量的定义

    文档很多,形式多样,具体见下面的代码段及注释。

    
    #inlcude <Eigen/Dense>
    #include <Eigen/Core>
    #include <iostream>
    using namespace std;
    int main( int argc, char** argv )
    {
        // Eigen 中所有向量和矩阵都是Eigen::Matrix,它是一个模板类。它的前三个参数为:数据类型,行,列
        // 声明一个2*3的float矩阵
        Eigen::Matrix<float, 2, 3> matrix_23;
    
        // 同时,Eigen 通过 typedef 提供了许多内置类型,不过底层仍是Eigen::Matrix
        // 例如 Vector3d 实质上是 Eigen::Matrix<double, 3, 1>,即三维向量
        Eigen::Vector3d v_3d;
    	// 这是一样的
        Eigen::Matrix<float,3,1> vd_3d;
    
        // Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>
        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, 5, 6;
        // 输出
        cout << matrix_23 << endl;
    
        // 用()访问矩阵中的元素
        for (int i=0; i<2; i++) {
            for (int j=0; j<3; j++)
                cout<<matrix_23(i,j)<<"\t";
            cout<<endl;
        }
    
        // 矩阵和向量相乘(实际上仍是矩阵和矩阵)
        v_3d << 3, 2, 1;
        vd_3d << 4,5,6;
        // 但是在Eigen里你不能混合两种不同类型的矩阵,像这样是错的
        // Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d;
        // 应该显式转换
        Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
        cout << result << endl;
    
        Eigen::Matrix<float, 2, 1> result2 = matrix_23 * vd_3d;
        cout << result2 << endl;
    
        // 同样你不能搞错矩阵的维度
        // 试着取消下面的注释,看看Eigen会报什么错
        // Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;
    
        // 一些矩阵运算
        // 四则运算就不演示了,直接用+-*/即可。
        matrix_33 = Eigen::Matrix3d::Random();      // 随机数矩阵
        cout << matrix_33 << endl << endl;
    
        cout << matrix_33.transpose() << endl;      // 转置
        cout << matrix_33.sum() << endl;            // 各元素和
        cout << matrix_33.trace() << endl;          // 迹
        cout << 10*matrix_33 << endl;               // 数乘
        cout << matrix_33.inverse() << endl;        // 逆
        cout << matrix_33.determinant() << endl;    // 行列式
    
        // 特征值
        // 实对称矩阵可以保证对角化成功
        Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33.transpose()*matrix_33 );
        cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl;
        cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl;
    
        // 解方程
        // 我们求解 matrix_NN * x = v_Nd 这个方程
        // N的大小在前边的宏里定义,它由随机数生成
        // 直接求逆自然是最直接的,但是求逆运算量大
    
        Eigen::Matrix< double, MATRIX_SIZE, MATRIX_SIZE > matrix_NN;
        matrix_NN = Eigen::MatrixXd::Random( MATRIX_SIZE, MATRIX_SIZE );
        Eigen::Matrix< double, MATRIX_SIZE,  1> v_Nd;
        v_Nd = Eigen::MatrixXd::Random( MATRIX_SIZE,1 );
    
        // 直接求逆
        Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd;
    
        
    	// 通常用矩阵分解来求,例如QR分解,速度会快很多
        x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
       
        return 0;
    }
    

    下面看下如何用eigen来进行旋转、平移的刚体变换矩阵,以及旋转矩阵,欧拉角,四元数之间的转换和运算。

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    #include <Eigen/Core>
    // Eigen 几何模块
    #include <Eigen/Geometry>
    
    /****************************
    * 本程序演示了 Eigen 几何模块的使用方法
    ****************************/
    
    int main ( int argc, char** argv )
    {
        // Eigen/Geometry 模块提供了各种旋转和平移的表示
        // 3D 旋转矩阵直接使用 Matrix3d 或 Matrix3f
        Eigen::Matrix3d rotation_matrix = Eigen::Matrix3d::Identity();
        // 旋转向量使用 AngleAxis, 它底层不直接是Matrix,但运算可以当作矩阵(因为重载了运算符)
        Eigen::AngleAxisd rotation_vector ( M_PI/4, Eigen::Vector3d ( 0,0,1 ) );     //沿 Z 轴旋转 45 度
        cout .precision(3);
        cout<<"rotation matrix =\n"<<rotation_vector.matrix() <<endl;                //用matrix()转换成矩阵
        // 也可以直接赋值
        rotation_matrix = rotation_vector.toRotationMatrix();
        // 用 AngleAxis 可以进行坐标变换
        Eigen::Vector3d v ( 1,0,0 );
        Eigen::Vector3d v_rotated = rotation_vector * v;
        cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
        // 或者用旋转矩阵
        v_rotated = rotation_matrix * v;
        cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
    
        // 欧拉角: 可以将旋转矩阵直接转换成欧拉角
        Eigen::Vector3d euler_angles = rotation_matrix.eulerAngles ( 2,1,0 ); // ZYX顺序,即roll pitch yaw顺序
        cout<<"yaw pitch roll = "<<euler_angles.transpose()<<endl;
    
        // 欧氏变换矩阵使用 Eigen::Isometry
        Eigen::Isometry3d T=Eigen::Isometry3d::Identity();                // 虽然称为3d,实质上是4*4的矩阵
        T.rotate ( rotation_vector );                                     // 按照rotation_vector进行旋转
        T.pretranslate ( Eigen::Vector3d ( 1,3,4 ) );                     // 把平移向量设成(1,3,4)
        cout << "Transform matrix = \n" << T.matrix() <<endl;
    
        // 用变换矩阵进行坐标变换
        Eigen::Vector3d v_transformed = T*v;                              // 相当于R*v+t
        cout<<"v tranformed = "<<v_transformed.transpose()<<endl;
    
        // 对于仿射和射影变换,使用 Eigen::Affine3d 和 Eigen::Projective3d 即可,略
    
        // 四元数
        // 可以直接把AngleAxis赋值给四元数,反之亦然
        Eigen::Quaterniond q = Eigen::Quaterniond ( rotation_vector );
        cout<<"quaternion = \n"<<q.coeffs() <<endl;   // 请注意coeffs的顺序是(x,y,z,w),w为实部,前三者为虚部
        // 也可以把旋转矩阵赋给它
        q = Eigen::Quaterniond ( rotation_matrix );
        cout<<"quaternion = \n"<<q.coeffs() <<endl;
        // 使用四元数旋转一个向量,使用重载的乘法即可
        v_rotated = q*v; // 注意数学上是qvq^{-1}
        cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
    
        return 0;
    }
    

    sophus库是基于eigen库开发的,针对于李群李代数的运算,不知道从哪里盗的图。
    用到的就是这些函数。在这里插入图片描述

    其中ctime用于计时。
    代码读完,应该能理解不少,如果其他需求还需要看官方文档。
    https://blog.csdn.net/augusdi/article/details/12907341
    这篇博客不错

    展开全文
  • C++Eigen库的配置和基本使用

    万次阅读 2019-06-19 19:08:01
    文件夹名字较长,解压后可重命名,如我命名为eigen3,把D:\program\eigen3添加到visual studio项目属性里的目录即可。在程序头部包含 #include <Eigen/Dense> 即可使用Eigen的各项功能了。 2.基本使用...

    1.配置

    1.下载

    http://bitbucket.org/eigen/eigen/get/3.2.5.tar.bz2

    2.配置

    文件夹名字较长,解压后可重命名,如我命名为eigen3,把D:\program\eigen3添加到visual studio项目属性里的库目录即可。在程序头部包含

    #include <Eigen/Dense>

    即可使用Eigen的各项功能了。

    2.基本使用

    // testEigen3.cpp : 定义控制台应用程序的入口点。
    //
     
    #include "stdafx.h"
    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    using namespace std;
    int main()
    {
    	MatrixXf a(4, 1);//必须要进行初始化
    	a = MatrixXf::Zero(4, 1);//初始化为0
    	cout << "初始化为0" << endl << a << endl;
    	a = MatrixXf::Ones(4, 1);//初始化为1,矩阵大小与初始化相关,因为是动态矩阵
    	cout << "初始化为1" << endl << a << endl;
    	a.setZero();//矩阵置零
    	a << 1, 2, 3, 4;//手动赋值
    	MatrixXf b(1, 4);
    	b.setRandom();//随机生成一个矩阵
    	MatrixXf c(3, 3);
    	c.setIdentity();
    	cout << "置单位矩阵:" << endl << c << endl;
    	c.setRandom();
    	MatrixXf d = c;
    	d = d.inverse();
    	cout << "矩阵c:" << endl << c << endl;
    	cout << "矩阵a:" << endl << a << endl;
    	cout << "矩阵b:" << b << endl;
    	cout << "访问a(0):" << endl << a(0) << endl;
    	cout << "矩阵相乘:" << endl << a*b << endl;
    	cout << "矩阵数乘:" << endl << 2 * a << endl;
    	cout << "矩阵c求逆d:" << endl << d << endl;
    	cout << "逆矩阵回乘:" << endl << d*c << endl;
    	cout << "逆矩阵d转置:" << endl << d.transpose() << endl;
    	Vector3d v(1, 2, 3);
    	Vector3d w(1, 0, 0);
    	cout << "向量相加:" << endl << v + w << endl;
    	return 0;
    }
    

    运行结果

    在这里插入图片描述


    作者:鲁中地区有小雨
    来源:CSDN
    原文:https://blog.csdn.net/gao_summer_cola/article/details/78329000
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • eigen库.zip

    2020-07-28 23:31:58
    本资源来自于eigen官方网站下载,可以用于矩阵运算,本人在自己的软件工程中,应用成功。
  • 最新eigen库3.2.10

    2020-07-30 23:32:12
    Eigen是一个高层次的C ++,有效支持线性代数,矩阵和矢量运算,数值分析及其相关的算法。Eigen是一个开源,是ceres solver必备的
  • 最新的eigen库 eigen.rar

    2020-07-27 23:30:15
    Eigen适用范围广,支持包括固定大小、任意大小的所有矩阵操作,甚至是稀疏矩阵;...Eigen支持多种编译环境,开发人员对中的实例在多种编译环境下经过测试,以保证其在不同编译环境下的可靠性和实用性。
  • 为了将Matlab写的运动学程序转化为C++所编写的dll,需要用用到矩阵库Eigen,Eigen库是一个使用C++源码编写的矩阵库,基本上能满足计算中所需要用到的运算,下面介绍一些库的入门学习。 1.首先是关于固定大小矩阵,...

    Eigen是一个高层次的C ++库,有效支持线性代数,矩阵和矢量运算,数值分析及其相关的算法。Eigen是一个开源库,从3.1.1版本开始遵从MPL2许可。

     

    为了将Matlab写的运动学程序转化为C++所编写的dll,需要用用到矩阵库Eigen,Eigen库是一个使用C++源码编写的矩阵库,基本上能满足计算中所需要用到的运算,下面介绍一些库的入门学习。

    1.首先是关于固定大小矩阵,向量的定义,初始化

     

    #include<iostream>

    #include<Eigen/Core>

     

    using namespace std;

    using namespace Eigen;

     

    //import most commen Eigen types

     

    int main(int, char *[])

    {

             Matrix3fm3; //3X3单精度矩阵

             m3<< 1, 2, 3, 4, 5, 6, 7, 8, 9;

             Matrix4fm4 = Matrix4f::Identity();//4X4单位矩阵(单精度)

             Vector4iv4(1, 2, 3, 4);                        //长度为4的整形向量

     

             //输出结果

             std::cout<< "m3\n" << m3 << "\nm4:\n"

                       <<m4 << "\nv4:\n" << v4 << std::endl;

             getchar();

             return0;

    }

    /*学习笔记*/

    /*

             Matrix表示矩阵, Vector表示向量, 数字表示维度,最后f和i分别表示单精度和整形数据类型

             固定大小表示编译时,行数和列数是固定的,这时,Eigen不会分配动态内存。这对于比较小的矩阵比较合适,例如16*16

    */

     

    2.动态定义矩阵Matrix,向量Vector

     

    #include<iostream>

    #include<Eigen/Core>

     

    using namespace std;

    using namespace Eigen;

     

    int main(int, char *[])

    {

             for(int size = 1; size < 4; ++size)

             {

                       MatrixXim(size, size + 1);        //一个整形大小为(size)X(size+1)的矩阵

                       for(int j = 0; j < m.cols(); ++j)//遍历列

                                for(int i = 0; i < m.rows(); ++i)//遍历行

                                         m(i,j) = i + j*m.rows();//使用圆括号m(i, j)访问矩阵的元素

                       std::cout<< m << "\n\n";//打印矩阵

             }

             //动态向量

             VectorXfv(4);   //定义一个4维单精度向量

             //使用圆括号或方括号[]访问向量元素

             v[0]= 1; v[1] = 2; v(2) = 3; v(3) = 4;

             std::cout<< "\nv:\n" << v << endl;

             getchar();

             return0;

    }

     

    //学习心得

    /*

             X表示动态大小

             #include<Eigen/Eigen>将包含所有的Eigen函数。#include<Eigen/Dense>包含所有普通矩阵函数,不包含稀疏矩阵函数,他们会增加编译时间。

    */

     

    3.使用Zero, Ones,UnitX,Constant初始化矩阵

     

    #include<iostream>

    #include<Eigen\Core>

     

    using namespace std;

    using namespace Eigen;

     

    int main(int, char*[])

    {

             intsize = 3;

             floatvalue = 3.0f;

             VectorXfx;        //定义动态向量

             x= VectorXf::Zero(size);  //全0向量

             cout<< x << endl << endl;

             x= VectorXf::Ones(size); //全1向量

             //创建固定大小的基向量

             Vector3fy;

             y= Vector3f::UnitX();       //1 0 0

             cout<< y << endl << endl;

             y= Vector3f::UnitY();       //0 1 0

             cout<< y << endl << endl;

             y= Vector3f::UnitZ();       //0 0 1

             cout<< "创建动态大小的基向量" << endl;

             VectorXfz;

             z= VectorXf::Unit(4, 2);

             cout<< z << endl << endl;

             z= Vector4f(0, 1, 0, 0);

             cout<< z << endl << endl;

             z= Vector4f::UnitY();

             cout<< z << endl << endl;

             getchar();

             return0;

    }

     

    #include<iostream>

    #include<Eigen/Core>

     

    using namespace std;

    using namespace Eigen;

     

    int main(int, char*[])

    {

             floatvalue = 3.0f;

             introws = 3;

             intcols = 4;

             MatrixXfx;

             x= MatrixXf::Zero(rows, cols);

             cout<< x << endl << endl;

             x= MatrixXf::Ones(rows, cols);

             cout<< x << endl << endl;

             x= MatrixXf::Constant(rows, cols, value);//constant:不变的恒定的

             cout<< x << endl << endl;

             x= MatrixXf::Identity(rows, cols);

             cout<< x << endl;

             getchar();

             return0;

    }

     

    4.通过cast转换数据类型

    #include<iostream>

    #include<Eigen\Core>

     

    using namespace std;

    using namespace Eigen;

    //元素通过Matrix::cast()自动转换

    int main(int, char*[])

    {

             Vector3dmd(1, 2, 3);

             Vector3fmf = md.cast<float>();

             cout<< "md = " << md << endl;

             cout<< "mf = " << mf << endl;

             getchar();

             return0;

    }

     

    5.使用逗号初始化矩阵

    #include<iostream>

    #include<Eigen\Core>

     

    using namespace std;

    using namespace Eigen;

     

    int main(int, char *[])

    {

             Matrix3fm;

             m<< 1, 2, 3,

                       4,5, 6,

                       7,8, 9;

             cout<< m << endl;

             getchar();

             return0;

    }

     

    //使用逗号初始化矩阵

     

    6.创建固定大小的矩阵和向量

     

    #include<iostream>

    #include<Eigen/Core>

     

    using namespace Eigen;

    using namespace std;

     

    int main(int, char *[])

    {

             floatvalue = 3.0;

             Matrix3fx;                 //创建一个3x3的单精度矩阵

             x= Matrix3f::Zero();                  //全零矩阵

             cout<< x << endl<<endl;

             x= Matrix3f::Ones();                 //全一矩阵

             cout<< x << endl << endl;

             x= Matrix3f::Constant(value);//全value矩阵

             cout<< x << endl << endl;

             x= Matrix3f::Identity();            //单位矩阵

             cout<< x << endl << endl;

             x= Matrix3f::Random();                    //随机矩阵

             cout<< x << endl << endl;

             x.setZero();                                           //设置x全为0

             cout<< x << endl << endl;

             x.setOnes();                                          //设置x全为1

             cout<< x << endl << endl;

             x.setIdentity();                                     //设置x为单位矩阵

             cout<< x << endl << endl;

             x.setConstant(value);                         //设置x为全value矩阵

             cout<< x << endl << endl;

             x.setRandom();                                              //设置x为随机局长你

             cout<< x << endl << endl;

             getchar();

             return0;

    }

     

    7. 矩阵的简单运算

    #include<iostream>

    #include<Eigen\Core>

     

    using namespace std;

    using namespace Eigen;

     

    int main(int, char*[])

    {

             MatrixXfres(10, 10);                 //动态创建10x10的矩阵

             Matrix3fa, b;

             a= Matrix3f::Identity();  //单位矩阵

             b= Matrix3f::Constant(3);       //全3矩阵

             res= a + b;       //res is resized to size3x3

     

             cout<< a << endl << endl;

             cout<< b << endl << endl;

             cout<< res << endl << endl;

             getchar();

             return0;

    }

     

    到这里,Eigen的基本的赋值,初始化操作已经完全结束了,打过一遍以上的程序,基本上就可以开始编写程序了,下面记录一下我在编写运动学算法的时候会用到的几个技巧:

    1.      将(double)数组转换为Matirx矩阵

    这里,我使用的时候一般是将double(16)转换为Matrix4d,具体用法如下

     

    Map<Matrix4d>(dSTOut, 4, 4) = sTargetMatrix;

     

    这里用到的是Map语句,其中dSTOut为16个元素的double数组,sTargetMatrix为Matrix4d的矩阵,需要注意的是,这里的dSTOut必须是按列排列,才能将矩阵还原

    2.      将Matrix4d转换为(double)数组

    和1中所述类似,这里我一般也是将Matrix4d转换为按列排列的double(16)数组,具体用法如下:

     

    dD_Tm1 = Map<Matrix4d>(dDArmOut_Tm1, 4, 4);

     

    其中dD_Tm1为Matrix4d矩阵,dDArmOut_Tm1为按列排列的16元素double数组,采用此语句即可将Matrix4d转换为按列排列的double数组。

     

    3.在对矩阵进行求逆的运算中,矩阵的逆有可能不存在,为了防止程序崩溃,通常这样写:

     

             BoolbInvertible = false;

             Matirx4dT1 = Matrix4d::zero();

             T1.computeInverseWithCheck(inverseT1,bInvertible);

             if(false == bInvertible)

             {

                       return1;

             }

             traMat_a1= inverseT1 * dTargetMatrix;

    4.      获取矩阵的子矩阵,这种方法在矩阵运算中也经常会用到,之前也查过很多博客,发现其中好多所说的取矩阵方式有有一些问题

     

    uniVec_P1= traMat_a1.block(0, 3, 1, 3);

     

    这是我所使用的方法,才用block方式进行取子矩阵的操作,这里block中有4个参数,前两个为取在矩阵中取子矩阵的首个元素的位置,这里的0, 3代表第1行,第4列,后两个元素分别代表从首个元素开始,所要获取的行数和列数,这里的1,3代表获取每行获取一个元素,总共获取三列。

     

    5.      将按行排列的数组转换为按列排列的数组

    这个方法也适用于将按列排列的数组转换为按行排列的数组

     

    intMatrixTran(double *dInMat)

    {

    double dTS[16] = {0.0};

    int itran = 0;

    int itrannum = 0;

     

    for(int a = 0; a < 16; a ++)

    {

               dTS[a] = dInMat[a];

    }

     

    for(int j = 0; j < 4; j++)

    {

               itrannum = j;

               for(int i = 0; i < 4; i++)

               {

                        dInMat[itran] =dTS[itrannum];

                        itrannum  +=  4;

                        itran++;

               }

              

    }

    return 0;

    }

     

    6.按照SVD的方法求矩阵伪逆

     

    //使用svd方式求伪逆

    template<typename_Matrix_Type_>

    _Matrix_Type_pseudoInverse(const_Matrix_Type_&a,oublepsilon=std::numeric_limits<double>::epsilon())

    {

    Eigen::JacobiSVD< _Matrix_Type_ > svd(a,Eigen::ComputeThinU | Eigen::ComputeThinV);

    double tolerance = epsilon * std::max(a.cols(),a.rows()) *svd.singularValues().array().abs()(0);

    return svd.matrixV() *  (svd.singularValues().array().abs() >tolerance).select(svd.singularValues().array().inverse(),0).matrix().asDiagonal() * svd.matrixU().adjoint();

    }

     

    在Eigen库中,没有直接像matlab中pinv那样求伪逆的程序,但是可以通过SVD方式,求出,方法如上所示,具体没有细致研究程序如何运行,有时间了再详细看这个吧,总的来说,求伪逆可以算是将matlab所写的运动学程序转换为c++时,最难的一个地方了

     

    总结

    虽然最后还可能需要大量的时间,对所写的程序进行调试,但是主要工作都已经完成,这次的编程实践,对于我这边来说可以定性为简单,因为并不需要我对运动学正逆解进行大量的思考,只需要完全按照黄康所写的matlab程序,转写为c语言程序,可算做c语言吧,因为并没有涉及到类的撰写,不过,心中还是有一些冲动,想过要将整个程序转换为类的样式,希望所系的运动学算法可以适用于多台设备,而不是仅仅这一种台车,发现了对于编程人员来说,要对所写的程序有本质的了解,对问题的特征可以进行提炼,从程序一开始,就要对程序进行全局的考虑,否则就会后患无穷,对后期工作造成很坏的影响,就拿这次来说,如果我之前按照黄康那种方式进行程序的撰写,那么在后期和王工进行接口对接的时候,就会面临大量程序接口以及程序内容的修改;其次,发现了程序统一规划的重要性,以及注释的重要性,目前程序的行数到达三千多行,发现自己对整个程序的掌控力已经在慢慢的失去,在开始变成之前,一定要统一接口,统一输入输出参数;另外,还有对于VB.Net的小部分理解,可以说VB.Net是一种很容易上手的语言,并不想c语言和c++那样需要严格的整体格式,感觉编译器在进行编译的时候会做很多事;想完成什么功能,只需要在其中写好相应的function后者sub即可,让我感觉,VB.Net本身就是一个大的累,我们所做的工作只是在类中添加所需要的函数而已。
     

    展开全文
  • Eigen库使用

    千次阅读 2016-11-30 10:16:52
    前言Eigen是一个高层次的C ++库,有效支持 得到的...配置关于Eigen库的配置只需要在属性表包含目录中添加Eigen路径即可。 例子Example 1:#include #include <Eigen/Dense>void main() { Eigen::MatrixXd m(2, 2); /

    前言

    Eigen是一个高层次的C ++库,有效支持 得到的线性代数,矩阵和矢量运算,数值分析及其相关的算法。

    配置

    关于Eigen库的配置只需要在属性表包含目录中添加Eigen路径即可。
    这里写图片描述

    例子

    Example 1:

    #include <iostream>
    #include <Eigen/Dense>
    
    void main()
    {
        Eigen::MatrixXd m(2, 2);            //声明一个MatrixXd类型的变量,它是2*2的矩阵,未初始化
        m(0, 0) = 3;                        //将矩阵第1个元素初始化3
        m(1, 0) = 2.5;                      //将矩阵第3个元素初始化3
        m(0, 1) = -1;  
        m(1, 1) = m(1, 0) + m(0, 1);  
        std::cout << m << std::endl;
    }

    Eigen头文件定义了很多类型,但对于简单的应用程序,可能只使用MatrixXd类型。 这表示任意大小的矩阵(MatrixXd中的X),其中每个条目是双精度(MatrixXd中的d)。 Eigen / Dense头文件定义了MatrixXd类型和相关类型的所有成员函数。 在这个头文件中定义的所有类和函数都在特征名称空间中。

    这里写图片描述

    Example 2:

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    using namespace std;
    int main()
    {  
        MatrixXd m = MatrixXd::Random(3,3);                 //使用Random随机初始化3*3的矩阵
        m = (m + MatrixXd::Constant(3,3,1.2)) * 50;  
        cout << "m =" << endl << m << endl;  
        VectorXd v(3);                                      //这表示任意大小的(列)向量。
        v << 1, 2, 3;  
        cout << "m * v =" << endl << m * v << endl;
    }
    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    using namespace std;
    int main()
    {  
        Matrix3d m = Matrix3d::Random();                    //使用Random随机初始化固定大小的3*3的矩阵
        m = (m + Matrix3d::Constant(1.2)) * 50;  
        cout << "m =" << endl << m << endl;  Vector3d v(1,2,3);    
        cout << "m * v =" << endl << m * v << endl;
    }

    Matrix&Vector

    Example 3:

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    int main()
    {  
        MatrixXd m(2,2);  
        m(0,0) = 3;  
        m(1,0) = 2.5;  
        m(0,1) = -1;  
        m(1,1) = m(1,0) + m(0,1);  
        std::cout << "Here is the matrix m:\n" << m << std::endl;  
        VectorXd v(2);  
        v(0) = 4;  
        v(1) = v(0) - 1;  
        std::cout << "Here is the vector v:\n" << v << std::endl;
    }

    逗号初始化

    Example 4:

    Matrix3f m;
    m << 1, 2, 3,     4, 5, 6,     7, 8, 9;
    std::cout << m;

    通过Resize调整矩阵大小

    矩阵的当前大小可以通过rows(),cols()和size()检索。 这些方法分别返回行数,列数和系数数。 通过resize()方法调整动态大小矩阵的大小。
    Example 5:

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    int main()
    {  
        MatrixXd m(2,5);                //初始化大小2*5
        m.resize(4,3);                  //重新调整为4*3
        std::cout << "The matrix m is of size "            << m.rows() << "x" << m.cols() << std::endl;  
        std::cout << "It has " << m.size() << " coefficients" << std::endl;  
        VectorXd v(2);  v.resize(5);  
        std::cout << "The vector v is of size " << v.size() << std::endl;
        std::cout << "As a matrix, v is of size "            << v.rows() << "x" << v.cols() << std::endl;
    }

    通过赋值调整矩阵大小

    Example 6:

    MatrixXf a(2, 2); 
    std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl; 
    MatrixXf b(3, 3); 
    a = b; 
    std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl;

    Eigen + - * 等运算

    Eigen通过通用的C ++算术运算符(例如+, - ,)或通过特殊方法(如dot(),cross()等)的重载提供矩阵/向量算术运算。对于Matrix类(矩阵和向量) 只被重载以支持线性代数运算。 例如,matrix1 matrix2表示矩阵矩阵乘积。
    Example 7:

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    int main()
    {  
        Matrix2d a;  a << 1, 2,       3, 4;  
        MatrixXd b(2,2); 
        b << 2, 3,       1, 4; 
        std::cout << "a + b =\n" << a + b << std::endl;
        std::cout << "a - b =\n" << a - b << std::endl; 
        std::cout << "Doing a += b;" << std::endl; 
        a += b;  
        std::cout << "Now a =\n" << a << std::endl; 
        Vector3d v(1,2,3);  
        Vector3d w(1,0,0);  
        std::cout << "-v + w - v =\n" << -v + w - v << std::endl;
    }

    Example 8:

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    int main()
    {  
        Matrix2d a;  
        a << 1, 2,       3, 4;  
        Vector3d v(1,2,3);  
        std::cout << "a * 2.5 =\n" << a * 2.5 << std::endl; 
        std::cout << "0.1 * v =\n" << 0.1 * v << std::endl; 
        std::cout << "Doing v *= 2;" << std::endl;  v *= 2; 
        std::cout << "Now v =\n" << v << std::endl;
    }

    矩阵转置、共轭和伴随矩阵

    MatrixXcf a = MatrixXcf::Random(2,2);
    cout << "Here is the matrix a\n" << a << endl;
    cout << "Here is the matrix a^T\n" << a.transpose() << endl;
    cout << "Here is the conjugate of a\n" << a.conjugate() << endl;
    cout << "Here is the matrix a^*\n" << a.adjoint() << endl;

    禁止如下操作:

    a = a.transpose(); // !!! do NOT do this !!!

    但是可以使用如下函数:

    a.transposeInPlace();

    此时a被其转置替换。

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    int main()
    {
        Matrix2i a;
        a << 1, 2, 3, 4;
        std::cout << "Here is the matrix a:\n" << a << std::endl;
        a = a.transpose(); // !!! do NOT do this !!!
        std::cout << "and the result of the aliasing effect:\n" << a << std::endl;
    }

    矩阵* 矩阵和矩阵* 向量操作

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    int main()
    {  
        Matrix2d mat;  mat << 1, 2,         3, 4;  
        Vector2d u(-1,1), v(2,0);  
        std::cout << "Here is mat*mat:\n" << mat*mat << std::endl;  
        std::cout << "Here is mat*u:\n" << mat*u << std::endl;  
        std::cout << "Here is u^T*mat:\n" << u.transpose()*mat << std::endl; 
        std::cout << "Here is u^T*v:\n" << u.transpose()*v << std::endl;
        std::cout << "Here is u*v^T:\n" << u*v.transpose() << std::endl;  
        std::cout << "Let's multiply mat by itself" << std::endl;  
        mat = mat*mat;  std::cout << "Now mat is mat:\n" << mat << std::endl;
    }

    点乘和叉乘

    对于点积和叉乘积,需要使用dot()和cross()方法。

    #include <iostream>
    #include <Eigen/Dense>
    using namespace Eigen;
    using namespace std;
    int main()
    {  
        Vector3d v(1,2,3);  
        Vector3d w(0,1,2); 
        cout << "Dot product: " << v.dot(w) << endl; 
        double dp = v.adjoint()*w; // automatic conversion of the inner product to a scalar  
        cout << "Dot product via a matrix product: " << dp << endl;  
        cout << "Cross product:\n" << v.cross(w) << endl;
    }
    #include <iostream>
    #include <Eigen/Dense>
    using namespace std;
    int main()
    {  
        Eigen::Matrix2d mat;
        mat << 1, 2,         3, 4;
        cout << "Here is mat.sum():       " << mat.sum()       << endl;  
        cout << "Here is mat.prod():      " << mat.prod()      << endl; 
        cout << "Here is mat.mean():      " << mat.mean()      << endl; 
        cout << "Here is mat.minCoeff():  " << mat.minCoeff()  << endl;  
        cout << "Here is mat.maxCoeff():  " << mat.maxCoeff()  << endl; 
        cout << "Here is mat.trace():     " << mat.trace()     << endl;
    }

    数组的运算(未完待续)

    Eigen最小二乘估计

    最小平方求解的最好方法是使用SVD分解。 Eigen提供一个作为JacobiSVD类,它的solve()是做最小二乘解。式子为Ax=b
    经过和Matlab对比。

    #include <iostream>
    #include <Eigen/Dense>
    using namespace std;
    using namespace Eigen;
    int main()
    {   
        MatrixXf A = MatrixXf::Random(3, 2);  
        cout << "Here is the matrix A:\n" << A << endl;  
        VectorXf b = VectorXf::Random(3);   
        cout << "Here is the right hand side b:\n" << b << endl;  
        cout << "The least-squares solution is:\n"        << A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b) << endl;
    }

    这里写图片描述

    展开全文
  • Eigen库

    千次阅读 2019-09-14 14:51:04
    参考:Eigen英文手册 Eigen的API手册写的真心详细,推荐阅读. Eigen中涉及的分解方法主要包括,Cholesky分解、QR分解、SVD分解、特征值分解(eigendecomposition)等. 1、线性求解问题中几种分解方法的比较 针对...
  • Eigen库的使用

    千次阅读 2018-09-13 22:17:51
    首先在官网下载Eigen库,下载地址 解压缩文件可以得到以下的文件 我们主要使用的是其中的Eigen文件夹,这其中就是主要的文件。 由于Eigen都是由头文件组成的,所以包含相应的库路径即可。 在VS201...
  • cmake使用eigen库

    千次阅读 2018-07-02 11:35:45
    Eigen是一个C++开源线性代数库:提供矩阵的...cmake使用eigen库 find_package(Eigen3) INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIR}) 程序中使用eigen库,引用各功能头文件 #include&lt;Eigen/core&gt;...
  • 【eigen】windows下使用eigen库

    千次阅读 2019-07-28 16:18:36
    下载eigen源码包,如:eigen-eigen-323c052e1731.zip。 将解压后的eigen-eigen-323c052e1731目录下的Eigen目录拷贝到自己工程下。 在工程中添加Eigen目录下的所有文件。 在自己的文件里包含eigen头文件,如:#...
  • Eigen的C++,配置了就可以用,亲测好用。VS2010和VS2015都试过了。
  • 查看当前正在使用的Eigen版本

    万次阅读 2018-09-14 16:59:40
    Eigen库版本的定义找了好久在/home/david/MySoft/Eigen3/Eigen/src/Core/util/Macros.h 里面。 Macros.h是Eigen库所有宏定义的文件。从下图可以看出我的Eigen版本是3.3.4.
  • 1 在clion工程下的根目录下的CMakeLists.txt下加入如下内容: find_package(Eigen3 REQUIRED) include_directories("/usr/include/eigen3") 2 编译整个工程。 3 函数内输入#include <...即可调用Eigen库
  • C++通过CMakeLists使用Eigen库

    千次阅读 2019-11-22 16:08:27
    即可引入Eigen库,但是直接g++编译的时候是通不过的。提示 Eigen/Eigen: No such file or directory。这里需要将Eigen库加入到库中,可以通过CMakeLists实现,如下: CMakeLists.txt cmake_minimum_required...
  • 有关eigen库的一些基本使用方法 https://blog.csdn.net/r1254/article/details/47418871
  • 查看Eigen库版本

    2020-04-27 20:09:27
    参考:Ubuntu16.04下怎么查看自己的eigen版本号 打开eigen安装路径里的文件夹:F:\eigen3\Eigen\src\Core\util 里面的 版本为3.3.7
  • 使用eigen库时出现找不到文件的错误 在编译点云处理程序时,会使用pcl,pcl依赖于eigen,出现错误 fatal error: Eigen/Core: No such file or directory 问题原因 出现这个错误的原因是eigen默认安装在/usr/...
  • Eigen库-求矩阵特征值分解

    千次阅读 2018-09-11 15:23:03
    实验证明无论是opencv还是Eigen,通过特征值分解求最小二乘解都不准确,他们的比较小的特征值的估计特不靠谱,而最小二乘解是最小特征值对应的特征向量。只有matlab的分解结果足够准确,可以用于最小二乘解求解。 ...
  • 由于eigen库的安装都是把头文件放在eigen3这个目录下的,但是ceres等库的头文件都是includeEigen/core的所以查了很多方法都没有效果,比如说设置g++之类 还有建立 软映射 ln -sf 编译器都没有通过,最后一个很简单的...
1 2 3 4 5 ... 20
收藏数 16,645
精华内容 6,658
关键字:

eigen库