2016-05-23 13 views
0

我所试图做的,最终被乘以两个复数这样的:计算Mutliplication

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 
} 

现在,这个功能是吃了很多的时间。还有另一种做法,你能想到我可以使用的东西吗?

+2

预分配结果的载体和填充它们,而不是使用的push_back –

回答

3

传递参数为const std::vector<double>&,以避免不必要的副本

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

+0

明显。谢谢! – FreddyKay

4

你也许能够使使用std::complex。这可能会实现您至少需要的操作以及它们可以实施的操作。

EDIT(在回复评论):

我这样做:如果你有一个大的输入阵列

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]); 

} 

否则,你做了很多乘法对双打恐怕这可能会很慢。你可以做的最好的事情就是围绕获取奖励缓存点的内存连续性。不可能真正说出没有分析代码的确切可能效果最好的。

+0

如上所述。我会给它一个镜头,但我需要填充std :: complex与我的载体。你知道如何有效地做到这一点吗? – FreddyKay

+0

@FreddyKay我怀疑你会发现,如果你将结果向量初始化为你期望的大小,或者'保留'那个空间,那么它会快得多。我将不得不进行简介,但是我会怀疑在代码中可能会花费相当长的时间为结果向量重新分配更多空间。我将编辑我的答案以显示此建议。 – sji

+0

@FreddyKay填充复数可以遵循先保留空间和循环的相同想法。我建议如果可能的话,只需将原始数据初始化为std :: compex的向量以避免额外的副本。 – sji

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]); 
+0

这看起来不错。我会给它一个镜头。虽然我不得不用阵列有效地填充阵列。你有什么建议吗? – FreddyKay

+0

@FreddyKay在答案中加入。 – Shreevardhan