首页 > 解决方案 > 如何在没有冗余计算的 if 语句中使用 std::valarray?

问题描述

我有以下代码float,例如:

std::vector<float> v = {0.f, 1.f, 2.f};
for(size_t i = 0; i < v.size(); ++i)
    if(v[i] != 0) // An optimization for `v[i] != 0`.
        v[i] = v[i] * v[i] * v[i]; // Time-consuming computation.

现在我想替换floatstd::valarray<float>

using vfloat = std::valarray<float>;
std::vector<vfloat> v = {vfloat{0.f, 0.f}, vfloat{1.f, 0.f}, vfloat{2.f, 0.f}};
for(size_t i = 0; i < v.size(); ++i)
    // if(v[i] != 0) // I want this optimization! ◀◀◀◄◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀
        v[i] = v[i] * v[i] * v[i]; // Time-consuming computation.

虽然新代码在逻辑上是正确的,但对于v[i][j] == 0.

那么如何在没有冗余计算的情况下使用std::valarrayinif语句呢?

标签: c++valarray

解决方案


如果你想跳过v[i]使用嵌套循环的元素

using vfloat = std::valarray<float>;
std::vector<vfloat> v = {vfloat{0.f, 0.f}, vfloat{1.f, 0.f}, vfloat{2.f, 0.f}};
for(size_t i = 0; i < v.size(); ++i)
    for(size_t j = 0; j < v[i].size(); ++j)
        if (v[i][j] != 0)
            v[i][j] = v[i][j] * v[i][j] * v[i][j]; // Time-consuming computation.

apply

using vfloat = std::valarray<float>;
std::vector<vfloat> v = {vfloat{0.f, 0.f}, vfloat{1.f, 0.f}, vfloat{2.f, 0.f}};
for(size_t i = 0; i < v.size(); ++i)
    v[i] = v[i].apply([](float n) -> float {
        if (n == 0) return 0;
        return n * n * n; // Time-consuming computation.
    });

如果你想跳过元素v

using vfloat = std::valarray<float>;
std::vector<vfloat> v = {vfloat{0.f, 0.f}, vfloat{1.f, 0.f}, vfloat{2.f, 0.f}};
for(size_t i = 0; i < v.size(); ++i)
    if ((v[i] != 0).max() != 0)
        v[i] = v[i] * v[i] * v[i]; // Time-consuming computation.

推荐阅读