Eigen3 (cpp) select 列给定掩码和总和,其中为真
Eigen3 (cpp) select column given mask and sum where true
我有一个 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
所以基本思想是不创建新矩阵来保持缓存一致性
谢谢
您的代码的主要问题是 .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
我想这就是你想要的,如果我理解这个问题的话。
我有一个 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
所以基本思想是不创建新矩阵来保持缓存一致性
谢谢
您的代码的主要问题是 .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
我想这就是你想要的,如果我理解这个问题的话。