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