我继承了一些代码,这些代码广泛使用双指针来表示二维数组。我没有使用 Eigen 的经验,但它似乎比双指针更易于使用且更健壮。
有没有人知道哪个更可取?
请记住,Eigen 具有 Map 功能,可让您将 Eigen 矩阵制作成连续的数据数组。如果很难完全更改您继承的代码,那么将事物映射到 Eigen 矩阵至少可以使与原始指针的互操作更容易。
Eigen 和 Boost.uBLAS 都定义了表达式层次结构和抽象矩阵数据结构,可以使用任何满足特定约束的存储类。这些库的编写使得线性代数运算可以在非常高的水平上清晰地表达和有效评估。这两个库都大量使用表达式模板,并且能够进行非常复杂的编译时表达式转换。特别是,Eigen 还可以使用 SIMD 指令,并且在多个基准测试中非常具有竞争力。
对于稠密矩阵,一种常见的方法是使用单个指针并跟踪其他行、列和步幅变量(您可能需要第三个变量的原因是因为您分配的内存可能比存储x * y * sizeof(value_type)
元素的实际需要更多,因为对齐)。但是,您没有适当的机制来检查超出范围的访问,代码中也没有任何东西可以帮助您进行调试。例如,如果您需要为教育目的实现一些线性代数运算,您只会想使用这种方法。(即使是这种情况,我建议您先考虑要实现哪些算法,然后查看std::unique_ptr
、std::move
、std::allocator
和运算符重载)。
是的,对于现代 C++,你应该使用容器而不是原始指针。
使用 Eigen 时,请注意其固定大小的类(如Vector3d
)使用需要正确对齐的优化。如果您将这些固定大小的特征值作为成员包含在结构或类中,则需要特别小心。您也不能通过值传递它们,只能通过引用传递。
如果你不关心这样的优化,禁用它就很简单了:只需添加
#define EIGEN_DONT_ALIGN
作为使用 Eigen 的所有源文件(.h、.cpp、...)的第一行。
其他两个选项是:
#include <boost/numeric/ublas/matrix.hpp>
boost::numeric::ublas::matrix<double> m (3, 3);
#include <vector>
std::vector<std::vector<double> > m(3, std::vector<double>(3));