it-swarm.com.de

Wie funktionieren trigonometrische Funktionen?

In der Mathematik der High School und wahrscheinlich am College lernen wir, wie man Triggerfunktionen verwendet, was sie tun und welche Probleme sie lösen. Sie wurden mir aber immer als Black Box präsentiert. Wenn Sie den Sinus oder Cosinus von etwas benötigen, drücken Sie die Sünde oder Cos-Taste Ihres Rechners und Sie sind fertig. Welches ist gut.

Ich frage mich, wie trigonometrische Funktionen normalerweise implementiert werden.

97
Jurassic_C

Zunächst müssen Sie eine Art Bereichsreduzierung durchführen. Auslöserfunktionen sind periodisch, daher müssen Sie die Argumente auf ein Standardintervall reduzieren. Für den Anfang können Sie den Winkel zwischen 0 und 360 Grad verringern. Durch die Verwendung einiger Identitäten erkennen Sie jedoch, dass Sie mit weniger auskommen können. Wenn Sie Sinus und Cosinus für Winkel zwischen 0 und 45 Grad berechnen, können Sie alle Triggerfunktionen für alle Winkel berechnen.

Wenn Sie Ihr Argument reduziert haben, verwenden die meisten Chips einen CORDIC - Algorithmus, um die Sinus- und Cosinus-Werte zu berechnen. Sie hören vielleicht Leute sagen, dass Computer Taylor-Serien verwenden. Das hört sich vernünftig an, stimmt aber nicht. Die CORDIC-Algorithmen sind viel besser für eine effiziente hardware -Implementierung geeignet. (Software -Bibliotheken verwenden möglicherweise die Taylor-Serie, z. B. auf Hardware, die keine Triggerfunktionen unterstützt.) Möglicherweise gibt es einige zusätzliche Verarbeitungsschritte, bei denen der CORDIC-Algorithmus verwendet wird, um ziemlich gute Antworten zu erhalten. 

Es gibt einige Verfeinerungen zu den oben genannten. Für sehr kleine Winkel theta (im Bogenmaß) ist beispielsweise sin (theta) = theta für die gesamte Genauigkeit, die Sie haben. Daher ist es effizienter, theta einfach zurückzugeben, als einen anderen Algorithmus zu verwenden. In der Praxis gibt es also eine Menge Spezialfalllogik, um alle möglichen Leistungen und Genauigkeit zu erreichen. Chips mit kleineren Märkten gehen möglicherweise nicht so sehr in den Optimierungsaufwand.

137
John D. Cook

edit: Jack Ganssle hat eine anständige Diskussion in seinem Buch über eingebettete Systeme, "The Firmware Handbook" .

Zu Ihrer Information: Bei Genauigkeits- und Leistungsbeschränkungen sollte die Taylor-Serie nicht verwendet werden, um Funktionen für numerische Zwecke zu approximieren. (Speichern Sie sie für Ihre Kalkülkurse.) Sie nutzen die Analytizität einer Funktion an einem einzigen Punkt, z. die Tatsache, dass alle seine Derivate zu diesem Zeitpunkt existieren. Sie konvergieren nicht unbedingt im interessierenden Intervall. Oft ist es eine miese Aufgabe, die Genauigkeit der Funktionsannäherung zu verteilen, um nahe am Bewertungspunkt "perfekt" zu sein; Der Fehler vergrößert sich in der Regel nach oben, wenn Sie ihn verlassen. Wenn Sie eine Funktion mit einer nicht-kontinuierlichen Ableitung haben (z. B. Rechteckwellen, Dreieckswellen und deren Integrale), wird Ihnen eine Taylor-Serie die falsche Antwort geben.

Die beste "einfache" Lösung, wenn ein Polynom mit maximalem Grad N verwendet wird, um eine gegebene Funktion f(x) über ein Intervall x0 <x <x1 zu approximieren, stammt von Chebyshev-Approximation ; Siehe Numerische Rezepte für eine gute Diskussion. Beachten Sie, dass Tj (x) und Tk (x) im Wolfram-Artikel I, der mit cos und inversem Kosinus verknüpft ist, Polynome sind. In der Praxis verwenden Sie eine Rekursionsformel, um die Koeffizienten zu erhalten. Siehe auch Numerische Rezepte.

edit: Wikipedia hat einen halbwegs anständigen Artikel zur Approximationstheorie . Eine der Quellen, die sie zitieren (Hart, "Computer Approximations"), ist vergriffen (und gebrauchte Kopien sind in der Regel teuer), gehen jedoch auf Details wie diese ein. (Jack Ganssle erwähnt dies in Ausgabe 39 seines Newsletters The Embedded Muse .)

edit 2: Hier sind einige konkrete Messwerte (siehe unten) für Taylor vs. Chebyshev für sin (x). Einige wichtige Punkte zu beachten:

  1. dass der maximale Fehler einer Taylor-Serienapproximation über einen bestimmten Bereich viel größer ist als der maximale Fehler einer Chebyshev-Approximation desselben Grades. (Bei ungefähr demselben Fehler können Sie mit Chebyshev eine kürzere Frist erhalten, was eine schnellere Leistung bedeutet.)
  2. Die Reduzierung der Reichweite ist ein großer Gewinn. Dies liegt daran, dass der Beitrag von Polynomen höherer Ordnung abnimmt, wenn das Näherungsintervall kleiner ist.
  3. Wenn Sie mit der Bereichsreduzierung nicht fertig werden können, müssen Ihre Koeffizienten präziser gespeichert werden.

Verstehen Sie mich nicht falsch: Die Taylor-Serie funktioniert einwandfrei für Sinus/Cosinus (mit angemessener Genauigkeit für den Bereich -pi/2 bis + pi/2; technisch gesehen können Sie mit ausreichenden Begriffen jede gewünschte Genauigkeit für alle echten Eingaben erreichen. Versuchen Sie jedoch, cos (100) mit der Taylor-Reihe zu berechnen, und Sie können dies nicht tun, wenn Sie Arithmetik mit beliebiger Genauigkeit verwenden. Wenn ich mit einem nichtwissenschaftlichen Rechner auf einer einsamen Insel festsitzen würde und Sinus und Cosinus berechnen müsste, würde ich wahrscheinlich die Taylor-Reihe verwenden, da die Koeffizienten leicht zu merken sind. Aber die realen Anwendungen, in denen Sie Ihre eigenen sin () - oder cos () - Funktionen schreiben müssen, sind selten genug, so dass Sie am besten eine effiziente Implementierung verwenden, um eine gewünschte Genauigkeit zu erreichen - was die Taylor-Serie ist nicht. .

Bereich = -pi/2 bis + pi/2, Grad 5 (3 Terme)

  • Taylor: maximaler Fehler um 4.5e-3, f(x) = x-x3/ 6 + x5/ 120
  • Chebyshev: max Fehler um 7e-5, f(x) = 0,9996949x-0,1656700x3+ 0,0075134x5

Bereich = -pi/2 bis + pi/2, Grad 7 (4 Terme)

  • Taylor: maximaler Fehler um 1,5e-4, f(x) = x-x3/ 6 + x5/ 120-x7/ 5040
  • Chebyshev: max Fehler um 6e-7, f(x) = 0,99999660x-0,16664824x3+ 0,00830629x5-0.00018363x7

Bereich = -pi/4 bis + pi/4, Grad 3 (2 Terme)

  • Taylor: maximaler Fehler um 2,5e-3, f(x) = x-x3/ 6
  • Chebyshev: max Fehler um 1,5e-4, f(x) = 0,999x-0,1603x3

Bereich = -pi/4 bis + pi/4, Grad 5 (3 Terme)

  • Taylor: maximaler Fehler um 3,5e-5, f(x) = x-x3/ 6 + x5
  • Chebyshev: max Fehler um 6e-7, f(x) = 0,999995x-0,1666016x3+ 0,0081215x5

Bereich = -pi/4 bis + pi/4, Grad 7 (4 Terme)

  • Taylor: maximaler Fehler um 3e-7, f(x) = x-x3/ 6 + x5/ 120-x7/ 5040
  • Chebyshev: Maximaler Fehler um 1,2e-9, f(x) = 0,999999986x-0,166666367x3+ 0,008331584x5-0.000194621x7
46
Jason S

Ich glaube, sie werden mit Taylor Series oder CORDIC berechnet. Einige Anwendungen, die häufig Trig-Funktionen (Spiele, Grafiken) verwenden, erstellen beim Start Trig-Tabellen, sodass sie Werte einfach nachschlagen können, anstatt sie immer wieder neu zu berechnen.

14
Jon Galloway

Check out den Wikipedia-Artikel über Triggerfunktionen. Ein guter Ort, um zu lernen, wie sie tatsächlich im Code implementiert werden, ist Numerical Recipes .

Ich bin kein großer Mathematiker, aber ich verstehe, woher Sünde, Cos und Bräune "kommen" ist, dass sie in gewissem Sinne beobachtet werden, wenn Sie mit rechtwinkligen Dreiecken arbeiten. Wenn Sie die Längen der Seiten eines Bündels verschiedener rechtwinkliger Dreiecke messen und die Punkte in einer Grafik darstellen, können Sie daraus Sünde, Cos und Bräunung gewinnen. Wie Harper Shelby hervorhebt, werden die Funktionen einfach als Eigenschaften von rechtwinkligen Dreiecken definiert.

Ein besseres Verständnis wird erreicht, wenn man versteht, wie diese Verhältnisse sich auf die Geometrie des Kreises beziehen, was zu Radiant und all dieser Güte führt. Im Wikipedia-Eintrag ist alles vorhanden.

6
Parappa

Am häufigsten werden bei Computern die Power-Series-Darstellung zur Berechnung von Sinus- und Cosinus-Werten verwendet, und diese werden für andere Triggerfunktionen verwendet. Das Erweitern dieser Reihe auf etwa 8 Terme berechnet die Werte, die für eine Genauigkeit nahe der Epsilon der Maschine benötigt werden (kleinste nicht-null-Gleitkommazahl, die gehalten werden kann). 

Die CORDIC-Methode ist schneller, da sie auf Hardware implementiert ist, sie wird jedoch hauptsächlich für eingebettete Systeme und nicht für Standardcomputer verwendet.

1
Joshua Howard

Ich möchte die Antwort von @Jason S erweitern. Bei Verwendung einer Domain-Unterteilung ähnlich der von @Jason S beschriebenen Methode und bei Verwendung von Maclaurin-Serienannäherungen wird eine durchschnittliche (2-3) X-Beschleunigung über dem Tan (), sin () Die in den gcc-Compiler integrierten Funktionen cos (), atan (), asin () und acos () mit -O3-Optimierung wurden erreicht. Die unten beschriebenen besten Approximationsfunktionen der Maclaurin-Serie erzielten eine doppelte Genauigkeit.

Für die Funktionen tan (), sin () und cos () und zur Vereinfachung wurde eine überlappende 0 bis 2 pi + pi/80-Domäne in 81 gleiche Intervalle mit "Ankerpunkten" bei pi/80, 3 pi/80 unterteilt. ..., 161 pi/80. Dann wurden tan (), sin () und cos () dieser 81 Ankerpunkte ausgewertet und gespeichert. Mit Hilfe von Trig-Identitäten wurde eine einzelne Maclaurin-Serienfunktion für jede Triggerfunktion entwickelt. Ein beliebiger Winkel zwischen ± unendlich kann den trig-Näherungsfunktionen zugewiesen werden, da die Funktionen zuerst den Eingabewinkel in den Bereich von 0 bis 2 pi verschieben. Dieser Übersetzungsaufwand ist im Näherungsaufwand enthalten. 

Ähnliche Methoden wurden für die Funktionen atan (), asin () und acos () entwickelt, bei denen eine überlappende Domäne von -1,0 bis 1,1 in 21 gleiche Intervalle mit Ankerpunkten bei -19/20, -17/20, .. unterteilt wurde. ., 19/20, 21/20. Dann wurde nur noch eine dieser 21 Ankerpunkte gespeichert. Mit Hilfe inverser Trig-Identitäten wurde wiederum eine einzige Maclaurin-Reihenfunktion für die atan () - Funktion entwickelt. Die Ergebnisse der atan () - Funktion wurden dann verwendet, um Asin () und Acos () zu approximieren. 

Da alle inversen trig-Näherungsfunktionen auf der atan () -Näherungsfunktion basieren, ist jeder Argumenteingabewert mit doppelter Genauigkeit zulässig. Das Argument, das in die Funktionen asin () und acos () eingegeben wird, wird jedoch auf die ± 1-Domäne gekürzt, da jeder Wert außerhalb von ihm bedeutungslos ist.

Um die approximierenden Funktionen zu testen, wurden eine Milliarde zufälliger Funktionsauswertungen gezwungen, ausgewertet zu werden (das heißt, der -O3-Optimierungscompiler durfte die Bewertung nicht umgehen, da einige berechnete Ergebnisse nicht verwendet würden.) Die Verzerrung der Bewertung einer Milliarde wurde entfernt Zufallszahlen und Verarbeitung der Ergebnisse wurden zuerst die Kosten eines Laufs ohne Auswertung eines Triggers oder einer inversen Triggerfunktion ausgeführt. Diese Vorspannung wurde dann von jedem Test abgezogen, um eine repräsentativere Annäherung an die tatsächliche Funktionsauswertungszeit zu erhalten.

Tabelle 2. Zeit in Sekunden, in der die angegebene Funktion oder die angegebenen Funktionen eine Milliarde Mal ausgeführt werden. Die Schätzungen werden erhalten, indem die Zeitkosten für die Bewertung einer Milliarde Zufallszahlen in der ersten Zeile von Tabelle 1 von den verbleibenden Zeilen in Tabelle 1 abgezogen werden.

Zeit in tan () verbracht: 18.0515 18.2545

In TAN3 () verbrachte Zeit (): 5.93853 6.02349

In TAN4 () verbrachte Zeit (): 6,72216 6,99134

Zeit in sin () und cos () verbracht: 19.4052 19.4311

In SINCOS3 () verbrachte Zeit: 7.85564 7.92844

Zeit, die in SINCOS4 () verbracht wurde: 9.36672 9.57946

Zeit, die in atan () verbracht wurde: 15.7160 15.6599

In ATAN1 () verbrachte Zeit: 6,47800 6,55230 

Zeit in ATAN2 (): 7.26730 7.24885

In ATAN3 () verbrachte Zeit (): 8,15299 8,21284

In asin () und acos () verbrachte Zeit: 36.8833 36.9496

In ASINCOS1 () verbrachte Zeit: 10.1655 9.78479

In ASINCOS2 () verbrachte Zeit: 10.6236 10.6000

In ASINCOS3 () verbrachte Zeit: 12.8430 12.0707

(Im Interesse der Platzersparnis ist Tabelle 1 nicht gezeigt.) Tabelle 2 zeigt die Ergebnisse von zwei separaten Durchläufen einer Milliarde Bewertungen jeder Näherungsfunktion. Die erste Spalte ist der erste Lauf und die zweite Spalte ist der zweite Lauf. Die Zahlen '1', '2', '3' oder '4' in den Funktionsnamen geben die Anzahl der Ausdrücke an, die in der Maclaurin-Serienfunktion verwendet werden, um den jeweiligen Trig oder die inverse Trig-Näherung zu bewerten. SINCOS # () bedeutet, dass sowohl sin als auch cos gleichzeitig ausgewertet wurden. In gleicher Weise bedeutet ASINCOS # (), dass sowohl Asin als auch Acos gleichzeitig ausgewertet wurden. Die gleichzeitige Bewertung beider Mengen hat wenig zusätzlichen Aufwand.

Die Ergebnisse zeigen, dass das Erhöhen der Anzahl von Begriffen die Ausführungszeit wie erwartet geringfügig erhöht. Selbst die kleinste Anzahl von Ausdrücken ergab überall eine Genauigkeit von 12 bis 14 Stellen, mit Ausnahme der Annäherung von tan () in der Nähe, wo sich ihr Wert ± unendlich nähert. Man würde erwarten, dass sogar die tan () - Funktion dort Probleme hat.

Ähnliche Ergebnisse wurden auf einem hochwertigen MacBook Pro-Laptop unter Unix und auf einem hochwertigen Desktop-Computer unter Linux erzielt.

0
Roger Wehage