Eigen:以无循环方式缩放正项

问题描述 投票:0回答:1

我有一个

Eigen::Array<float, N, 1>
。我想将所有正元素乘以所选择的正标量
s
,以便正元素之和达到目标
t
。我可以用这样的代码来做到这一点:

template<int N>
void positive_scale(Eigen::Array<float, N, 1>& A, float t) {
  float pos_sum = 0;
  for (int i = 0; i < N; ++i) {
    if (A(i) > 0) pos_sum += A(i);
  }

  float s = t / pos_sum;
  for (int i = 0; i < N; ++i) {
    if (A(i) > 0) A(i) *= s;
  }
}

我想知道是否有一种更优雅、无循环的方法来做到这一点。例如,在 python numpy 中,我们可以更紧凑地编写:

def positive_scale(A, t):
  A[A > 0] *= t / sum(A[A > 0])
c++ eigen
1个回答
0
投票

Eigen 不像 Numpy 那样支持布尔索引,但它有一个可以使用的

select
方法。

void positive_scale(Eigen::Ref<Eigen::ArrayXf> inout, float target)
{
    // sum of positive entries. Fully vectorized
    float pos_sum = inout.cwiseMax(0.f).sum();
    float factor = target / pos_sum;
    // keep old negative values. Replace positive values
    inout = (inout > 0.f).select(inout * factor, inout);
}
© www.soinside.com 2019 - 2024. All rights reserved.