2016-05-23 9 views
0

Was ich versuche letztlich zu tun ist, zwei komplexe Zahlen wie folgt multipliziert:Compute Mutliplication von komplexen Zahlen

z1 = R1 + I1*j 

z2 = R2 + I2*j 

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

Aber was ich habe, sind zwei getrennte Vektoren für die reellen und komplexen Teil beider dieser komplexen Zahlen. So etwas wie folgt aus:

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 

Also, wenn ich z3 versuche jetzt zu berechnen, ich dies tun:

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 
} 

Nun, diese Funktion viel Zeit isst. Es gibt sicher eine andere Möglichkeit, dass Sie an etwas denken können, das ich verwenden kann?

+2

vorbelegen die Ergebnisvektoren und füllen sie in valarray, anstatt push_back –

Antwort

3

Pass in Parameter als const std::vector<double>&, um unnötige Kopie zu vermeiden

Sie auch parallel betrachten kann jede Multiplikation Berechnung, wenn N groß genug ist, der Aufwand für Parallel Computing lohnt

+0

Offensichtlich verwenden. Vielen Dank! – FreddyKay

4

Sie könnten in der Lage sein, zu machen Verwendung von std::complex. Dies implementiert wahrscheinlich Operationen, die Sie benötigen, mindestens so gut wie sie implementiert werden können.

EDIT (In Antwort auf Kommentar):

Ich würde dies tun:

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

} 

Andernfalls, wenn Sie einen großen Eingangs-Array haben, und Sie werden eine Menge Multiplikation auf Doppel tun Ich habe Angst, Das könnte nur langsam sein. Das Beste, was Sie tun können, ist herumzubasteln mit Dingen, die zusammenhängend im Speicher für Bonus-Cache-Punkte sind. Unmöglich, wirklich zu sagen, ohne den Code genau zu profilieren, was am besten funktionieren könnte.

+0

Wie oben. Ich werde es versuchen, aber ich würde std :: complex mit meinen Vektoren füllen. Kennst du einen Weg dies effektiv zu tun? – FreddyKay

+0

@FreddyKay Ich vermute, Sie würden finden, es war alles viel schneller, wenn Sie den Ergebnisvektor auf die Größe initialisieren, die Sie erwarten, oder "reservieren" diesen Raum. Ich müsste mich profilieren, um sicher zu sein, aber ich würde vermuten, dass ich bei der Betrachtung dieses Codes viel Zeit in Anspruch nehmen könnte, um mehr Speicherplatz für die Ergebnisvektoren zu reservieren. Ich werde meine Antwort bearbeiten, um diesen Vorschlag anzuzeigen. – sji

+0

@FreddyKay das Auffüllen der komplexen Zahlen könnte nach den gleichen Ideen erfolgen, wie man den Raum zuerst reserviert und einfach schleift. Ich würde vorschlagen, dass Sie wenn möglich Ihre ursprünglichen Daten einfach als Vektor von std :: compex initialisieren, um die zusätzliche Kopie zu vermeiden. – sji

1

Verwenden Sie std::valarray von std::complex. Es ist einfach und für arithmetische Operationen optimiert

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 

    // . . . 
} 

EDIT: Vektoren konvertieren

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

Das scheint nett zu sein. Ich werde es versuchen. Obwohl ich die Arrays mit meinen Vektoren effizient füllen müsste. Hast du da einen Vorschlag? – FreddyKay

+0

@FreddyKay in der Antwort hinzugefügt. – Shreevardhan