Eigen3(cpp)选择列给定掩码和总和,其中为真

Posted

技术标签:

【中文标题】Eigen3(cpp)选择列给定掩码和总和,其中为真【英文标题】:Eigen3 (cpp) select column given mask and sum where true 【发布时间】:2022-01-08 04:33:55 【问题描述】:

我有一个Eigen::Matrix2Xf,其中行是 X 和 Y 位置,列充当列表索引

我想要一些列条件为真的列的总和(按行),这里有一些示例代码:

Eigen::Vector2f computeStuff(Eigen::Matrix2Xf & values, const float max_norm)

    const auto mask = values.colwise().norm().array() < max_norm;

    return mask.select(values.colwise(), Eigen::Vector2f::Zero()).rowwise().sum();
    

但是这段代码无法编译并抱怨 if/else 矩阵的类型,什么是正确(并且计算速度更快)的方法?

我也知道有类似的问题有答案,但是他们创建了一个新的Eigen::Matrix2Xf,并使用给定掩码的过滤值,此代码旨在在#pragma omp parallel for 内运行,因此基本思想是不要创建一个新的矩阵来维护缓存的一致性

谢谢

【问题讨论】:

values 是 2x4 ... 那是 2 行 4 列。那么values.colwise().norm().array() &lt; max_norm 将是 1x4,一行四列。然后你说你想对 mask 选择的 values 中的行求和... values 只包含 2 行,mask 有四列。您的意思是要对掩码选择的values 中的 求和吗? @jwezorek 是的,正是这样,如果我不清楚,对不起,我解决了这个问题 另一件事是输出怎么可能是vector2f?如果我了解您要执行的操作,则输出将是一个行向量,其中包含输入的列数。如果您希望它只有非零列并且知道只有两个或其他东西,您无法使用.select(...) 输出将是vector2f,其想法是屏蔽矩阵值的某些列,然后进行逐行归约操作我只想得到屏蔽列的逐行总和 【参考方案1】:

您的代码的主要问题是.select( ... ) 至少需要一个参数才能具有与掩码相同的形状。参数可以是两个矩阵或一个矩阵和一个标量,反之亦然,但在所有情况下,矩阵的形状都必须像掩码。

在您的代码中,mask 是行向量,但 values 是 2 x x 矩阵。处理此问题的一种方法是将行向量复制到两行矩阵中:

#include <Eigen/Dense>
#include <iostream>

Eigen::Vector2f computeStuff(Eigen::Matrix2Xf& values, const float max_norm) 

    auto mask = (values.colwise().norm().array() < max_norm).replicate(2, 1);
    return mask.select(values, 0).rowwise().sum();


int main() 

    Eigen::Matrix2Xf mat(2,4);
    mat << 1, 4, 3, 2, 
           1, 2, 4, 3;

    auto val = computeStuff(mat, 5);

    std::cout << val;

    return 0;

上面的mask会是:

1 1 0 1
1 1 0 1

1 1 0 1 行重复了一次。然后mask.select(values, 0) 产生

1 4 0 2
1 2 0 3

所以结果是

7
6

如果我理解这个问题,我认为这就是你想要的。

【讨论】:

以上是关于Eigen3(cpp)选择列给定掩码和总和,其中为真的主要内容,如果未能解决你的问题,请参考以下文章

网络层-第三节3:子网划分与子网掩码和无分类域间路由选择CIDR

主机ip子网掩码 默认网关最后不是0,1。 linux的ip怎么设置?

子网掩码225.225.225.0它的网络掩码长度是多少?

使用掩码和其他数组替换数组中的值

根据其他列的值选择总和

子网掩码和IP地址的关系