///|
/// Moving-average smoothing for an already sampled scalar signal.
pub fn moving_average(values : Array[Double], window : Int) -> Array[Double] {
  if values.length() == 0 || window <= 1 {
    return values.copy()
  }
  let result : Array[Double] = []
  for index in 0.. Array[Double] {
  let result : Array[Double] = []
  if values.length() == 0 {
    return result
  }
  if step <= 0.0 {
    return Array::make(values.length(), 0.0)
  }
  result.push(0.0)
  for i in 1.. Array[Double] {
  if values.length() == 0 {
    return []
  }
  let mut minimum = values[0]
  let mut maximum = values[0]
  for value in values {
    if value < minimum {
      minimum = value
    }
    if value > maximum {
      maximum = value
    }
  }
  let span = maximum - minimum
  if span == 0.0 {
    Array::make(values.length(), 0.0)
  } else {
    values.map(fn(value) { (value - minimum) / span })
  }
}

///|
/// Clamp a signal to a monotone non-decreasing envelope.
pub fn monotone_envelope(values : Array[Double]) -> Array[Double] {
  if values.length() == 0 {
    return []
  }
  let result : Array[Double] = [values[0]]
  for i in 1.. Int? {
  if values.length() == 0 {
    None
  } else {
    let mut index = 0
    for i in 1.. values[index] {
        index = i
      }
    }
    Some(index)
  }
}

///|
pub fn rms(values : Array[Double]) -> Double {
  if values.length() == 0 {
    0.0
  } else {
    let mut total = 0.0
    for value in values {
      total = total + value * value
    }
    (total / values.length().to_double()).sqrt()
  }
}