【问题标题】:Eigen: Efficient way of referencing ArrayWrapperEigen:引用 ArrayWrapper 的有效方法
【发布时间】:2018-03-12 09:52:39
【问题描述】:

我正在使用原始指针连接一些代码。所以我广泛使用了地图类:

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();
}

但如果我能直接获得对ArrayWrappers 的引用,那就更好了,这样我们就不会制作任何副本。然而,我能弄清楚如何让它工作的唯一方法是使用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;
}

此代码有效,并且在测试时似乎引用了指针中的条目(而不是像之前的 sn-p 那样制作副本)。然而, 自从 Eigen 文档 explicitly suggests NOT doing this 以来,我一直担心它的效率。那么有人可以请在这种情况下定义变量类型的首选方法是什么?

在我看来,我应该在这里使用Ref,但我不知道如何让它发挥作用。具体来说,我尝试用

替换 auto
Eigen::Ref<Eigen::Array<T, 1, cols>>

Eigen::Ref<Eigen::ArrayWrapper<Eigen::Matrix<T, 1, cols>>>

但编译器不喜欢其中任何一个。

【问题讨论】:

  • 两件事:Ref 不会复制;默认情况下,您可以使用 Map&lt;Eigen::Array... 而不是 Map&lt;Eigen::Matrix... 来使用元素操作。
  • 嗯。唯一的问题是我们有一个通用接口类,用于从原始指针获取Map&lt;Eigen::Matrix 对象。我想我可以在那个对象上做Map&lt;Eigen::Array.. &gt;&gt;(mapMatrix.data())
  • 让我看看这是否适用于我们的案例。
  • 啊。实际上,由于使用我的接口文件时底层指针的跨步,这种方法不起作用。但它适用于原始问题......
  • 这是auto的完美安全用法。

标签: c++ c++11 eigen eigen3


【解决方案1】:

为避免每次使用Map&lt;Eigen::Matrix... 时都必须写array(),您可以使用Map&lt;Eigen::Array... 代替/附加。这将使用默认的元素运算符而不是矩阵运算符。要改用矩阵运算符,您可以使用map.matrix()(类似于您在帖子中的mat.array())。

【讨论】:

  • 同样,你可以/需要写Array&lt;T, 1, cols&gt; thrust = mat.row(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)

有名字。并且数组包装器不会持久化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 2012-04-18
    • 2020-03-02
    • 2014-11-15
    • 2020-12-02
    • 2018-08-02
    • 1970-01-01
    相关资源
    最近更新 更多