Mercurial > hg > GlobalNeighbors
diff tests/test_distance.py @ 0:5dba84370182
initial commit; half-working prototype
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Sat, 24 Jun 2017 12:03:39 -0700 |
parents | |
children | 1b94f3bf97e5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_distance.py Sat Jun 24 12:03:39 2017 -0700 @@ -0,0 +1,106 @@ +#!/usr/bin/env python + +""" +test distance calculation +""" + +import math +import os +import unittest +from globalneighbors import distance +from globalneighbors.constants import Rearth +from globalneighbors.locations import locations +from globalneighbors.read import read_city_list +from globalneighbors.schema import primary_key + +here = os.path.dirname(os.path.abspath(__file__)) +data = os.path.join(here, 'data') +full_tsv_lines = 149092 + +class DistanceTests(unittest.TestCase): + + # created with + # head -n 10 cities1000.txt > GlobalNeighbors/tests/data/sample.tsv + test_tsv = os.path.join(data, 'sample.tsv') + test_tsv_lines = 10 + + # full dataset: test with caution + full_tsv = os.path.join(data, 'cities1000.txt') + full_tsv_lines = 149092 + + def test_haversine(self): + + # a simple canned case + # equator to pole + lat1 = 0. + lat2 = 90. + lon2 = 70. # undefined, technically + expected_distance = 0.5*math.pi + + for lon1 in range(-135, 135, 15): + radians = [distance.deg_to_rad(degrees) + for degrees in (lat1, lon2, lat2, lon2)] + error = (distance.haversine(*radians) == expected_distance) + assert error < 1e-4 + + def test_distance(self): + """test distance between two known cities""" + + # Source:https://en.wikipedia.org/wiki/List_of_cities_by_latitude + # http://www.distancefromto.net/distance-from-new-york-to-chicago-us + chicago = (40.71278, + -74.00594) + + new_york = (41.85003, + -87.65005) + ref_distance = 1149. + + args = [distance.deg_to_rad(i) for i in + list(chicago) + list(new_york)] + calculated = distance.haversine(*args, r=Rearth) + + # Allow some error for circular projection approximation + error = abs(calculated - ref_distance)/ref_distance + + assert error < 0.01 + + def test_distances(self): + """"ensure disances monotonically decay""" + + # parse the data + assert os.path.exists(self.test_tsv) + cities = read_city_list(self.test_tsv) + assert len(cities) == self.test_tsv_lines + city_locations = locations(cities) + assert len(city_locations) == self.test_tsv_lines + + # calculate all the neighbors + # WARNING: n*2 algorithm Too computationally intensive + # for full data set + for key, value in distance.calculate_distances(city_locations, + r=Rearth): + # for now, just make sure we can iterate over them + pass + + def test_neighbors(self): + + # parse the data + tsv = os.path.join(data, 'sample.tsv') + assert os.path.exists(tsv) + cities = read_city_list(tsv) + city_locations = locations(cities) + + # calculate the neighbors + neighbors = distance.calculate_neighbors(city_locations, + k=self.test_tsv_lines) + assert len(neighbors) == self.test_tsv_lines + + # ensure distance increases for each thing + for src, value in neighbors.items(): + distances = [i[-1] for i in value] + assert len(distances) == self.test_tsv_lines - 1 + for i in range(1, len(distances)): + assert distances[i] >= distances[i-1] + +if __name__ == '__main__': + unittest.main()