///|
pub(all) struct BlockDensity {
row_start : Int32
column_start : Int32
row_stop : Int32
column_stop : Int32
recurrent : Int32
eligible : Int32
rate : Double?
} derive(Debug, Eq)
///|
pub extend BlockDensity with @debug.Debug::{to_repr}
///|
pub extend BlockDensity with Eq::{equal, not_equal}
///|
/// Block output is row-major; partial bottom/right blocks are included.
pub fn Recurrence::block_densities(
self : Recurrence,
rows_per_block : Int32,
cols_per_block : Int32,
) -> Result[Array[BlockDensity], RqaError] {
if rows_per_block < 1 ||
cols_per_block < 1 ||
rows_per_block > 4096 ||
cols_per_block > 4096 {
return Err(Invalid("block dimensions"))
}
let row_blocks = (self.height - 1) / rows_per_block + 1
let col_blocks = (self.width - 1) / cols_per_block + 1
let result : Array[BlockDensity] = []
for bi in 0.. Result[Recurrence, RqaError] {
if row < 0 ||
col < 0 ||
height < 1 ||
width < 1 ||
row >= self.height ||
col >= self.width ||
height > self.height - row ||
width > self.width - col {
return Err(Invalid("recurrence crop"))
}
Ok({
height,
width,
bits: Array::makei(height * width, fn(p) {
self.bits[(row + p / width) * self.width + col + p % width]
}),
mask: Array::makei(height * width, fn(p) {
self.mask[(row + p / width) * self.width + col + p % width]
}),
})
}