///|
pub(all) struct AliasPair {
left : String
right : String
correlation : Double
} derive(Debug, Eq)
///|
pub extend AliasPair with @debug.Debug::{to_repr}
///|
pub extend AliasPair with Eq::{equal, not_equal}
///|
pub(all) struct Diagnostics {
runs : Int32
terms : Int32
rank : Int32
residual_dof : Int32
estimable : Bool
zero_columns : Array[String]
exact_aliases : Array[AliasPair]
max_abs_correlation : Double
log_determinant : Double?
} derive(Debug, Eq)
///|
pub extend Diagnostics with @debug.Debug::{to_repr}
///|
pub extend Diagnostics with Eq::{equal, not_equal}
///|
pub fn diagnose(
p : Plan,
model : Array[Term],
tol~ : Double = 1.0e-10,
) -> Diagnostics raise DesignError {
tolerance(tol)
let a = design_matrix(p, model)
let (_, k) = matrix_shape(a)
let norms = Array::make(k, 0.0)
let scaled = [ for row in a => row.copy() ]
let zero_columns = []
for j in 0.. scale {
scale = row[j].abs()
}
}
if scale == 0.0 {
zero_columns.push(model[j].name)
} else {
for i in 0.. max_abs_correlation {
max_abs_correlation = absolute
}
if (1.0 - absolute).abs() <= tol {
exact_aliases.push({
left: model[i].name,
right: model[j].name,
correlation,
})
}
}
}
let rank = matrix_rank(a, tol~)
{
runs: a.length(),
terms: k,
rank,
residual_dof: a.length() - rank,
estimable: rank == k,
zero_columns,
exact_aliases,
max_abs_correlation,
log_determinant: log_determinant(information(a), tol~),
}
}
///|
pub fn alias_matrix(
fitted : Array[Array[Double]],
omitted : Array[Array[Double]],
tol~ : Double = 1.0e-10,
) -> Array[Array[Double]] raise DesignError {
let (n, p) = matrix_shape(fitted)
let (m, q) = matrix_shape(omitted)
if n != m {
raise Invalid("alias matrix run counts must match")
}
let result = zeros(p, q)
for j in 0.. row[j] ], tol~)
for i in 0..