///|
/// Columns are UInt64 bit vectors over GF(2), low bits are row indices.
pub fn Matroid::binary(
rows : Int32,
columns : Array[UInt64],
) -> Matroid raise MatroidError {
check_size(columns.length())
if rows < 0 || rows > 64 {
raise InvalidInput("binary rows outside 0..64")
}
for c in columns {
if rows < 64 && c >> rows != 0UL {
raise InvalidInput("binary column exceeds row count")
}
}
let owned = columns.copy()
{
size: owned.length(),
model: "binary",
evaluate: xs => {
let pivots = Array::make(rows, 0UL)
let mut rank = 0
for e in xs {
let mut vector = owned[e]
for row = rows - 1; row >= 0; row = row - 1 {
if (vector & (1UL << row)) != 0UL {
if pivots[row] == 0UL {
pivots[row] = vector
rank = rank + 1
break
} else {
vector = vector ^ pivots[row]
}
}
}
}
rank
},
}
}