///|
/// MaxPool1d over input shape (channels, length).
/// Flat layout: x[c * length + l]
pub fn max_pool1d(
x : Array[Double],
channels : Int,
length : Int,
kernel_size : Int,
stride : Int,
) -> Array[Double] {
let out_length = (length - kernel_size) / stride + 1
let output = Array::make(channels * out_length, 0.0)
for c = 0; c < channels; c = c + 1 {
for pos = 0; pos < out_length; pos = pos + 1 {
let start = pos * stride
let mut max_v = x[c * length + start]
for k = 1; k < kernel_size; k = k + 1 {
let v = x[c * length + start + k]
if v > max_v {
max_v = v
}
}
output[c * out_length + pos] = max_v
}
}
output
}
///|
/// AvgPool1d over input shape (channels, length).
/// Flat layout: x[c * length + l]
pub fn avg_pool1d(
x : Array[Double],
channels : Int,
length : Int,
kernel_size : Int,
stride : Int,
) -> Array[Double] {
let out_length = (length - kernel_size) / stride + 1
let output = Array::make(channels * out_length, 0.0)
for c = 0; c < channels; c = c + 1 {
for pos = 0; pos < out_length; pos = pos + 1 {
let start = pos * stride
let mut sum = 0.0
for k = 0; k < kernel_size; k = k + 1 {
sum = sum + x[c * length + start + k]
}
output[c * out_length + pos] = sum / kernel_size.to_double()
}
}
output
}