Skip to main content

powerio_matrix/matrix/
adjacency.rs

1//! Bus adjacency matrix: `1` where an in-service branch joins two distinct
2//! buses, `0` otherwise. Symmetric, zero diagonal, parallel branches
3//! collapsed to a single `1`.
4
5use std::collections::HashSet;
6
7use sprs::CsMat;
8
9use crate::Result;
10use crate::indexed::IndexedNetwork;
11use crate::matrix::triplet::CooBuilder;
12
13/// Calculate the `n × n` 0/1 adjacency matrix.
14pub fn calc_adjacency_matrix(case: &IndexedNetwork) -> Result<CsMat<f64>> {
15    let n = case.n();
16    let mut edges: HashSet<(usize, usize)> = HashSet::new();
17    for (idx, br) in case.in_service_branches() {
18        let i = case
19            .bus_index(br.from)
20            .ok_or(powerio_tx::Error::UnknownBus {
21                bus_id: br.from,
22                element_index: idx,
23            })?;
24        let j = case.bus_index(br.to).ok_or(powerio_tx::Error::UnknownBus {
25            bus_id: br.to,
26            element_index: idx,
27        })?;
28        if i != j {
29            edges.insert(if i < j { (i, j) } else { (j, i) });
30        }
31    }
32
33    let mut a = CooBuilder::with_capacity(n, 2 * edges.len());
34    for (i, j) in edges {
35        a.add(i, j, 1.0);
36        a.add(j, i, 1.0);
37    }
38    Ok(a.finish_csr())
39}