From eacbe29c82affaa0c3e1d5d17fcbd6203451c659 Mon Sep 17 00:00:00 2001 From: Trevor Gerhardt Date: Mon, 17 Feb 2025 17:40:08 +0100 Subject: [PATCH] Add an invariants check As requested in https://github.com/conveyal/r5/pull/935#issuecomment-2015058140 --- .../r5/analyst/TemporalDensityResult.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/com/conveyal/r5/analyst/TemporalDensityResult.java b/src/main/java/com/conveyal/r5/analyst/TemporalDensityResult.java index c8db6e220..fc75a9f1b 100644 --- a/src/main/java/com/conveyal/r5/analyst/TemporalDensityResult.java +++ b/src/main/java/com/conveyal/r5/analyst/TemporalDensityResult.java @@ -63,6 +63,28 @@ public void recordOneTarget (int target, int[] travelTimePercentilesSeconds) { } } + /** + * As travel time cutoff increases, accessibility should increase. + * As percentile increases, travel time should decrease, and accessibility should decrease. + * If one of these invariants does not hold, there is something wrong with the calculations. + */ + private void checkInvariants() { + int nPointSets = opportunitiesPerMinute.length; + int nPercentiles = opportunitiesPerMinute.length > 0 ? opportunitiesPerMinute[0].length : 0; + for (int d = 0; d < nPointSets; d++) { + for (int p = 0; p < nPercentiles; p++) { + for (int m = 0; m < 120; m++) { + if (m > 0 && opportunitiesPerMinute[d][p][m] < opportunitiesPerMinute[d][p][m - 1]) { + throw new AssertionError("Increasing travel time decreased accessibility."); + } + if (p > 0 && opportunitiesPerMinute[d][p][m] > opportunitiesPerMinute[d][p - 1][m]) { + throw new AssertionError("Increasing percentile increased accessibility."); + } + } + } + } + } + /** * Writes dual accessibility values (in minutes) to our standard access grid format. The value returned (for * an origin) is the number of minutes required to reach a threshold number of opportunities (specified by @@ -70,6 +92,8 @@ public void recordOneTarget (int target, int[] travelTimePercentilesSeconds) { * travel time. If the threshold cannot be reached in less than 120 minutes, returns 0. */ public int[][][] calculateDualAccessibilityGrid() { + checkInvariants(); + int nPointSets = opportunitiesPerMinute.length; int nPercentiles = opportunitiesPerMinute.length > 0 ? opportunitiesPerMinute[0].length : 0; int nThresholds = dualAccessibilityThresholds.length; @@ -88,6 +112,7 @@ public int[][][] calculateDualAccessibilityGrid() { } } } + // TODO check invariants return dualAccessibilityGrid; } }