Genauigkeit von cos (atan2 (y, x)) im Vergleich mit komplexen , C ++
-
24-09-2019 - |
Frage
Ich habe einige Koordinatentransformationen schriftlicher Form (genauer gesagt die Joukoswky Transformation, Wikipedia Joukowsky Trans ), und ich habe Interesse an Leistung, aber natürlich Präzision. Ich versuche, die Koordinatentransformationen auf zwei Arten zu tun:
1) Die Berechnung der realen und komplexe Teile in separaten, mit doppelter Genauigkeit, wie folgt:
double r2 = chi.x*chi.x + chi.y*chi.y;
//double sq = pow(r2,-0.5*n) + pow(r2,0.5*n); //slow!!!
double sq = sqrt(r2); //way faster!
double co = cos(atan2(chi.y,chi.x));
double si = sin(atan2(chi.y,chi.x));
Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*si*sq;
, wo Chi und Z sind einfache Strukturen mit Doppel x und y als Mitglieder.
2) Unter Verwendung komplexer:
Z = 0.5 * (chi + (1.0 / chi));
Wo Z und Chi ist komplex. Es interessante Teil ist, dass in der Tat der Fall 1) schneller (ca. 20%), aber die Genauigkeit ist schlecht, Fehler geben in der dritten Dezimalzahl nach dem Komma nach der inversen Transformation, während der Komplex die genaue Zahl gibt zurück. So ist das Problem auf dem cos (atan2), sin (atan2)? Aber wenn es, wie die komplexen Griffe das?
EDIT: Nur herausgefunden, dass dies nicht genau die Frage, die ich im Sinne hatte. Ich habe die allgemeine Transformation zu tun, wie
Z = 1/2 * (chi ^ n + (1 / Chi) ^ n), und bisher den obigen Code war so, wie ich dachte ich, es zu tun. Genauer gesagt,
double sq = pow(sqrt(r2),n); //way faster!
double co = cos(n*atan2(chi.y,chi.x));
double si = sin(n*atan2(chi.y,chi.x));
Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*(si*sq - sq/si);
Auch den Fehler auf Z.y zu korrigieren.
Lösung
ich denke, dass in 1) sollte
seinZ.y = 0.5*(si*sq - si/sq);
Wenn Sie wirklich gute Leistung wollen, können Sie zurück zum ersten Prinzipien gehen wollen und verweisen darauf, dass
1/(a+ib) = (a-ib)/(a*a+b*b)
Nein sqrt()
, atan2()
oder cos()
oder sin()
.
Andere Tipps
Da r = sqrt(x*x+y*y)
:
cos(atan2(y,x)) == x/r
sin(atan2(y,x)) == y/r
es auf diese Weise ermitteln, sollte genauer und schneller sein.
Wenn Sie diese Werte in die Formeln für Z.x und Z.y anschließen, wird die Quadratwurzel als auch zunichte machen, so dass Sie mit nur Grundrechenarten bleiben werden.