From 283e9de30a716a5577a3205e87dbfeb24b6e47ba Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 27 Sep 2024 10:26:44 -0600
Subject: [PATCH] fix interpolate to handle any array

---
 libs/nshmp-lib/calc/maths.util.ts | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/libs/nshmp-lib/calc/maths.util.ts b/libs/nshmp-lib/calc/maths.util.ts
index bd67e9c..1f5aa0b 100644
--- a/libs/nshmp-lib/calc/maths.util.ts
+++ b/libs/nshmp-lib/calc/maths.util.ts
@@ -36,14 +36,12 @@ const interpolate = (xySequence: XySequence, value: number): number => {
   const xValues = xySequence.xs;
   const yValues = xySequence.ys;
 
-  const indexBelow = yValues.findIndex(y => {
-    return y < value;
-  });
-
-  const x0 = xValues[indexBelow - 1];
-  const x1 = xValues[indexBelow];
-  const y0 = yValues[indexBelow - 1];
-  const y1 = yValues[indexBelow];
+  const index = closestIndex(yValues, value);
+
+  const x0 = xValues[index - 1];
+  const x1 = xValues[index];
+  const y0 = yValues[index - 1];
+  const y1 = yValues[index];
   const x = interpolateValue(x0, x1, y0, y1, value);
   return isNaN(x) ? x : round(x, 6);
 };
@@ -90,6 +88,20 @@ const calculateResponseSpectrum = (
   return interpolate(xySequence, 1 / returnPeriod);
 };
 
+/**
+ * Return index of closest value.
+ *
+ * @param values Array of values
+ * @param value Value to find
+ */
+const closestIndex = (values: number[], value: number): number => {
+  const closestValue = values.reduce((prev, curr) =>
+    Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev
+  );
+
+  return values.findIndex(value => value === closestValue);
+};
+
 /**
  * Interpolate.
  *
-- 
GitLab