///|
pub fn DenseMatrix::determinant(self : DenseMatrix) -> Double {
if self.rows() != self.columns() {
abort("determinant: matrix must be square")
}
if self.rows() == 0 {
return 1.0
}
let values = self.values.copy()
let mut result = 1.0
let mut sign = 1.0
for pivot in 0..
values[row * self.columns() + pivot].abs() {
row = candidate
}
}
let pivot_value = values[row * self.columns() + pivot]
if pivot_value.abs() < 0.000000000001 {
return 0.0
}
if row != pivot {
sign = 0.0 - sign
for column in 0.. Array[Double] {
let size = self.rows().min(self.columns())
let result = []
for index in 0.. Double {
self.values.fold(init=0.0, (total, value) => total + value * value).sqrt()
}
///|
pub fn DenseMatrix::hadamard(
self : DenseMatrix,
other : DenseMatrix,
) -> DenseMatrix {
if self.rows() != other.rows() || self.columns() != other.columns() {
abort("hadamard: dimensions must match")
}
DenseMatrix::new(
self.rows(),
self.columns(),
self.values.mapi(fn(index, value) { value * other.values[index] }),
)
}
///|
pub fn outer_product(
left : Array[Double],
right : Array[Double],
) -> DenseMatrix {
let result = Array::make(left.length() * right.length(), 0.0)
for row in 0.. DenseMatrix {
if samples.length() < 2 || samples[0].length() == 0 {
abort("covariance_matrix: observations are required")
}
let dimension = samples[0].length()
let center = Array::make(dimension, 0.0)
for sample in samples {
if sample.length() != dimension {
abort("covariance_matrix: dimensions must match")
}
for index in 0.. Array[Double] {
if diagonal.length() != right.length() {
abort("solve_diagonal: dimensions must match")
}
right.mapi(fn(index, value) {
if diagonal[index] == 0.0 {
abort("solve_diagonal: singular matrix")
}
value / diagonal[index]
})
}
///|
pub fn matrix_vector_distance(
left : Array[Double],
right : Array[Double],
) -> Double {
if left.length() != right.length() {
abort("matrix_vector_distance: dimensions must match")
}
left
.foldi(init=0.0, fn(index, total, value) {
let error = value - right[index]
total + error * error
})
.sqrt()
}