// 1D/2D Interpolation algorithms for spectrum grids and fiber profiles.

///|
/// 1D Linear interpolation: evaluate y(x_target) from sorted grid x and y
pub fn interp1d_linear(
  x : Array[Double],
  y : Array[Double],
  x_target : Double,
) -> Double {
  let n = x.length()
  if n == 0 {
    return 0.0
  }
  if n == 1 || x_target <= x[0] {
    return y[0]
  }
  if x_target >= x[n - 1] {
    return y[n - 1]
  }

  // Binary search for interval
  let mut low = 0
  let mut high = n - 1
  while high - low > 1 {
    let mid = (low + high) / 2
    if x[mid] <= x_target {
      low = mid
    } else {
      high = mid
    }
  }

  let frac = (x_target - x[low]) / (x[high] - x[low])
  y[low] + frac * (y[high] - y[low])
}

///|
/// Resample array y defined on grid x onto a new target grid x_new
pub fn resample_grid(
  x_old : Array[Double],
  y_old : Array[Double],
  x_new : Array[Double],
) -> Array[Double] {
  let n_new = x_new.length()
  let y_new = Array::make(n_new, 0.0)
  for i = 0; i < n_new; i = i + 1 {
    y_new[i] = interp1d_linear(x_old, y_old, x_new[i])
  }
  y_new
}