Pourquoi la loi des cosinus est-elle préférable à haversine lors du calcul de la distance entre deux points de latitude-longitude?


41

En fait, lorsque Sinnott a publié la formule de haversine, la précision des calculs était limitée. De nos jours, JavaScript (et la plupart des ordinateurs et langages modernes) utilise des nombres à virgule flottante IEEE 754 64 bits, qui fournissent 15 chiffres de précision significatifs. Avec cette précision, la loi sphérique simple de la formule des cosinus ( cos c = cos a cos b + sin a sin b cos C) donne des résultats bien conditionnés jusqu'à des distances aussi petites que 1 mètre environ. Compte tenu de cela, il vaut probablement la peine, dans la plupart des cas, d’utiliser la loi plus simple des cosinus ou la formule ellipsoïdale plus précise de Vincenty, de préférence à la haversine! (en gardant à l’esprit les remarques ci-dessous sur les limites de précision du modèle sphérique).
Source: http://www.movable-type.co.uk/scripts/latlong.html

Quelle est la raison pour laquelle la loi des cosinus est plus préférable?

Remarque: le texte cité a été mis à jour par son auteur comme indiqué ci - dessous .


10
Comment la loi des cosinus est-elle "préférable"? Nous pouvons répondre à cette question de deux manières: pour l'ordinateur et le programmeur. Pour l'ordinateur, la formule haversine utilise moins de fonctions trigonométriques mais nécessite deux racines carrées. Pour l'efficacité du calcul, alors, c'est un coup monté. Pour le programmeur, la formule de haversine est un peu plus longue. Cependant, la formule de la loi des cosinus nécessite une implémentation ACos, qui est vue un peu moins fréquemment qu'une implémentation ATan. De plus, pour écrire du code à l'épreuve des balles, vous devez vérifier que les ACo n'échoueront pas. Pour cette seule raison, nous devrions préférer haversine.
whuber

2
Je viens d'implémenter haversine et cosinus en Python. Sur cet ordinateur, haversine prend 3,3 μs et le cosinus, 2,2 μs, ce qui est assez important si vous devez en faire beaucoup
gnibbler

1
Merci à tous pour de bonnes observations et informations. J'ai mis à jour le texte cité dans la question pour qu'il soit, j'espère, plutôt objectif et utile.
ChrisV

@ChrisV, merci pour la mise à jour! J'ai déplacé ceci dans un commentaire car il ne s'agit pas directement d'une réponse à la question, merci pour votre site formidable.
scw

Réponses:


49

Le problème est indiqué par le mot "bien conditionné". C'est une question d'arithmétique informatique, pas de mathématiques.

Voici les faits de base à considérer:

  1. Un radian sur la terre couvre près de 10 ^ 7 mètres.

  2. La fonction cosinus pour les arguments x proches de 0 est approximativement égale à 1 - x ^ 2/2.

  3. La virgule flottante double précision a environ 15 chiffres décimaux de précision.

Les points (2) et (3) impliquent que lorsque x mesure environ un mètre ou 10 ^ -7 radians (point 1), la quasi-totalité de la précision est perdue: 1 - (10 ^ -7) ^ 2 = 1 - 10 ^ - 14 est un calcul dans lequel les 14 premiers des 15 chiffres significatifs sont tous annulés, ne laissant qu'un chiffre pour représenter le résultat. En inversant la situation (ce que fait le cosinus inverse, "acos") signifie que le calcul des acos pour des angles correspondant à des distances d'un mètre ne peut pas être effectué avec une précision significative. (Dans certains mauvais cas, la perte de précision donne une valeur où acos n'est même pas défini, ainsi le code s'effondrera sans donner de réponse, une réponse absurde ou un crash de la machine.) Des considérations similaires suggèrent que vous évitiez l'utilisation du cosinus inverse. si des distances inférieures à quelques centaines de mètres sont impliquées, cela dépend de la précision que vous êtes prêt à perdre.

Le rôle joué par acos dans la formule naïve du droit des cosinus est de convertir un angle en distance. Ce rôle est joué par atan2 dans la formule de haversine. La tangente d'un petit angle x est approximativement égale à x elle-même. Par conséquent, la tangente inverse d'un nombre, qui est approximativement ce nombre, est calculée essentiellement sans perte de précision. C'est pourquoi la formule haversine, bien que mathématiquement équivalente à la formule de la loi des cosinus, est de loin supérieure pour les petites distances (de l'ordre de 1 mètre ou moins).

Voici une comparaison des deux formules utilisant 100 paires de points aléatoires sur le globe (en utilisant les calculs à double précision de Mathematica).

texte alternatif

Vous pouvez voir que pour des distances inférieures à environ 0,5 mètre, les deux formules divergent. Au-dessus de 0,5 mètre, ils ont tendance à être d'accord. Pour montrer à quel point ils sont d’accord, le graphique suivant présente les ratios de la loi des cosinus: résultats de la régression rapide pour 100 autres paires de points aléatoires, avec leurs latitudes et longitudes différant de manière aléatoire jusqu’à 5 mètres.

texte alternatif

Cela montre que la formule de la loi des cosinus est bonne à 3 ou 4 décimales une fois que la distance dépasse 5 à 10 mètres. Le nombre de décimales de précision augmente de façon quadratique; ainsi, à 50-100 mètres (un ordre de grandeur), vous obtenez une précision de 5 à 6 dp (deux ordres de grandeur); à 500-1000 mètres, vous obtenez 7-8 dp, etc.


Existe-t-il un test bon marché - par exemple, delta latitude > .1 || delta longitude > .1choisir de manière dynamique un cosinus (pour les grandes tailles) ou une formule inverse (pour les petites distances)? Afin d'obtenir les meilleures performances et une bonne précision.
Anony-Mousse

@ Anony-Mousse Les deux formules peuvent être décalées de quelques dixièmes de un pour cent pour les distances d'un quart du monde, alors nous ne nous occuperons pas de la précision! Par conséquent, tout test permettant de distinguer des points rapprochés (quelques centaines de mètres) de points presque diamétralement opposés (environ 20 millions de mètres) de tout ce qui les sépare devrait être suffisant.
whuber

atan2Offre- t-il des avantages numériques asin? J'ai vu des repères, où atan2était 2-3x plus lent que asin, et nous avons besoin d'une seconde sqrtaussi.
Erich Schubert

@Erich Je n'ai pas étudié la différence, mais remarquez qu'il asins'agit essentiellement de la même chose acoset que , par conséquent, de la même perte de précision pour certaines valeurs - dans ce cas, pour les arguments proches de 1 et -1. En principe, atan2n'a pas ce problème.
whuber

Ce serait à très grandes distances? Combiner cela avec la suggestion de @ Anony-Mousse ci-dessus semble alors intéressant.
Erich Schubert

7

Une note de bas de page historique:

La haversine était un moyen d’éviter de grosses erreurs d’arrondi dans les calculs tels que

1 - cos(x)

quand x est petit. En termes de haversine nous avons

1 - cos(x) = 2*sin(x/2)^2
           = 2*haversin(x)

et 2 * sin (x / 2) ^ 2 peuvent être calculés avec précision même lorsque x est petit.

Auparavant, la formule haversine présentait l'avantage supplémentaire d'éviter une addition (ce qui impliquait une recherche d'antilog, une addition et une recherche de journal). Une formule trigonométique qui ne comportait que des multiplications était dite "sous forme logarithmique".

De nos jours, l'utilisation des formules de haversine est légèrement anachronique. Il se peut que l'angle x soit exprimé en termes sin(x)et cos(x)(et que x ne soit pas explicitement connu). Dans ce cas, le calcul 1 - cos(x)via la formule de haversine implique une arctangente (pour obtenir l'angle x), une réduction de moitié (pour obtenir x/2), un sinus (pour obtenir sin(x/2)), un carré (pour obtenir sin(x/2)^2) et un doublement final. Vous êtes bien mieux en utilisant l'évaluation

1 - cos(x) = sin(x)^2/(1 + cos(x))

ce qui n'implique aucune évaluation des fonctions trigonométriques. (Évidemment, utilisez le côté droit uniquement si cos(x) > 0; sinon, vous pouvez utiliser 1 - cos(x)directement.)


1

La formule cosinus peut être implémentée sur une seule ligne:

  Distance = acos(SIN(lat1)*SIN(lat2)+COS(lat1)*COS(lat2)*COS(lon2-lon1))*6371

La formule haversine prend plusieurs lignes:

  dLat = (lat2-lat1)
  dLon = (lon2-lon1)
  a = sin(dLat/2) * sin(dLat/2) + cos(lat1) * cos(lat2) * sin(dLon/2) * sin(dLon/2)
  distance = 6371 * 2 * atan2(sqrt(a), sqrt(1-a))

Mathématiquement, ils sont identiques, la seule différence est donc pratique.


Bien que Haversine d’origine n’utilise pas la atan2formule informatique, rien n’empêche de réécrire les 4 lignes ci-dessus dans une seule formule.
Arjan

@ Arjan, est vrai, mais il serait inefficace parce que vous auriez besoin de calculer un double. Il est essentiel que la formule implique à la fois Sqrt (a) et Sqrt (1-a), car si l'un d'entre eux sera numériquement instable sur de très petites ou de très grandes distances, l'autre ne le sera pas: voilà pourquoi cette approche fonctionne.
whuber

C'est vrai, @ whuber, mais je doute que le nombre de lignes me fasse choisir l'une au lieu de l'autre. (Et comme vous l'avez déjà expliqué dans votre réponse, il existe des raisons bien plus importantes d'en favoriser une.)
Arjan

3
@ Arjan je suis d'accord. La première priorité devrait être l’adéquation du code pour la tâche de programmation. Après cela, je placerais la clarté: la lisibilité, la maintenabilité et la documentation littéraire. Sans un tel contexte, compter le nombre de lignes de code n'a pas de sens.
whuber

1
atan2(sqrt(a), sqrt(1-a))est le même queasin(sqrt(a))
user102008
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.