From b839325740f9487bf30c74b649993c7e400a2aaa Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 18 Apr 2016 19:47:22 -0400 Subject: [PATCH] LUCENE-7185: fix buggy worst-case error and add test for absurd distances --- .../org/apache/lucene/util/SloppyMath.java | 2 +- .../apache/lucene/util/TestSloppyMath.java | 23 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java b/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java index 7be9be1c4ad..0bfca5e6f5e 100644 --- a/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java +++ b/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java @@ -37,7 +37,7 @@ public class SloppyMath { * specified in decimal degrees (latitude/longitude). This works correctly * even if the dateline is between the two points. *

- * Error is at most 2E-1 (20cm) from the actual haversine distance, but is typically + * Error is at most 4E-1 (40cm) from the actual haversine distance, but is typically * much smaller for reasonable distances: around 1E-5 (0.01mm) for distances less than * 1000km. * diff --git a/lucene/core/src/test/org/apache/lucene/util/TestSloppyMath.java b/lucene/core/src/test/org/apache/lucene/util/TestSloppyMath.java index 6a2eb86b2b6..488f00e1a4b 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestSloppyMath.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestSloppyMath.java @@ -33,7 +33,7 @@ public class TestSloppyMath extends LuceneTestCase { // accuracy for asin() static double ASIN_DELTA = 1E-7; // accuracy for haversinMeters() - static double HAVERSIN_DELTA = 2E-1; + static double HAVERSIN_DELTA = 38E-2; // accuracy for haversinMeters() for "reasonable" distances (< 1000km) static double REASONABLE_HAVERSIN_DELTA = 1E-5; @@ -161,11 +161,28 @@ public class TestSloppyMath extends LuceneTestCase { double lat2 = GeoTestUtil.nextLatitude(); double lon2 = GeoTestUtil.nextLongitude(); - double expected = haversinMeters(lat1, lon1, lat2, lon2); - double actual = slowHaversin(lat1, lon1, lat2, lon2); + double expected = slowHaversin(lat1, lon1, lat2, lon2); + double actual = haversinMeters(lat1, lon1, lat2, lon2); assertEquals(expected, actual, HAVERSIN_DELTA); } } + + /** + * Step across the whole world to find huge absolute errors. + * Don't rely on random number generator to pick these massive distances. */ + public void testAcrossWholeWorldSteps() { + for (int lat1 = -90; lat1 <= 90; lat1 += 10) { + for (int lon1 = -180; lon1 <= 180; lon1 += 10) { + for (int lat2 = -90; lat2 <= 90; lat2 += 10) { + for (int lon2 = -180; lon2 <= 180; lon2 += 10) { + double expected = slowHaversin(lat1, lon1, lat2, lon2); + double actual = haversinMeters(lat1, lon1, lat2, lon2); + assertEquals(expected, actual, HAVERSIN_DELTA); + } + } + } + } + } public void testAgainstSlowVersionReasonable() { for (int i = 0; i < 100_000; i++) {