///|
/// Sliding-window delay embedding: row i is [x_i, x_(i+lag), ...].
/// No normalization or resampling is applied implicitly.
pub fn delay_embed(
series : Array[Double],
dimension~ : Int,
lag~ : Int,
stride? : Int = 1,
) -> Array[Array[Double]] raise TopologyError {
if dimension < 1 ||
dimension > 32 ||
lag < 1 ||
lag > 10000 ||
stride < 1 ||
stride > 10000 {
raise TopologyError(
"embedding requires dimension 1..32 and lag/stride 1..10000",
)
}
if series.length() > 10000 {
raise TopologyError("at most 10000 time samples are supported")
}
for value in series {
if !finite(value) || value.abs() > 1.0e100 {
raise TopologyError("time samples must be finite and bounded")
}
}
let span = (dimension - 1) * lag
if span >= series.length() {
raise TopologyError("series too short for requested embedding")
}
let count = (series.length() - 1 - span) / stride + 1
if count > 128 {
raise TopologyError("embedding exceeds 128 points; increase stride")
}
Array::makei(count, fn(i) {
Array::makei(dimension, fn(k) { series[i * stride + k * lag] })
})
}