我正在使用原始指针连接一些代码。所以我广泛使用了地图类:
void foo(T* raw_pointer){
const int rows = ...;
const int cols = ...;
Map<Matrix<T, rows, cols>> mat(raw_pointer);
// DO some stuff with "mat"
}
现在我想在foo
中应用一些cwise操作,我使用.array()
完成了这些操作。但是,由于函数中散布的所有.array()
调用,它看起来非常混乱。例如,为了论证,让我们假设函数看起来像这样:
void foo(T* raw_pointer){
const int rows = ...;
const int cols = ...;
Map<Matrix<T, rows, cols>> mat(raw_pointer);
for (int i = 0 ; i < 1000 ; ++i)
... something = i * mat.row(1).array() * sin(mat.row(4).array()) + mat.col(1).array();
}
这个问题的部分原因是很难清楚代码实际上在做什么。如果给出变量名称会更好:
void foo(T* raw_pointer){
const int rows = ...;
const int cols = ...;
Map<Matrix<T, rows, cols>> mat(raw_pointer);
Matrix<T, 1, cols> thrust = mat.row(1);
Matrix<T, 1, cols> psi = mat.row(4);
Matrix<T, 1, cols> bias = mat.row(2);
for (int i = 0 ; i < 1000 ; ++i)
... something = i * thrust.array() * sin(psi.array()) + bias.array();
}
但如果我可以直接获得对ArrayWrapper
的引用,那么它会更好,这样我们就不会制作任何副本。但是,我能弄清楚如何使其工作的唯一方法是使用auto
:
void foo(T* raw_pointer){
const int rows = ...;
const int cols = ...;
Map<Matrix<T, rows, cols>> mat(raw_pointer);
auto thrust = mat.row(1).array();
auto psi = mat.row(4).array();
auto bias = mat.row(2).array();
for (int i = 0 ; i < 1000 ; ++i)
... something = i * thrust * sin(psi) + bias;
}
此代码有效,并且在测试时似乎引用指针中的条目(而不是像上一个代码片段那样制作副本)。然而, 自Eigen文档explicitly suggests NOT doing this以来,我对其效率感到担忧。那么有人可以在这样的情况下,首先定义变量类型的首选方法是什么?
在我看来,我应该在这里使用Ref
,但我无法弄清楚如何让它发挥作用。具体来说,我尝试用
auto
Eigen::Ref<Eigen::Array<T, 1, cols>>
和
Eigen::Ref<Eigen::ArrayWrapper<Eigen::Matrix<T, 1, cols>>>
但编译器并不喜欢其中任何一个。
答案 0 :(得分:3)
为避免每次使用array()
时都必须写Map<Eigen::Matrix...
,您可以使用Map<Eigen::Array...
代替/。这将使用默认的逐元素运算符而不是矩阵运算符。要使用矩阵运算符,您可以使用map.matrix()
(类似于帖子mat.array()
中的内容)。
答案 1 :(得分:2)
auto thrust = [](auto&&mat){return mat.row(1).array();};
auto psi = [](auto&&mat){return mat.row(4).array();};
auto bias = [](auto&&mat){return mat.row(2).array();};
for (int i = 0 ; i < 1000 ; ++i)
... something = i * thrust(mat) * sin(psi(mat)) + bias(mat)
有名字。并且数组包装器不会持久存在。