总结一些最近编程遇到的坑(C++)
使用Eigen时的一个报错:
在使用Eigen库时,有时会报错:
my_program: path/to/eigen/Eigen/src/Core/DenseStorage.h:44: Eigen::internal::matrix_array<T, Size, MatrixOptions, Align>::internal::matrix_array() [with T = double, int Size = 2, int MatrixOptions = 2, bool Align = true]: Assertion `(reinterpret_cast
(array) & (sizemask)) == 0 && "this assertion is explained here: http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html READ THIS WEB PAGE !!! ****"' failed.
这里Eigen已经把解决问题的网页贴出来了。进去一看,给出了可能的原因,我这里遇到的是因为一个类里面的成员为Eigen的类,比如
class Foo
{
//...
Eigen::Vector2d v;
//...
};
//...
Foo *foo = new Foo;
需要加上一个宏EIGEN_MAKE_ALIGNED_OPERATOR_NEW
,如下
class Foo
{
//...
Eigen::Vector2d v;
//...
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
//...
Foo *foo = new Foo;
就不会报错了。这个是对于固定维数的矩阵(向量)会出现的错误,动态维数的矩阵(向量)不存在这样的问题。其它的情况包括按值传递矩阵(向量、或者带矩阵成员的类),需要改成按引用传递。这个问题的根本原因是Eigen为了提高运算速度,采取了128位内存对齐,以让编译器进行向量化优化。而如果自己的new就不会有内存对已,因此需要加上一个宏,重新实现内存对齐的new.
一个在析构函数中需要注意的问题
为了减少头文件包含,我们有时会这样写
class bar;
class foo{
public:
foo();
~foo()
{
delete m_bar;
}
private:
bar* m_bar
}
这个时候编译器会给出警告,因为没有bar的析构函数。正确的还是应该把析构函数放进cpp文件里面。
Eigen的矩阵判断相等
Eigen库有一个用于判断矩阵是否大致相等的函数,可以这样用
typedef typename Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenMatrix;
EigenMatrix a, b;
// True if equal
bool r = a.isApprox(b, 1e-5);
原理是两个矩阵相减并求Frobenius范数。