///|
pub(all) struct PrometheeResult {
ranking : Ranking
preference_matrix : Array[Array[Double]]
positive_flow : Array[Double]
negative_flow : Array[Double]
} derive(@debug.Debug)
///|
fn preference_specs(
m : DecisionMatrix,
specs : Array[Preference],
) -> Unit raise ChoiceError {
if specs.length() != m.criteria.length() {
raise Invalid("preference specification count mismatch")
}
for spec in specs {
valid_preference(spec)
}
}
///|
/// Thresholds are in raw criterion units, not normalized units.
pub fn promethee(
m : DecisionMatrix,
weights : Array[Double],
preferences : Array[Preference],
tolerance~ : Double = 1.0e-10,
) -> PrometheeResult raise ChoiceError {
let w = matrix_weights(m, weights)
preference_specs(m, preferences)
let (n, p) = m.shape()
let pi = zeros(n, n)
for i in 0.. 1 {
let denominator = (n - 1).to_double()
for i in 0.. pi[k][i] ]) / denominator
net[i] = positive_flow[i] - negative_flow[i]
}
}
{
ranking: rank_scores(m.names, net, tolerance~),
preference_matrix: pi,
positive_flow,
negative_flow,
}
}
///|
pub extend PrometheeResult with @debug.Debug::{to_repr}