Eigen库使用入门

2023-11-18

为了将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本身就是一个大的累,我们所做的工作只是在类中添加所需要的函数而已。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Eigen库使用入门 的相关文章

  • 覆盖 R 中 C++ 编译标志的系统默认值

    我正在使用 RcppEigen 为我的 R 代码编写一些 C 函数 并且我想尽可能优化它们的编译 当我过去使用 Eigen 时 O3 和 fopenmp 给我带来了显着的提升 关注德克的advice 我编辑了 R Makevars 以便我的
  • 使用 std::vector 初始化 Eigen::vector

    我以前见过它 但我不记得如何有效地初始化Eigen Vector已知长度的std vector相同长度的 这是一个很好的例子 std vector
  • 如何在 Eigen 中计算张量的外积?

    在特征中 我们可以使用以下方法轻松地进行张量收缩 Tensor
  • 特征:矩阵到四元数和后面有不同的结果

    我使用 Eigen 库将矩阵转换为四元数 但是当我将其中一个矩阵转换为四元数并将其烧回时 它变成了另一个矩阵 即单位矩阵 我使用的旋转矩阵是从变换矩阵分解而来的 Eigen Matrix3f R3d R topLeftCorner lt 3
  • 调整 Eigen::Ref 大小的解决方法

    我想使用 Eigen Ref 来使用 Eigen Matrix 参数来实现非模板函数 我的问题是 在这些函数中 我可能必须调整 Eigen Ref 引用的矩阵的大小 我知道 一般而言 不应调整 Eigen Ref 的大小 因为它可以映射到表
  • Eigen 库 - 矩阵的伪逆(Matlab - pinv)

    我正在尝试使用特征库找到矩阵的伪逆 他们有一个类确实实现了它 但是我不知道如何编写脚本语法 这是它在网站上显示的方式 https eigen tuxfamily org dox classEigen 1 1CompleteOrthogona
  • eigen3 与 libfmt >= 9.0

    我曾经能够将 Eigen3 数组 矩阵传递给 spdlog 它内部使用 libfmt 从 libfmt 9 0 0 开始 这些类型不再由 libfmt 格式化 无需进一步的代码 fmt 通过专门化支持自定义类型fmt formatter
  • 如何将 Eigen 库添加到 C++ 项目中

    可能是一个愚蠢 简单的问题 但我一直无法找到答案 我不知道如何使用 CodeBlocks c 添加库 我从以下位置下载了 zip 文件http eigen tuxfamily org index php title Main Page ht
  • Eigen Matrix 与 Numpy Array 乘法性能

    I read 在这个问题中 https stackoverflow com questions 10366054 c performance in eigen librar that eigen具有非常好的性能 但是 我尝试比较eigen
  • Rcpp 相当于 rowsum [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在寻找 R 函数的快速替代方案r
  • 如何修补 Eigen 3.3.7 以解决 GCC 8.2.1 错误(arm-none-eabi 8-2018q4-major 工具链)?

    我试图用以下命令编译 Eigen 3 3 7Arm的裸机8 2018q4 major工具链 https launchpad net gcc arm embedded announcement 15181并看到完全相同的错误 请参阅x86 6
  • 在 Android 中使用 iBeacons 进行三边测量

    我们希望使用 iBeacons 实现某种室内位置确定 这篇文章看起来真的很有趣 http techblog rga com determining indoor position using ibeacon 其中作者使用 Eigen C 库
  • 在特征中混合标量类型

    include
  • Eigen::Ref<> 类的正确用法

    Eigen 引入了 Ref 类 以便在不需要编写模板函数时以 Eigen 对象作为参数编写函数 而无需使用不必要的临时变量 人们可以读到这一点here http eigen tuxfamily org dox TopicFunctionTa
  • Eigen SparseMatrix 的零拷贝构造

    我有以下问题 我有一个Eigen SparseMatrix我需要通过网络发送 而我的网络库仅支持发送原始类型的数组 我可以通过执行类似的操作来检索指向 SparseMatrix 的支持数组的指针 这是支持对象的代码 https eigen
  • 如何访问 C++ Eigen 数组中的多个元素?

    我想检索特征数组中的某些元素并将它们作为向量返回 我使用以下代码 Eigen ArrayXXi test test resize 5 5 test setRandom Eigen Matrix
  • Eigen static libaligned_free“双重释放或损坏”

    这是一个延续较早的帖子 https stackoverflow com questions 70788173 eigen static lib memory align 但这一次希望有一个更好的例子 设置向量时 这个简单的测试会崩溃 我正在
  • 为什么选择 Eigen 作为 TensorFlow? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 TensorFlow白皮书提到使用了Eigen 是否有关于如何选择 Eigen 的公开解释 它们是在 T
  • 特征密集稀疏矩阵乘积是线程化的吗?

    我知道稀疏密集产品是根据文档进行线程化的 https eigen tuxfamily org dox TopicMultiThreading html https eigen tuxfamily org dox TopicMultiThre
  • 访问特征矩阵的行向量时复制或引用

    我正在使用的代码Eigen http eigen tuxfamily org index php title Main Page矩阵库 我注意到在整个代码中 有如下访问器 RowVector3f V size t vertex index

随机推荐

  • 在Linux远程服务器上搭建JavaWeb开发环境

    配置 远程linux服务器版本为CentOS7 6 使用的是阿里云服务器 目录 1 安装JDK 1 1 查看yum源中JDK版本 1 2 使用yum安装JDK1 8 1 3 查看是否安装成功 2 安装MySQL 2 1 查看是否已安装mys
  • C++ 循环

    有时候 程序需要多次执行同一块代码 一般情况下 语句是顺序执行的 函数中的第一个语句先执行 接着是第二个语句 依此类推 循环语句允许多次执行一个语句或语句组 大多数编程语言中循环语句的一般形式 循环类型 C 编程语言提供了以下几种循环类型
  • Anaconda环境的创建、激活、删除和管理

    1 Anaconda环境的创建 conda create n 环境的名字 自定义 python 3 7 其中环境的名字 自定义 表示创建环境的名字 可以自定义 建议为英文 后面python 3 7表示创建的解释器的版本 conda crea
  • 这里有141个创业公司的死亡案例,看鸡汤不如听教训

    今天我们打算跟大家聊聊失败 关于成功的方法论有着趋同性 多半与 天时地利人和 有关 而关于失败 却很少有人愿意公开谈起 也许因为野兽总是不想将伤口暴露在外 探讨失败的意义 可能远远大于成功 因为面对挫折 即使自认为最无畏的人也会有这样的时刻
  • PicGo安装与配置-Gitee图床

    PicGo安装与配置 Gitee图床 文章目录 PicGo安装与配置 Gitee图床 1 前言 2 下载 3 安装 4 Gitee 5 Node js 6 配置PicGo 6 1 PicGo界面配置 6 2 npm安装PicGo插件Gite
  • 空格的正则表达式

    在正则表达式想使用空格的时候不能采用 s的方法 因为 s指的是空白 就是所有空白 如果想表示单纯的空格的话可以采用 方括号本身就是匹配其中的字符 那么其中放空格就是匹配空格 如果有其他正则表达式问题可以查看 https blog csdn
  • GCP reliable google cloud infrastructure, devops lab

    最后更新2022 03 13 先到menu source repository里建立repository 还是不很好找 source repository在CI CD分类里面 点右上角的add repository按钮 输名字devops
  • uniapp集成unipush2.0

    unipush3 0集成 unipush推出2 0服务 之前一直用的1 0 现在项目推荐使用2 0 最近也是对2 0这个推送做了测试 下面就主要对华为这个来总结一下 其余的厂商大同小异 1 push1 0和2 0对比 个人理解 2 0比1
  • 深入浅出 RPC - 深入篇

    深入篇 我们主要围绕 RPC 的功能目标和实现考量去展开 一个基本的 RPC 框架应该提供什么功能 满足什么要求以及如何去实现它 RPC 功能目标 RPC 的主要功能目标是让构建分布式计算 应用 更容易 在提供强大的远程调用能力时不损失本地
  • 深度学习——制作自己的VOC图像分割数据集

    1 数据集介绍 COCO数据集有80个类别 VOC数据集有20个类别 当这些数据集类别中没有自己需要的时候 就需要自己动手做自己的数据集了 我自己在做数据集的时候主要使用到了labelme和labelImg两个工具 labelme主要是制作
  • string str="i"与 String str=new String("i")和String s = new String("abc")的解释!!!

    string str i 与 String str new String i String x 张三 String y 张三 String z new String 张三 System out println x y true System
  • Android中的回调

    mark一句比较好的话 A类中调用B类的某个方法C 然后B类反过来调用A类的方法D D这个方法就叫回调 在不同的状态 回调 我们的实现类 来达到接口和实现和分类 先定义一个接口 监听接口 来在主界面监听界面变化状态 public inter
  • sqli-labs通关攻略54-65[Challenges]

    Advanced Injections 文章目录 Advanced Injections less 54 less 55 less 56 less 60 less 62 less 63 less 64 less 65 最后一篇补上 less
  • yolov3 数据预处理部分实现细节

    参考 https mp weixin qq com s T9LshbXoervdJDBuP564dQ https blog csdn net qm5132 article details 83651291 https mp weixin q
  • 软件工程复习10:软件设计与实现

    作者 非妃是公主 专栏 软件工程 个性签 顺境不惰 逆境不馁 以心制境 万事可成 曾国藩 专栏地址 软件工程专栏地址 专栏系列文章 软件工程复习01 软件工程概述 软件工程复习02 个人技术 软件工程复习03 个人软件流程 软件工程复习04
  • Java经典面试题:Redis 和 Mysql 如何保证数据一致性

    Redis 和 Mysql 如何保证数据一致性 引言 重要性 挑战 Redis和MySQL概述 Redis Remote Dictionary Server MySQL 数据一致性概述 Redis的数据一致性机制 MySQL的数据一致性机制
  • vim常用操作——vim中执行shell

    vim常用操作 vim中执行shell vim中执行shell命令 有以下四种形式 单纯执行shell命令 不更改文件 形式 command 解释 不退出vim 并执行shell命令command 将命令输出显示在vim的命令区域 不会改变
  • 文件,文件夹操作(权限设置+操作)

    文件权限 r 可读权限 值为4 w 可写权限 值为2 x 可执行权限 值为1 文件权限说明 文件夹权限755 文件权限644 一个文件或文件夹的三种用户 第一位是拥有者 第二个是组内用户 第三个是组外用户 权限举例说明 文件夹权限为755
  • Project:解决问题:在Microsoft project2016中如何编辑一周七天工作日

    1 目的 1 1 想 在Microsoft project2016中如何编辑一周七天工作日 2 操作 2 1 项目 gt 更改工作时间 gt 对于日历 标准 项目日历 gt 工作周 gt 详细信息 gt 选中 星期日 和 星期六 gt 对所
  • Eigen库使用入门

    为了将Matlab写的运动学程序转化为C 所编写的dll 需要用用到矩阵库Eigen Eigen库是一个使用C 源码编写的矩阵库 基本上能满足计算中所需要用到的运算 下面介绍一些库的入门学习 1 首先是关于固定大小矩阵 向量的定义 初始化