///|
pub struct Covariance2 {
xx : Double
xy : Double
yy : Double
} derive(Debug, Eq)
///|
pub fn covariance_of(dimensions : Array[ProjectedDimension]) -> Covariance2 {
if dimensions.length() == 0 {
abort("cannot calculate covariance for an empty projected chain")
}
let mut xx = 0.0
let mut xy = 0.0
let mut yy = 0.0
for dimension in dimensions {
let variance = dimension.tolerance * dimension.tolerance
xx += dimension.vector.x * dimension.vector.x * variance
xy += dimension.vector.x * dimension.vector.y * variance
yy += dimension.vector.y * dimension.vector.y * variance
}
{ xx, xy, yy }
}
///|
pub fn Covariance2::variance_along(
self : Covariance2,
direction : Vector2,
) -> Double {
let xx = self.xx * direction.x * direction.x
let xy = 2.0 * self.xy * direction.x * direction.y
let yy = self.yy * direction.y * direction.y
xx + xy + yy
}
///|
pub fn projected_standard_deviation(
covariance : Covariance2,
direction : Vector2,
) -> Double {
let variance = covariance.variance_along(direction)
if variance < 0.0 {
0.0
} else {
variance.sqrt()
}
}