36 votes

Définitions de sqrt, sin, cos, pow etc. en cmath

Existe-t-il des définitions de fonctions comme sqrt() , sin() , cos() , tan() , log() , exp() (ceux de math.h/cmath) disponibles ?

Je voulais juste savoir comment ils fonctionnent.

1 votes

Fdlibm fournit des implémentations de toutes ces choses, et est open-source, autonome, assez lisible. Ce ne sont pas les implémentations les plus simples possibles, puisqu'elles sont conçues pour fournir des performances décentes.

0 votes

66voto

Alexandre C. Points 31758

C'est une question intéressante, mais la lecture des sources de bibliothèques efficaces ne vous mènera pas très loin si vous ne connaissez pas la méthode utilisée.

Voici quelques indications pour vous aider à comprendre les méthodes classiques. Mes informations ne sont en aucun cas exactes. Les méthodes suivantes ne sont que les méthodes classiques, des implémentations particulières peuvent utiliser d'autres méthodes.

  • Les tables de consultation sont fréquemment utilisées
  • Les fonctions trigonométriques sont souvent implémentées via la fonction CORDIC (soit sur l'unité centrale, soit avec une bibliothèque). Notez qu'habituellement le sinus et le cosinus sont calculés ensemble, je me suis toujours demandé pourquoi la bibliothèque C standard ne fournit pas une fonction sincos fonction.
  • Utilisation des racines carrées Méthode de Newton avec quelques astuces d'implémentation : vous trouverez peut-être quelque part sur le web un extrait du code source de Quake avec une implémentation de 1 / sqrt(x) époustouflante.
  • Les exponentielles et logarithmes utilisent exp(2^n x) = exp(x)^(2^n) et log2(2^n x) = n + log2(x) pour avoir un argument proche de zéro (de un pour log) et utilisent une approximation de fonction rationnelle (généralement Padé approximatifs ). Notez que cette même astuce permet d'obtenir des exponentielles et des logarithmes de matrice. Selon @Stephen Canon, les implémentations modernes favorisent l'expansion de Taylor par rapport à l'approximation des fonctions rationnelles où la division est beaucoup plus lente que la multiplication.
  • Les autres fonctions peuvent être déduites de celles-ci. Les implémentations peuvent fournir des routines spécialisées.
  • pow(x, y) = exp(y * log(x)), donc pow est pas à utiliser lorsque y est un nombre entier
  • hypot(x, y) = abs(x) sqrt(1 + (y/x)^2) si x > y (hypot(y, x) sinon) pour éviter le débordement. atan2 est calculée par un appel à sincos et un peu de logique. Ces fonctions sont les éléments constitutifs de l'arithmétique complexe.
  • Pour les autres fonctions transcendantales (gamma, erf, bessel, ...), veuillez consulter l'excellent ouvrage suivant Recettes numériques, 3e édition pour avoir quelques idées. Le bon vieux Abramowitz & Stegun est également utile. Il existe une nouvelle version à l'adresse http://dlmf.nist.gov/ .
  • Des techniques comme l'approximation de Chebyshev, l'expansion de fraction continue (en fait liée aux approximations de Padé) ou l'économie de séries de puissance sont utilisées dans des fonctions plus complexes (s'il vous arrive de lire le code source de erf, bessel ou gamma par exemple). Je doute qu'elles aient une réelle utilité dans les fonctions mathématiques simples, mais qui sait ? Consultez Numerical Recipes pour un aperçu.

10 votes

+1 pour avoir expliqué les maths. Je me suis senti beaucoup mieux quand j'ai réalisé que les fonctions trigonométriques n'étaient que des expansions de séries de Taylor tronquées. Sinon, les approximations ressemblent à de la magie !

3 votes

@Ben : les bonnes bibliothèques n'utilisent généralement pas de séries de taylor tronquées -- d'autres approximations polynomiales (Minimax, Chebyshev, Padé) ont des caractéristiques d'erreur beaucoup plus souhaitables et permettent d'obtenir la même précision avec moins d'opérations arithmétiques.

2 votes

@Alexandre : l'approximation rationnelle n'est plus à la mode depuis quelques années. exp y log parce que la multiplication et l'addition sont beaucoup plus rapides que la division sur le matériel moderne. Elle est cependant toujours utilisée pour des fonctions plus rigides.

21voto

birryree Points 29165

Chaque implémentation peut être différente, mais vous pouvez vérifier une implémentation à partir du code source de glibc (la bibliothèque C de GNU).

edit : Google Code Search a été mis hors ligne, donc l'ancien lien que j'avais ne mène nulle part.

Les sources de la bibliothèque mathématique de la glibc sont situées ici :

http://sourceware.org/git/?p=glibc.git;a=tree;f=math;h=3d5233a292f12cd9e9b9c67c3a114c64564d72ab;hb=HEAD

7voto

ismail Points 19146

Regardez comment glibc met en œuvre diverses fonctions mathématiques, pleines de magie, d'approximation et d'assemblage.

0 votes

+1 pour le lien vers le logiciel source de la glibc, mais wow le site est lent en ce moment. (édité)

1 votes

A priori, ce sont les versions les plus lentes avec des implémentations plus rapides dans des sous-dossiers spécifiques à l'arch.

2 votes

LOL, internet est toujours lent ici, je ne vois pas de différence ;)

5voto

Daniel Trebbien Points 18089

Jetez un coup d'œil à la fdlibm sources. Elles sont agréables car la bibliothèque fdlibm est autonome, chaque fonction est bien documentée avec des explications détaillées des mathématiques impliquées, et le code est extrêmement clair à lire.

4voto

David Cournapeau Points 21956

Ayant beaucoup regardé le code mathématique, je déconseille de regarder la glibc - le code est souvent assez difficile à suivre, et dépend beaucoup de la magie de la glibc. Le site librairie mathématique sous FreeBSD est beaucoup plus facile à lire, même si elle est parfois plus lente (mais pas de beaucoup).

Pour les fonctions complexes, la principale difficulté réside dans les cas limites - le traitement correct des nan/inf/0 est déjà difficile pour les fonctions réelles, mais c'est un cauchemar pour les fonctions complexes. La norme C99 définit de nombreux cas limites, certaines fonctions ont facilement 10 à 20 cas limites. Vous pouvez consulter l'annexe G de la version la plus récente de la norme C99. Document standard C99 pour se faire une idée. Il y a aussi une difficulté avec le double long, car son format n'est pas standardisé - d'après mon expérience, vous devez vous attendre à un certain nombre de bogues avec le double long. J'espère que la prochaine version révisée de la norme IEEE754 avec une précision étendue améliorera la situation.

0 votes

Bonne remarque sur les cas particuliers. Ils peuvent facilement devenir des goulots d'étranglement dans certains cas (l'implémentation de ldexp sur MSVC rend la fonction plutôt inutile par exemple)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X