Die approximation der inversen trigonometrischen Funktionen
Ich habe zu implementieren, asin, acos und atan in der Umgebung, wo ich nur folgende Mathe-tools:
- Sinus
- Cosinus
- elementaren fixed-point Arithmetik (floating-point-zahlen sind nicht verfügbar)
Ich auch schon einigermaßen gute Wurzel-Funktion.
Kann ich die Umsetzung einigermaßen effizient inverse trigonometrische Funktionen?
Brauche ich nicht zu große Präzision (die floating-point-zahlen haben eine sehr begrenzte Genauigkeit egal), grundlegende Annäherung zu tun.
Ich bin schon halb entschlossen, zu gehen mit lookup-Tabelle, aber ich würde gerne wissen, wenn es etwas ordentlicher option (das muss nicht mehrere hundert Zeilen code, einfach zu implementieren einfache Mathematik).
EDIT:
, Um die Sache aufzuklären: ich brauche, um die Funktion auszuführen, Hunderte Male pro Bild bei 35 frames pro Sekunde.
- mögliche Duplikate von Wie kann Trigonometrischen Funktionen arbeiten?
- Die vorgeschlagene doppelte ist mehr darüber, wie die trigonometrischen Funktionen arbeiten (wie Titel). Dies ist über die inverse trigonometrische Funktionen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Benötigen Sie ein großer Präzision für
arcsin(x)
Funktion? Wenn Nein, Sie können die Berechnungarcsin
im N Knoten, und halten die Werte im Speicher. Ich schlage vor, mit line-aproximation. wennx = A*x_(N) + (1-A)*x_(N+1)
dannx = A*arcsin(x_(N)) + (1-A)*arcsin(x_(N+1))
woarcsin(x_(N))
bekannt ist.In einem fixed-point-Umgebung (S15.16) ich habe erfolgreich verwendet den CORDIC-Algorithmus (siehe Wikipedia für eine Allgemeine Beschreibung) zu berechnen atan2(y,x), dann aus der asin() und acos() aus, die mit bekannten funktionalen Identitäten, die mit der Quadratwurzel:
Es stellt sich heraus, dass die Suche nach einem sinnvollen Beschreibung des CORDIC-iteration für die atan2() für die double ist schwieriger, als ich dachte. Die folgende Webseite wird angezeigt, um eine hinreichend detaillierte Beschreibung, und auch beschreibt zwei alternative Ansätze, die polynomiale approximation und lookup-Tabellen:
http://ch.mathworks.com/examples/matlab-fixed-point-designer/615-calculate-fixed-point-arctangent
möchten Sie vielleicht zu verwenden Annäherung: verwenden Sie eine unendliche Reihe, bis die Lösung ist nahe genug für Sie.
zum Beispiel:
arcsin(z) = Sigma((2n!)/((2^2n)*(n!)^2)*((z^(2n+1))/(2n+1)))
wo n in [0,unendlich)Sollte es einfach sein zu addapt Sie den folgenden code, um festen Punkt. Es beschäftigt rationale approximation zur Berechnung des Arkustangens normiert auf den [0 1) - Intervall (können Sie multiplizieren Sie diese mit Pi/2 zu bekommen, die real Arkustangens). Anschließend können Sie bekannte Identitäten zu Holen Sie sich die arcsin/arccos aus dem Arkustangens.
Sich der maximale Fehler ist 0.1620 º
In Fall müssen Sie mehr Präzision, gibt es eine rationale Funktion 3. Ordnung:
die eine maximale Annäherung Fehler 0.00811 º
Vielleicht eine Art intelligentes brute-force-wie newton-rapson.
Also für die Lösung des asin() Sie gehen mit der Methode des steilsten Abstiegs auf sin()
http://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Expression_as_definite_integrals
Könnte man tun, dass die integration numerisch mit Ihrem Wurzel-Funktion, die approximation mit einer unendlichen Reihe:
Einreichen, hier meine Antwort aus diesem andere ähnliche Frage.
nVidia hat einige große Ressourcen, die ich verwendet habe, für meine eigenen verwendet, einige Beispiele: acos asin atan2 etc etc...
Diese algorithmen produzieren präzise genug Ergebnisse. Hier ist ein straight-up-Python-Beispiel mit Ihrem code kopieren eingefügt:
Und hier sind die Ergebnisse für den Vergleich:
Das ist ziemlich nah! Multiplizieren von 57.29577951 um Ergebnisse zu erhalten (in Grad), die auch von Ihrem "Grad" - Formel.
Verwenden Sie eine Polynom-approximation. Least-squares-fit ist am einfachsten (Microsoft Excel) und Tschebyscheff-approximation genauer ist.
Diese Frage wurde abgedeckt, bevor: Wie Trigonometrische Funktionen funktionieren?
Nur stetige Funktionen sind approximable von Polynomen. Und arcsin(x) ist discontinous im Punkt x=1.gleich arccos(x).Aber eine Reihe Reduktion auf Intervall 1,sqrt(1/2) in diesem Fall diese situation vermeiden. Wir haben arcsin(x)=pi/2 - arccos(x),arccos(x)=pi/2-arcsin(x).Sie können verwenden Sie matlab für die minimax-approximation.Aproximate nur im Bereich [0,sqrt(1/2)](wenn Winkel, der arcsin ist die Anfrage größer ist, dass sqrt(1/2) finden cos(x).Arkustangens-Funktion nur für x<1.arctan(x)=pi/2-arctan(1/x).