// One square root of a covariance, used wherever a filter has to displace points
// by a covariance. A covariance that is only semi-definite has no Cholesky
// factor, so the fallback is the diagonal, which always exists.
///|
/// A lower triangular square root of `covariance`, or its diagonal when the
/// matrix is not positive definite.
fn matrix_sqrt(covariance : @linear.Mat) -> @linear.Mat {
let n = covariance.rows
let jitter = @linear.Mat::identity(n).scale(1.0e-12)
@linear.cholesky(covariance.add(jitter)) catch {
_ => {
let diagonal = @linear.Vec::zeros(n)
for i in 0.. 0.0 { value.sqrt() } else { 0.0 })
}
@linear.Mat::diagonal(diagonal)
}
}
}