///|
/// Generic batch operations shared by offline and online training loops.
pub fn array_sum(values : Array[Double]) -> Double {
let mut sum = 0.0
for value in values {
sum = sum + value
}
sum
}
///|
pub fn array_mean(values : Array[Double]) -> Double {
if values.length() == 0 {
0.0
} else {
array_sum(values) / values.length().to_double()
}
}
///|
pub fn array_min(values : Array[Double]) -> Double {
if values.length() == 0 {
0.0
} else {
let mut result = values[0]
for value in values {
if value < result {
result = value
}
}
result
}
}
///|
pub fn array_max(values : Array[Double]) -> Double {
if values.length() == 0 {
0.0
} else {
let mut result = values[0]
for value in values {
if value > result {
result = value
}
}
result
}
}
///|
pub fn array_l1_distance(left : Array[Double], right : Array[Double]) -> Double {
let mut result = 0.0
let length = if left.length() < right.length() {
left.length()
} else {
right.length()
}
let mut i = 0
while i < length {
let distance = left[i] - right[i]
result = result + (if distance < 0.0 { -distance } else { distance })
i = i + 1
}
result
}
///|
pub fn array_l2_squared_distance(
left : Array[Double],
right : Array[Double],
) -> Double {
let mut result = 0.0
let length = if left.length() < right.length() {
left.length()
} else {
right.length()
}
let mut i = 0
while i < length {
let distance = left[i] - right[i]
result = result + distance * distance
i = i + 1
}
result
}
///|
pub fn array_scale_add(
left : Array[Double],
scale : Double,
right : Array[Double],
) -> Array[Double] {
let result : Array[Double] = []
let length = if left.length() < right.length() {
left.length()
} else {
right.length()
}
let mut i = 0
while i < length {
result.push(left[i] * scale + right[i])
i = i + 1
}
result
}
///|
pub fn array_weighted_average(
values : Array[Double],
weights : Array[Double],
) -> Double {
let length = if values.length() < weights.length() {
values.length()
} else {
weights.length()
}
let mut numerator = 0.0
let mut denominator = 0.0
let mut i = 0
while i < length {
numerator = numerator + values[i] * weights[i]
denominator = denominator + weights[i]
i = i + 1
}
if denominator == 0.0 {
0.0
} else {
numerator / denominator
}
}
///|
pub fn array_take(values : Array[Double], count : Int) -> Array[Double] {
let result : Array[Double] = []
let length = if count < values.length() { count } else { values.length() }
let mut i = 0
while i < length {
if i >= 0 {
result.push(values[i])
}
i = i + 1
}
result
}
///|
pub fn array_drop(values : Array[Double], count : Int) -> Array[Double] {
let result : Array[Double] = []
let start = if count < 0 {
0
} else if count > values.length() {
values.length()
} else {
count
}
let mut i = start
while i < values.length() {
result.push(values[i])
i = i + 1
}
result
}
///|
pub fn array_pad(
values : Array[Double],
length : Int,
fill : Double,
) -> Array[Double] {
let result : Array[Double] = []
for value in values {
if result.length() < length {
result.push(value)
}
}
while result.length() < length {
result.push(fill)
}
result
}
///|
pub fn array_mask(values : Array[Double], mask : Array[Bool]) -> Array[Double] {
let result : Array[Double] = []
let length = if values.length() < mask.length() {
values.length()
} else {
mask.length()
}
let mut i = 0
while i < length {
if mask[i] {
result.push(values[i])
}
i = i + 1
}
result
}
///|
pub fn array_cumulative(values : Array[Double]) -> Array[Double] {
let result : Array[Double] = []
let mut running = 0.0
for value in values {
running = running + value
result.push(running)
}
result
}
///|
pub fn array_difference(values : Array[Double]) -> Array[Double] {
let result : Array[Double] = []
if values.length() == 0 {
return result
}
result.push(values[0])
let mut i = 1
while i < values.length() {
result.push(values[i] - values[i - 1])
i = i + 1
}
result
}