///|
pub fn huber_location(
data : Array[Double],
max_iter? : Int = 50,
tol? : Double = 0.0001,
) -> Double {
if data.length() == 0 {
return 0.0
}
let mut mu = median(data)
let m = mad(data)
if m == 0.0 {
return mu
}
let k = 1.345 * m
for iter = 0; iter < max_iter; iter = iter + 1 {
let mut sum_w = 0.0
let mut sum_wx = 0.0
for v in data {
let mut res = v - mu
if res < 0.0 {
res = -res
}
let w = if res <= k { 1.0 } else { k / res }
sum_w += w
sum_wx += w * v
}
let new_mu = sum_wx / sum_w
let mut diff = new_mu - mu
if diff < 0.0 {
diff = -diff
}
if diff < tol {
return new_mu
}
mu = new_mu
}
mu
}