///|
pub fn alr(x : Array[Double], reference : Int) -> Array[Double] raise CodaError {
positive(x)
if reference < 0 || reference >= x.length() {
raise Shape("ALR reference outside composition")
}
let base = @math.ln(x[reference])
let out = []
for i, v in x {
if i != reference {
out.push(@math.ln(v) - base)
}
}
out
}
///|
pub fn alr_inverse(
z : Array[Double],
reference : Int,
) -> Array[Double] raise CodaError {
vector_size(z.length() + 1)
real_vector(z)
if reference < 0 || reference > z.length() {
raise Shape("ALR reference outside reconstructed composition")
}
let logits = []
let mut index = 0
for i in 0..<(z.length() + 1) {
if i == reference {
logits.push(0.0)
} else {
logits.push(z[index])
index += 1
}
}
clr_inverse(logits)
}