`

Eigen库:那些年我们一起经历的bug

c++ 
阅读更多
1、使用auto声明新变量时不要局部eval()
这句话神马意思呢? 我们知道,在C++函数中最好不要返回局部变量,否则可能产生因为局部变量被回收而引发的错误。
而这个问题正是源于此。
在以下这个bug中:
http://eigen.tuxfamily.org/bz/show_bug.cgi?id=505 
“a*b”就会引发自动的eval(),从而产生局部变量,该局部变量被一个表达式所引用,导致结果不可预知。
最新版本的Eigen已经解决了这个问题~~~那么,这个bug是不是完全不存在了呢?
答案是NO。。。。
看以下的代码:

    auto A_mul_B_plus_C = C + (A * B).colwise().sum();
    auto A_mul_B_Eval_plus_C = C + (A * B).colwise().sum().eval();

二者的结果都是表达式,但是第二个表达式中局部变量被eval()了,产生了一个临时的Matrix,该临时变量会被回收,导致结果的不正确。
解决方案:
  • 1、不使用auto A_mul_B_Eval_plus_C,而是使用MatrixXd A_mul_B_Eval_plus_C这类的显式声明。(但这样不够灵活有没有!)
  • 2、使用eval(),对,你没看错,但是是在整条语句上使用eval();比如:auto A_mul_B_plus_C_EvalAll = (C + (A * B).colwise().sum().eval() ).eval(); //如果该变量要多次使用,推荐这种做法,这种做法也是最安全的(不会因为Eigen库还有之前a*b产生局部变量引发的错误)
  • 3、完全不使用eval(); 比如:auto A_mul_B_plus_C = C + (A * B).colwise().sum();

完整的代码参见:http://eigen.tuxfamily.org/bz/show_bug.cgi?id=883
更深入了解这个bug看下面这个链接:http://eigen.tuxfamily.org/bz/show_bug.cgi?id=99

2、不用eval()也是不行的!(最新版本(3.2.2)不存在这个问题了)
也许你会有所疑问,我干嘛要手动eval()呢?
这源于另一个bug:
一年前接触Eigen库的时候,写过这么一段代码

      Eigen::MatrixXd m=Eigen::MatrixXd::Ones(3,4);
      m.array().rowwise()/=m.array().colwise().sum();
      std::cout<<m<<std::endl;

结果大跌眼镜(最新版本的输出没问题了):
  • 0.333333 0.333333 0.333333 0.333333
  • 0.428571 0.428571 0.428571 0.428571
  • 0.567568 0.567568 0.567568 0.567568

原因可能是等号右边时表达式,左边每行除以右边时,右边的表达式都会被重新计算。。。
所以当时的版本必须eval()一下!好在现在这个bug消除了!
另外多说一句,基于效率考虑,可能也要eval()一下,但是我调了下代码,当前版本的Eigen右侧的表达式是只计算一遍的,放心的不eval()吧!
分享到:
评论

相关推荐

    c++ 的eigen库:eigen-3.3.7

    去官网下载的目前最新版的eigen库 官网链接:http://eigen.tuxfamily.org/index.php?title=Main_Page#Download

    C++调用Eigen库技巧的直观理解.docx

    C++调用Eigen库技巧的直观理解 包含常用的Eigen库函数及使用方法

    eigen库使用方法.zip

    eigen3源码操作示例程序vs2015程序示例,带说明文档,保证通俗易懂,迅速走入eigen开发大门

    eigen库使用教程,使用说明文档

    eigen库使用教程,使用说明文档

    eigen库 最新稳定版3.3.9

    eigen库 最新稳定版3.3.9

    C++eigen库和dlib库使用笔记.md

    能学到什么: 读者将了解到Eigen库和Dlib库的功能、用途和基本操作。他们将学会如何安装这些库、进行基本矩阵和向量运算、进行图像处理和特征提取、进行机器学习任务,以及在科学计算和工程应用中的应用。 阅读建议...

    Eigen: C++开源矩阵计算工具

    his is the API documentation for Eigen3. You can download it as a tgz archive for offline reading.

    C++ Eigen库计算矩阵特征值及特征向量

    本文主要讲解利用Eigen库计算矩阵的特征值及特征向量并与Matlab计算结果进行比较。 C++Eigen库代码 #include #include &lt;Eigen&gt; #include &lt;Eigen&gt; using namespace Eigen; using namespace std; void Eig() { ...

    Eigen3库编译资源

    Eigen3库虽然可以不编译,但是我为了编译Ceres库还是把Eigen库编译了一下,Eigen库编译不会生成动态链接库,只会有include文件和share文件,主要是使用include文件中的eigen3文件夹

    Eigen库的简单实用说明

    这是我在做项目时,给下一届接手的人写的一个关于Eigen库的快速上手手册,主要是针对于项目的应用来写的。当时使用Eigen库的目的是,将Matlab写的,LPCC和MFCC两种声音识别算法,十字形声阵列的MUSIC定位算法,和SVM...

    C++ Eigen库的下载配置和使用

    一、Eigen 介绍 二、Eigen 的下载 三、Eigen 的配置 3.1 在 Qt 下配置 3.2 在 Visual Studio (VS) 下配置 四、Eigen 的使用 4.1 矩阵和向量的初始化 4.2 矩阵元素的赋值 4.3 矩阵元素的访问 4.4 获取矩阵大小 4.5 ...

    eigen库函数可直接使用

    eigen库可以在c里面直接添加使用,避免了复杂的编程问题!

    My_ORB-SLAM24Windows

    ORB-SLAM2在wondows下的移植,基于CMake构建项目,修改了一下源码,改为二进制格式读写ORB字典,并修改了一个win下的测试用例。

    最新的eigen库 eigen.rar

    Eigen适用范围广,支持包括固定大小、任意大小的所有矩阵操作,甚至是稀疏矩阵;...Eigen支持多种编译环境,开发人员对库中的实例在多种编译环境下经过测试,以保证其在不同编译环境下的可靠性和实用性。

    C++矩阵库 Eigen 快速入门

    近需要用 C++ 做一些数值计算,之前一直采用Matlab 混合编程的方式处理矩阵运算,非常麻烦,直到发现了 Eigen 库,简直相见恨晚,好用哭了。 Eigen 是一个基于C++模板的线性代数库,直接将库下载后放在项目目录下,...

    Eigen矩阵运算库源代码

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

    Eigen 3 库文件及 unsupported 文件

    Eigen C++运算库 被集成到TensorFlow里面,做矩阵运算效率比较高,方便大家进行嵌入式移植

    Eigen数学库Android Studio项目模版

    Eigen高等数学/线性代数库在Android Studio中使用项目模版

    eigen3+vs2017+cmake使用vs2017编译Eigen3库 Eigen3.3.9库

    使用vs2017和cmake编译的Eigen3.3.9的库,32位64位通用

Global site tag (gtag.js) - Google Analytics