Skip to main content

detect_blocks

Function detect_blocks 

Source
pub fn detect_blocks(
    dim: usize,
    irn: &[Index],
    jcn: &[Index],
) -> Option<Vec<i32>>
Expand description

Find a block-diagonal-plus-border partition in an assembled KKT, or None.

The border of an arrowhead KKT is its high-degree columns: every block touches them, so their degree grows with the block count while a block’s own columns keep a fixed degree. Peel the top-k by degree for geometrically growing k, and accept the first k that leaves a partition worth having.

“Worth having” is deliberately strict, because engaging this path on a matrix that merely can be cut buys nothing and costs a border solve:

  • the peeled columns must stand out — the smallest peeled degree at least DEGREE_GAP times the median degree. A chain has no such gap, and removing any interior column of a chain splits it, so without this a plain tridiagonal matrix “detects” as blocks;
  • at least MIN_BLOCKS blocks, and a border under 5% of the matrix;
  • no block holding half the interior.

A separating set found this way can be larger than necessary (the peel is geometric), so it is then shrunk: a peeled column whose neighbours all lie in one block belongs in that block.

Measured on a 210k-variable N-1 SCOPF this recovers the model’s own structure exactly — 259 shared columns, 65 blocks — without being told.

irn / jcn are the 1-based lower-triangle triplet.