// Rolling Pearson correlation between two series.

///|
/// Number of leading NaN values produced by `correl` for the given period.
pub fn correl_lookback(period : Int32) -> Int32 {
  period - 1
}

///|
/// Pearson correlation coefficient of `data1` and `data2` over a rolling
/// window of `period` values: `sum(dx * dy) / sqrt(sum(dx^2) * sum(dy^2))`
/// with `dx`/`dy` the per-window deviations from the mean. Result ranges
/// from -1 to +1; a window containing NaN, or where either series is flat
/// (zero deviation sum), yields NaN.
pub fn correl(
  data1 : Array[Double],
  data2 : Array[Double],
  period : Int32,
) -> Array[Double] raise @base.TaError {
  @base.validate_series(data1, period)
  @base.validate_series(data2, period)
  if data1.length() != data2.length() {
    raise @base.MismatchedLength("data1 and data2 must have equal lengths")
  }
  let n = data1.length()
  // Five O(n) rolling sums feed the Pearson formula; NaN in any window
  // propagates to NaN through the sums.
  let sx = @base.rolling_sum(data1, period)
  let sy = @base.rolling_sum(data2, period)
  let sq1 : Array[Double] = []
  let sq2 : Array[Double] = []
  let prod : Array[Double] = []
  for i in 0..