计算复数的多重复制

时间:2016-05-23 16:15:12

标签: c++ arrays vector multiplication complex-numbers

我最终要做的是将两个复数相乘:

z1 = R1 + I1*j

z2 = R2 + I2*j

z3 = z1 * z2 = (R1*R2 - I1*I2) (R1*I2 + R2*I1)*j;

但我所拥有的是这两个复数的真实和复杂部分的两个独立的向量。所以像这样:

v1 = [R1, R2, R3, R4 ... Rn] of z1

v2 = [I1, I2, I3, I4 ... In] of z1

v1 = [R1, R2, R3, R4 ... Rn] of z2

v2 = [I1, I2, I3, I4 ... In] of z2

所以当我现在尝试计算z3时,我会这样做:

foo (std::vector<double> real1, std::vector<double> imag1,
     std::vector<double> real2, std::vector<double> imag2)
{
    std::vector<double> realResult;
    std::vector<double> imagResult;

    for (size_t i = 0; i < real1.size(); i++)
    {
         realResult.push_back(real1[i]*real2[i] - imag1[i]*imag2[i]);
         imagResult.push_back(real1[i]*imag2[i] + real2[i]*imag1[i]);
    }

    //And so on
}

现在,这个功能正在耗费大量时间。肯定有另一种方法可以让你想到我可以使用的东西吗?

3 个答案:

答案 0 :(得分:4)

您可以使用std::complex。这可能会实现您至少接近并且可以实现的操作。

编辑(回复评论):

我会这样做:

size_t num_items = real1.size();
std::vector<double> realResult;
realResult.reserve(num_items);
std::vector<double> imagResult;
imagResult.reserve(num_items);
for (size_t i = 0; i < num_items; ++i) {
  // lalala not re-sizeing any vectors yey!
  realResult.push_back(real1[i] * real2[i] - imag1[i] * imag2[i]);
  imagResult.push_back(real1[i] * imag2[i] + real2[i] * imag1[i]);

}

否则,如果你有一个大的输入数组并且你在双打上做了很多乘法,我担心这可能会很慢。你可以做的最好的事情就是在内存中连续获取额外的缓存点。如果不对代码进行精确分析,就不可能真正说出最合适的代码。

答案 1 :(得分:3)

将参数传递为const std::vector<double>&以避免不必要的复制

您也可以考虑并行计算每个乘法,如果N足够大,并行计算的开销是值得的

答案 2 :(得分:1)

使用std::valarraystd::complex。它简单并针对算术运算进行了优化

foo(std::valarray<std::complex<double>> & z1, 
    std::valarray<std::complex<double>> & z2) 
{
    auto z3 = z1 * z2;  // applies to each element of two valarrays, or a valarray and a value 

    // . . .
}

编辑:将矢量转换为valarray

std::valarray<std::complex<double>> z1(real1.size());
for (size_t i = 0; i < z1.size(); ++i)
    z1[i] = std::complex<double>(real1[i], imag1[i]);