///|
/// Dense elimination is deliberately bounded separately from sparse decoding.
pub struct Encoder {
priv code : ParityCheck
priv reduced : Array[Array[Int32]]
priv pivots : Array[Int32]
priv free : Array[Int32]
} derive(Debug)
///|
pub fn Encoder::new(code : ParityCheck) -> Encoder raise CodeError {
if code.n > 2048 || code.checks() > 2048 || code.n * code.checks() > 1048576 {
raise ResourceLimit(
"GF(2) elimination: at most 2048 axes and 1048576 cells",
)
}
let reduced = Array::makei(code.checks(), fn(c) {
let row = Array::make(code.n, 0)
for v in code.rows[c] {
row[v] = 1
}
row
})
let pivots : Array[Int32] = []
let mut work = 0L
let mut pivot_row = 0
for col in 0.. 50000000L {
raise ResourceLimit("encoder elimination work")
}
for k in col.. Int32 {
self.pivots.length()
}
///|
pub fn Encoder::dimension(self : Encoder) -> Int32 {
self.free.length()
}
///|
pub fn Encoder::information_positions(self : Encoder) -> Array[Int32] {
self.free.copy()
}
///|
pub fn Encoder::parity_positions(self : Encoder) -> Array[Int32] {
self.pivots.copy()
}
///|
pub fn Encoder::rate(self : Encoder) -> Double {
self.dimension().to_double() / self.code.n.to_double()
}
///|
/// Free columns carry information; pivot columns are solved from RREF.
pub fn Encoder::encode(
self : Encoder,
information : Array[Int32],
) -> Array[Int32] raise CodeError {
ensure_bits(information, self.dimension())
let word = Array::make(self.code.n, 0)
for i, v in self.free {
word[v] = information[i]
}
for r, pivot in self.pivots {
let mut value = 0
for v in self.free {
value = value ^ (self.reduced[r][v] & word[v])
}
word[pivot] = value
}
word
}
///|
/// Extraction rejects a non-codeword rather than silently accepting corruption.
pub fn Encoder::extract(
self : Encoder,
word : Array[Int32],
) -> Array[Int32] raise CodeError {
if !self.code.is_codeword(word) {
raise Inconsistent("nonzero syndrome")
}
self.free.map(fn(v) { word[v] })
}
///|
pub fn Encoder::generator(
self : Encoder,
) -> Array[Array[Int32]] raise CodeError {
if self.dimension() * self.code.n > 1048576 {
raise ResourceLimit("generator cells")
}
let result : Array[Array[Int32]] = []
for i in 0.. Array[Int32] raise CodeError {
ensure_bits(syndrome, self.code.checks())
let rows = Array::makei(self.code.checks(), fn(c) {
let row = Array::make(self.code.n + 1, 0)
for v in self.code.rows[c] {
row[v] = 1
}
row[self.code.n] = syndrome[c]
row
})
let mut work = 0L
let mut rank = 0
let pivots : Array[Int32] = []
for col in 0.. 50000000L {
raise ResourceLimit("syndrome elimination work")
}
for k in col..<(self.code.n + 1) {
rows[r][k] = rows[r][k] ^ rows[rank][k]
}
}
}
pivots.push(col)
rank += 1
if rank == rows.length() {
break
}
}
for r in rank..