Haversine-Formel liefert falsche Werte

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
__blackjack__
User
Beiträge: 13130
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Strawk: Wo kommt denn die zweite Zeile her? Oder wo sind die Zeilen dazwischen geblieben?
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Code: Alles auswählen

coords = get_airport_positions("data\\airports.dat", "All")
counter = 0
# print(len(coords))
for i in range(7184):
    coord0 = coords[i]
    coords = np.array(coords[i+1:]) # slicing von i+1 bis Ende Array
ergibt:
IndexError: index 119 is out of bounds for axis 0 with size 44
Mehr ist da nicht, alles andere ist auskommentiert.
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
ThomasL
User
Beiträge: 1367
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

mach mal print(coords.shape)
in der Annahme, dass das ein numpy ndarray ist.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo ThomasL! :-)
Wäre ja nicht das erste Mal, dass du mir entscheidend hilfst.
(7184, 2)
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Code: Alles auswählen

coords = get_airport_positions("data\\airports.dat", "All")
coords = np.array(coords)
counter = 0
# print(len(coords))
print(coords.shape)
for i in range(10):
    coord0 = coords[i]
    coords = coords[i+1:] # slicing von i+1 bis Ende Array
    print(len(coords))
(7184, 2)
7183
7181
7178
7174
7169
7163
7156
7148
7139
7129
Verkürzt sich in immer größeren Schritten, statt 1er-Schritten. Ich habe wohl ein größeres Brett vorm Kopf.
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 13130
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Strawk: Du veränderst/verkürzt die Länge von `coords` ja bei jedem Schleifendurchlauf *selbst* und wunderst Dich dann, dass die kürzer wird? Und genau das hattest Du beim ersten mal als Du das Problem beschrieben hast, auch gar nicht gezeigt, dass Du `coords` immer wieder an kürzere Arrays bindest.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Benutzeravatar
ThomasL
User
Beiträge: 1367
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Länge coords = 7184
i läuft von 0 bis 9 also
i=0 coords = coords[1:] Länge um 1 gekürzt 7183
i=1 coords = coords[2;] Länge nochmals um 2 gekürzt also 7181
i=2 coords = coords[3;] Länge nochmals um 3 gekürzt also 7178
etc
Was willst du denn mit dieser Zuweisung bewirken?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hi!

So! :)

Bitte kritisieren. Die Konvention Funktionen/Variablen kann ich nicht ändern; mein Lehrer will es so.

Code: Alles auswählen

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 26 10:45:34 2019

@author: Karl Kraft
"""
from __future__ import print_function, division
import numpy as np
from distances_airports_worldwide import get_airport_positions
import time

def haversine(lat1, lat2, lon1, lon2):
    """ calculates the distance in meters between geographical points
    """
    # in: 2 pairs of coordinates
    # out: distance in meters of them
    
    # Haversine formula
    lat1 = np.radians(lat1)
    lat2 = np.radians(lat2)
    lon1 = np.radians(lon1)
    lon2 = np.radians(lon2)
    leftParenthesis = ((lat2 - lat1)/2)
    rightParenthesis = ((lon2 - lon1)/2)
    allUnderSquareRoot = ((np.sin(leftParenthesis))**2) + np.cos(lat1)*np.cos(lat2)*(np.sin(rightParenthesis))**2
    squareRootResult = np.sqrt(allUnderSquareRoot)
    arcSin = np.arcsin(squareRootResult)
    middleEarthRadiusKm = 6371.009
    middleEarthRadiusM = middleEarthRadiusKm * 1000
    distancesMeters = 2 * middleEarthRadiusM * arcSin
    
    return distancesMeters

def haversine_vectorized(coord0, coords):
    """ prepares data vor vectorized use of haversine-function
    """
    # in: one tupel of first 2 coordinates, list of all remainung coordinates
    # out: vectorized result, which is list of kilometers
    lat0, lon0 = coord0
    lats = coords[:,0] # 1. Spalte von coords (= array von latitudes)
    lons = coords[:,1] # 2. Spalte von coords (= array von longitudes)
    result_vectorized = haversine(lat0, lats, lon0, lons)
    
    return result_vectorized

def calc_dist_all2all_airports(airport_file, country):
    """ calculates the distances of each airport to each and adds them
    """
    # in: the file where the airport data are stored, the desired country
    # out: added kilometers of all the distances, number of calculations done
    coords = get_airport_positions(airport_file, country)
    coords = np.array(coords)
    coordsOneValue = coords
    multipleKilometers = []
    counter = 0
    for i in range(len(coords)):
        coord0 = coordsOneValue[i]
        coords = coords[i+1:] # slicing from i+1 until end array
        result_vectorized = haversine_vectorized(coord0, coords) / 1000
        multipleKilometers.extend(result_vectorized)
        counter += 1
    sumKilometers = sum(multipleKilometers)
    nCalculations = counter
    
    return sumKilometers, nCalculations

# number of airports: 7184
if __name__ == "__main__":
    t0 = time.clock()
    sumKilometers, nCalculations = calc_dist_all2all_airports("data\\airports.dat", country="All")
    print("sum kilometers: %10.1f" % (sumKilometers))
    print("number of calculations done: %10.f" % (nCalculations))
    print("Computation of distances took %6.2f secs" % (time.clock()-t0))

Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17766
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: Konvention hin oder her, Variablen schreibt man klein_mit_unterstrich. Warum nennst Du nCalculations mal counter? und zählst die Länge von coords, das ist doch unnötig. Und warum n? number_of_calculations (richtig geschrieben) sind das ja auch nicht, sondern nur die Anzahl der Flughäfen (number_of_airports).
Was soll dann noch coords_one_value? Das ist das selbe wie coords, also überflüssig.

Mit ein bißchen numy wird das ganze dann deutlich kürzer.

Code: Alles auswählen

EARTH_RADIUS_IN_M = 63710090

def haversine(lat1, lat2, lon1, lon2):
    """ calculates the distance in meters between geographical points
    in: 2 pairs of coordinates in radians
    out: distance in meters of them
    """
    mean_lat = (lat2 - lat1) * 0.5
    mean_lon = (lon2 - lon1) * 0.5
    a = np.sin(mean_lat)**2 + np.cos(lat1)*np.cos(lat2)* np.sin(mean_lon)**2
    return 2 * EARTH_RADIUS_IN_M * np.arcsin(a**0.5)

def calc_dist_all2all_airports(airport_file, country):
    """ calculates the distances of each airport to each and adds them
    in: the file where the airport data are stored, the desired country
    out: added kilometers of all the distances, number of calculations done
    """
    coords = get_airport_positions(airport_file, country)
    lat, lon = np.radians(coords).T
    distances = haversine(lat[:, None], lon[:, None], lat[None, :], lon[None, :])
    return distances.sum()/2, len(coords)

# number of airports: 7184
if __name__ == "__main__":
    t0 = time.clock()
    total_distance, number_of_airports = calc_dist_all2all_airports("data\\airports.dat", country="All")
    print("sum of kilometers: %10.1f" % total_distance)
    print("number of airports: %10d" % number_of_airports)
    print("Computation of distances took %6.2f secs" % (time.clock()-t0))
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Aufgabe ist aktuell, eine Matrix distance_airports(i)(j) zu schaffen, in der jeweils die Abstände in Kilometern des i-ten Flughafens zum j-ten Flughafen enthalten sind. Daran beiße ich mir seit Dienstag die Zähne aus. Problem ist, dass die Daten ja bisher mittels Vektor generiert werden. Das kriege ich mit einer Struktur (i)(j) nicht zusammen gebacken. Benötige dazu mal einen heißen Tipp. Ich habe runde Klammern benutzt, um die Forumssoftware nicht zu verwirren (italics).

Strawk :)
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17766
Registriert: Sonntag 21. Oktober 2012, 17:20

Bis auf den Punkt, dass ich lat und lon ein bißchen durcheinander gebracht habe, rechnet ›calc_dist_all2all_airports‹ genau das was du willst.
Benutzeravatar
Strawk
User
Beiträge: 233
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

@Sirius3: Habe ich denn etwas nicht gleichlautendes behauptet? :)

Grüße, Strawk
Ich programmiere erfolglos, also bin ich nicht.
Antworten