std :: accumulate()只是复杂std :: vector的真实部分

时间:2016-07-20 18:31:30

标签: c++ c++11 matrix vector complex-numbers

我曾经采用对称(Hermitian)矩阵的总和(矩阵在Tire),这是一个巨大的浪费,因为虚部总是加零(我说的是巨大的)边长为std::vector的矩阵,所以我认为它会产生影响。

所以现在我只添加矩阵的上三角部分。但是我想进一步优化它,避免添加复杂的部分,因为我不需要它。

我目前使用的是:

n>1000

这会将std::real(std::accumulate(myMatrix.begin(), myMatrix.end(), std::complex<Real>(0,0))); 的所有元素添加到myMatrix,从而产生我需要的总和。

但是这会添加我的矢量的实部和虚部,这是浪费!如何编写最优化的版本,只添加该矩阵的实部?

更新

虽然我接受了有效的答案,但我发现它比对矩阵的实部和虚部求和要慢。对于边长为128的矩阵,它慢了5%-10%。这是令人惊讶的。任何其他更快的建议都非常感谢。

请询问您是否需要其他信息。

3 个答案:

答案 0 :(得分:8)

Real real_sum = std::accumulate(
    myMatrix.cbegin(), myMatrix.cend(), Real{},
    [](Real const acc, std::complex<Real> const& c) { return acc + std::real(c); }
);

答案 1 :(得分:4)

std::accumulate有两个重载,其中一个需要运算符:

<li class="dropdown hidden-xs open">

只需提供您自己的,而不是默认为template< class InputIt, class T, class BinaryOperation > T accumulate( InputIt first, InputIt last, T init, BinaryOperation op );

+

或者,您可以像使用boost::transform_iterator一样开心:

std::accumulate(myMatrix.begin(), myMatrix.end(), Real{0},
    [](Real const& sum, std::complex<Real> const& next){
        return sum + std::real(next);
    });

range-v3

auto make_real = [](std::complex<Real> const& c) {
    return std::real(c);
};

std::accumulate(
    boost::make_transform_iterator(myMatrix.begin(), make_real),
    boost::make_transform_iterator(myMatrix.end(), make_real),
    Real{0});

如果accumulate(myMatrix, Real{0}, std::plus<>{}, [](std::complex<Real> const& c) { return c.real(); } ); 没有重载,上述两种方法都会更好,你可以在提升示例中提供real,在第二方提供std::real<Real>

答案 2 :(得分:1)

绝对需要使用display: flex; For childs: align-items: stretch; 吗?

std::accumulate

不要误会我的意思,我赞成在适合时使用标准算法,但似乎很难在可读性方面击败这个循环。

这与我的g ++ - 4.8.4安装附带的实现相比:

    Real acc = 0;
    for(auto c : myMatrix)
       acc += real(c);

所以你可以看到他们在做同样的事情。