Ainsi, en mathématiques au secondaire et probablement au collège, on nous apprend à utiliser les fonctions trigonométriques, ce qu’elles font et le type de problèmes qu’elles résolvent. Mais ils m'ont toujours été présentés comme une boîte noire. Si vous avez besoin du sinus ou du cosinus de quelque chose, vous appuyez sur le bouton péché ou cos de votre calculatrice et vous êtes prêt. Ce qui va bien.
Ce que je me demande, c'est comment les fonctions trigonométriques sont généralement implémentées.
Tout d'abord, vous devez faire une sorte de réduction de la portée. Les fonctions Trig étant périodiques, vous devez donc réduire les arguments à un intervalle standard. Pour commencer, vous pouvez réduire les angles entre 0 et 360 degrés. Mais en utilisant quelques identités, vous réalisez que vous pourriez vous en tirer avec moins. Si vous calculez des sinus et des cosinus pour des angles compris entre 0 et 45 degrés, vous pouvez commencer à calculer toutes les fonctions trigonométriques pour tous les angles.
Une fois que vous avez réduit votre argument, la plupart des puces utilisent un algorithme CORDIC pour calculer les sinus et les cosinus. Vous pouvez entendre des gens dire que les ordinateurs utilisent la série de Taylor. Cela semble raisonnable, mais ce n'est pas vrai. Les algorithmes CORDIC conviennent beaucoup mieux à une implémentation efficace de matériel. (Les bibliothèques Software peuvent utiliser des séries de Taylor, par exemple sur du matériel qui ne prend pas en charge les fonctions trig.) Il peut y avoir un traitement supplémentaire, utilisant l'algorithme CORDIC pour obtenir d'assez bonnes réponses mais faisant autre chose pour améliorer la précision.
Il y a quelques raffinements à ce qui précède. Par exemple, pour de très petits angles, thêta (en radians), sin (thêta) = thêta avec toute la précision dont vous disposez, il est donc plus efficace de simplement renvoyer thêta que d'utiliser un autre algorithme. Donc, dans la pratique, il y a beaucoup de logique de cas spéciale pour extraire toutes les performances et la précision possibles. Les puces avec des marchés plus petits risquent de ne pas nécessiter autant d’optimisation.
edit: Jack Ganssle a une discussion décente dans son livre sur les systèmes embarqués, "The Firmware Handbook" .
Pour votre information: si vous avez des contraintes de précision et de performances, les séries de Taylor doivent et non être utilisées pour approximer des fonctions à des fins numériques. (Enregistrez-les pour vos cours de calcul.) Ils utilisent le analyticity d'une fonction en un point unique , par exemple. le fait que tous ses dérivés existent à ce point. Ils ne convergent pas nécessairement dans l'intervalle d'intérêt. Souvent, ils font un travail de distribution moche de la précision de l'approximation de la fonction afin d'être "parfaits" tout près du point d'évaluation; l'erreur s'agrandit généralement lorsque vous vous en éloignez. Et si vous avez une fonction avec tout dérivé non continu (par exemple, les ondes carrées, les ondes triangulaires et leurs intégrales), une série de Taylor vous donnera la mauvaise réponse.
La meilleure solution "facile", lorsque vous utilisez un polynôme de degré N maximum pour approximer une fonction donnée f(x) sur un intervalle x0 <x <x1, est de approximation de Chebyshev ; voir Recettes numériques pour une bonne discussion. Notez que Tj (x) et Tk (x) dans l'article de Wolfram I lié aux cos et cosinus inversés utilisés sont des polynômes et qu'en pratique, vous utilisez une formule de récurrence pour obtenir les coefficients. Encore une fois, voir Recettes numériques.
edit: Wikipedia a un article semi-décent sur théorie de l'approximation . L’une des sources citées (Hart, "Computer Approximations") est épuisée (les copies utilisées tendent à être chères), mais elle donne beaucoup de détails sur ce genre de choses. (Jack Ganssle le mentionne dans le numéro 39 de sa lettre d’information The Embedded Muse .)
edit 2: Voici quelques métriques d'erreur tangibles (voir ci-dessous) pour Taylor vs. Chebyshev pour sin (x). Quelques points importants à noter:
Ne vous méprenez pas: les séries de Taylor fonctionnent correctement pour les sinus/cosinus (avec une précision raisonnable pour la plage -pi/2 à + pi/2; techniquement, avec suffisamment de termes, vous pouvez atteindre la précision souhaitée pour toutes les entrées réelles, mais essayez de calculer cos (100) en utilisant la série de Taylor et vous ne pouvez le faire que si vous utilisez une arithmétique de précision arbitraire). Si j'étais coincé sur une île déserte avec une calculatrice non scientifique et que je devais calculer le sinus et le cosinus, j'utiliserais probablement la série de Taylor, car les coefficients sont faciles à retenir. Mais les applications du monde réel qui obligent à écrire vos propres fonctions sin () ou cos () sont suffisamment rares pour que vous fassiez mieux d'utiliser une implémentation efficace pour atteindre la précision souhaitée - ce que la série de Taylor est pas .
Plage = -pi/2 à + pi/2, degré 5 (3 termes)
Plage = -pi/2 à + pi/2, degré 7 (4 termes)
Plage = -pi/4 à + pi/4, degré 3 (2 termes)
Plage = -pi/4 à + pi/4, degré 5 (3 termes)
Plage = -pi/4 à + pi/4, degré 7 (4 termes)
Je crois qu'ils sont calculés en utilisant Taylor Series ou CORDIC . Certaines applications qui font un usage intensif des fonctions trig (jeux, graphiques) construisent des tables trig au démarrage pour pouvoir simplement rechercher des valeurs plutôt que de les recalculer encore et encore.
Découvrez l'article Wikipedia sur les fonctions trigonométriques. Un bon endroit pour apprendre à les implémenter dans le code est Recettes numériques .
Je ne suis pas un grand mathématicien, mais ma compréhension de l'origine du péché, du cos et du bronzage est qu'ils sont, en un sens, observés lorsque vous travaillez avec des triangles à angle droit. Si vous prenez des mesures de la longueur des côtés d'un groupe de différents triangles à angle droit et tracez les points sur un graphique, vous pouvez obtenir péché, cos et bronzage. Comme le souligne Harper Shelby, les fonctions sont simplement définies comme des propriétés de triangles à angle droit.
Une compréhension plus sophistiquée est obtenue en comprenant comment ces rapports se rapportent à la géométrie du cercle, ce qui conduit aux radians et à toutes ces qualités. Tout est là dans l'entrée Wikipedia.
Le plus souvent pour les ordinateurs, la représentation en série de puissance est utilisée pour calculer les sinus et les cosinus et ceux-ci sont utilisés pour d'autres fonctions trigonométriques. En étendant ces séries à environ 8 termes, les valeurs nécessaires sont calculées avec une précision proche de la machine epsilon (le plus petit nombre à virgule flottante différent de zéro pouvant être tenu).
La méthode CORDIC est plus rapide car elle est implémentée sur le matériel, mais elle est principalement utilisée pour les systèmes intégrés et non pour les ordinateurs standard.
J'aimerais étendre la réponse fournie par @Jason S. En utilisant une méthode de subdivision de domaine similaire à celle décrite par @Jason S et en utilisant des approximations en série de Maclaurin, une accélération moyenne de (2-3) X par rapport à tan (), sin () , cos (), atan (), asin () et acos () intégrées au compilateur gcc avec optimisation -O3 ont été réalisées. Les meilleures fonctions d'approximation de la série Maclaurin décrites ci-dessous ont permis d'obtenir une précision double précision.
Pour les fonctions tan (), sin () et cos () et pour plus de simplicité, un domaine de recouvrement de 0 à 2pi + pi/80 a été divisé en 81 intervalles égaux avec des "points d'ancrage" à pi/80, 3pi/80, ... 161pi/80. Ensuite, tan (), sin () et cos () de ces 81 points d'ancrage ont été évalués et stockés. A l'aide des identités trig, une seule fonction de la série Maclaurin a été développée pour chaque fonction trig. Tout angle compris entre ± l'infini peut être soumis aux fonctions d'approximation trig, car celles-ci traduisent d'abord l'angle d'entrée dans le domaine 0 à 2pi. Cette surcharge de traduction est incluse dans la surcharge d'approximation.
Des méthodes similaires ont été développées pour les fonctions atan (), asin () et acos (), dans lesquelles un domaine qui se chevauchait de -1,0 à 1,1 a été divisé en 21 intervalles égaux avec des points d'ancrage à -19/20, -17/20, .. ., 19/20, 21/20. Alors seulement atan () de ces 21 points d’ancrage a été stocké. Encore une fois, avec l’aide d’identités trigonométriques inverses, une fonction unique de la série Maclaurin a été développée pour la fonction atan (). Les résultats de la fonction atan () ont ensuite été utilisés pour approximer asin () et acos ().
Étant donné que toutes les fonctions d'approximation de trigonométrie inverse sont basées sur la fonction d'approximation d'atan (), toute valeur d'entrée d'argument à double précision est autorisée. Cependant, l'argument entré dans les fonctions d'approximation asin () et acos () est tronqué au domaine ± 1 car toute valeur en dehors de celle-ci n'a pas de sens.
Pour tester les fonctions approximatives, un milliard d’évaluations de fonctions aléatoires ont été forcées (c’est-à-dire que le compilateur optimiseur -O3 n’a pas été autorisé à ignorer l’évaluation, car certains résultats calculés ne seraient pas utilisés). des nombres aléatoires et en traitant les résultats, le coût d'une exécution sans évaluer aucune fonction trig ou inverse n'a été effectué en premier. Ce biais a ensuite été soustrait de chaque test pour obtenir une approximation plus représentative du temps réel d'évaluation des fonctions.
Tableau 2. Temps passé en secondes à exécuter la ou les fonctions indiquées un milliard de fois. Les estimations sont obtenues en soustrayant le coût en temps de l'évaluation d'un milliard de nombres aléatoires indiqués dans la première ligne du tableau 1 des lignes restantes du tableau 1.
Temps passé à bronzer (): 18.0515 18.2545
Temps passé dans TAN3 (): 5.93853 6.02349
Temps passé dans TAN4 (): 6.72216 6.99134
Temps passé dans sin () et cos (): 19.4052 19.4311
Temps passé dans SINCOS3 (): 7.85564 7.92844
Temps passé dans SINCOS4 (): 9.36672 9.57946
Temps passé à atan (): 15.7160 15.6599
Temps passé dans ATAN1 (): 6.47800 6.55230
Temps passé dans ATAN2 (): 7.26730 7.24885
Temps passé dans ATAN3 (): 8.15299 8.21284
Temps passé en asin () et acos (): 36.8833 36.9496
Temps passé dans ASINCOS1 (): 10.1655 9.78479
Temps passé dans ASINCOS2 (): 10.6236 10.6000
Temps passé dans ASINCOS3 (): 12.8430 12.0707
(Dans l'intérêt d'économiser de l'espace, le tableau 1 n'est pas présenté.) Le tableau 2 montre les résultats de deux exécutions distinctes d'un milliard d'évaluations de chaque fonction approximative. La première colonne est la première analyse et la deuxième colonne est la deuxième analyse. Les nombres '1', '2', '3' ou '4' dans les noms de fonctions indiquent le nombre de termes utilisés dans la fonction de la série de Maclaurin pour évaluer l'approximation trig ou inverse trig particulière. SINCOS # () signifie que sin et cos ont été évalués simultanément. De même, ASINCOS # () signifie que asin et acos ont été évalués simultanément. L'évaluation des deux quantités en même temps entraîne peu de frais généraux supplémentaires.
Les résultats montrent que l'augmentation du nombre de termes augmente légèrement le temps d'exécution, comme prévu. Même le plus petit nombre de termes donnait partout une précision d'environ 12 à 14 chiffres, à l'exception de l'approximation tan () près de l'endroit où sa valeur est proche de l'infini. On s'attendrait même à ce que la fonction tan () y pose des problèmes.
Des résultats similaires ont été obtenus sur un ordinateur portable MacBook Pro haut de gamme sous Unix et sur un ordinateur de bureau haut de gamme sous Linux.