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::indexed::IndexedNetwork;
10use crate::matrix::triplet::CooBuilder;
11use crate::{Error, Result};
12
13/// Build the `n × n` 0/1 adjacency matrix.
14pub fn build_adjacency(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.bus_index(br.from).ok_or(Error::UnknownBus {
19            bus_id: br.from,
20            element_index: idx,
21        })?;
22        let j = case.bus_index(br.to).ok_or(Error::UnknownBus {
23            bus_id: br.to,
24            element_index: idx,
25        })?;
26        if i != j {
27            edges.insert(if i < j { (i, j) } else { (j, i) });
28        }
29    }
30
31    let mut a = CooBuilder::with_capacity(n, 2 * edges.len());
32    for (i, j) in edges {
33        a.add(i, j, 1.0);
34        a.add(j, i, 1.0);
35    }
36    Ok(a.finish_csr())
37}