mirror of
https://github.com/cberner/raptorq.git
synced 2024-06-29 18:21:43 +00:00
Remove unneeded OctetMatrix methods
This commit is contained in:
parent
2937619983
commit
1f0a6639b4
39
src/base.rs
39
src/base.rs
@ -844,51 +844,12 @@ pub fn fused_inverse_mul_symbols(matrix: &OctetMatrix, symbols: &Vec<Symbol>, nu
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate rand;
|
||||
|
||||
use base::tests::rand::Rng;
|
||||
use symbol::Symbol;
|
||||
use matrix::OctetMatrix;
|
||||
use systematic_constants::extended_source_block_symbols;
|
||||
use constraint_matrix::generate_constraint_matrix;
|
||||
use base::fused_inverse_mul_symbols;
|
||||
use octet::Octet;
|
||||
use base::IntermediateSymbolDecoder;
|
||||
|
||||
fn identity(size: usize) -> OctetMatrix {
|
||||
let mut result = OctetMatrix::new(size, size);
|
||||
for i in 0..size {
|
||||
result.set(i, i, Octet::one());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn rand_symbol(symbol_size: usize) -> Symbol {
|
||||
let mut data: Vec<u8> = vec![0; symbol_size];
|
||||
for i in 0..symbol_size {
|
||||
data[i] = rand::thread_rng().gen();
|
||||
}
|
||||
Symbol::new(data)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inverse() {
|
||||
Octet::static_init();
|
||||
|
||||
for &source_symbols in [5, 20, 30, 50, 100].iter() {
|
||||
let symbols = extended_source_block_symbols(source_symbols);
|
||||
let a = generate_constraint_matrix(source_symbols, 0..symbols);
|
||||
let identity = identity(a.height());
|
||||
assert_eq!(identity, a.clone() * a.inverse().unwrap());
|
||||
|
||||
let mut rand_symbols = vec![];
|
||||
for _ in 0..a.width() {
|
||||
rand_symbols.push(rand_symbol(8));
|
||||
}
|
||||
assert_eq!(a.clone().inverse().unwrap().mul_symbols(&rand_symbols), fused_inverse_mul_symbols(&a, &rand_symbols, source_symbols).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn operations_per_symbol() {
|
||||
Octet::static_init();
|
||||
|
@ -42,17 +42,6 @@ fn main() {
|
||||
}
|
||||
println!("Original density for {}x{}: {} of {}", a.height(), a.width(), density, a.height() * a.width());
|
||||
|
||||
let inverse = a.inverse().unwrap();
|
||||
let mut density = 0;
|
||||
for i in 0..inverse.height() {
|
||||
for j in 0..inverse.width() {
|
||||
if inverse.get(i, j) != Octet::zero() {
|
||||
density += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("Inverse density for {}x{}: {} of {}", inverse.height(), inverse.width(), density, inverse.height() * inverse.width());
|
||||
|
||||
let symbols = vec![Symbol::zero(1); a.width()];
|
||||
let mut decoder = IntermediateSymbolDecoder::new(&a, &symbols, num_symbols);
|
||||
decoder.execute();
|
||||
|
149
src/matrix.rs
149
src/matrix.rs
@ -2,7 +2,6 @@ use std::ops::Mul;
|
||||
use octet::Octet;
|
||||
use octets::fused_addassign_mul_scalar;
|
||||
use octets::add_assign;
|
||||
use symbol::Symbol;
|
||||
use util::get_both_indices;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@ -25,28 +24,6 @@ impl OctetMatrix {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mul_symbols(&self, symbols: &Vec<Symbol>) -> Vec<Symbol> {
|
||||
assert_eq!(self.width, symbols.len());
|
||||
assert_ne!(0, symbols.len());
|
||||
let mut result: Vec<Symbol> = vec![];
|
||||
for i in 0..self.height {
|
||||
let mut symbol = Symbol::zero(symbols[0].len());
|
||||
for j in 0..self.width {
|
||||
if self.elements[i][j] == 0 {
|
||||
continue;
|
||||
}
|
||||
if self.elements[i][j] == 1 {
|
||||
symbol += &symbols[j];
|
||||
}
|
||||
else {
|
||||
symbol.fused_addassign_mul_scalar(&symbols[j], &Octet::new(self.elements[i][j]));
|
||||
}
|
||||
}
|
||||
result.push(symbol);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn set(&mut self, i: usize, j: usize, value: Octet) {
|
||||
self.elements[i][j] = value.byte();
|
||||
}
|
||||
@ -124,87 +101,6 @@ impl OctetMatrix {
|
||||
self.height = new_height;
|
||||
self.width = new_width;
|
||||
}
|
||||
|
||||
pub fn inverse(&self) -> Option<OctetMatrix> {
|
||||
// Calculate inverse using Gauss-Jordan elimination
|
||||
|
||||
// Only implemented for square matrices
|
||||
assert_eq!(self.height, self.width);
|
||||
|
||||
// Extend with identity on right side
|
||||
let mut intermediate = vec![];
|
||||
for i in 0..self.height {
|
||||
intermediate.push(vec![]);
|
||||
for j in 0..self.width {
|
||||
intermediate[i].push(Octet::new(self.elements[i][j]));
|
||||
}
|
||||
}
|
||||
for i in 0..self.height {
|
||||
for _ in 0..self.width {
|
||||
intermediate[i].push(Octet::zero());
|
||||
}
|
||||
intermediate[i][self.width + i] = Octet::one();
|
||||
}
|
||||
|
||||
// Convert to row echelon form
|
||||
for i in 0..self.width {
|
||||
// Swap a row with leading coefficient i into place
|
||||
for j in i..self.height {
|
||||
if intermediate[j][i] != Octet::zero() {
|
||||
intermediate.swap(i, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if intermediate[i][i] == Octet::zero() {
|
||||
// If all following rows are zero in this column, then matrix is singular
|
||||
return None
|
||||
}
|
||||
|
||||
// Scale leading coefficient to 1
|
||||
if intermediate[i][i] != Octet::one() {
|
||||
let element_inverse = Octet::one() / intermediate[i][i].clone();
|
||||
for j in i..(2*self.width) {
|
||||
intermediate[i][j] = intermediate[i][j].clone() * element_inverse.clone();
|
||||
}
|
||||
}
|
||||
|
||||
// Zero out all following elements in i'th column
|
||||
for j in (i + 1)..self.height {
|
||||
if intermediate[j][i] != Octet::zero() {
|
||||
let scalar = intermediate[j][i].clone();
|
||||
// Multiply and subtract i'th row from j'th row
|
||||
for k in i..(2*self.width) {
|
||||
intermediate[j][k] = intermediate[j][k].clone() - scalar.clone() * intermediate[i][k].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Perform backwards elimination
|
||||
for i in (0..self.width).rev() {
|
||||
// Zero out all preceding elements in i'th column
|
||||
for j in 0..i {
|
||||
if intermediate[j][i] != Octet::zero() {
|
||||
let scalar = intermediate[j][i].clone();
|
||||
// Multiply and subtract i'th row from j'th row
|
||||
for k in i..(2*self.width) {
|
||||
intermediate[j][k] = intermediate[j][k].clone() - scalar.clone() * intermediate[i][k].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return inverse
|
||||
let mut result = OctetMatrix::new(self.height, self.width);
|
||||
for row in 0..self.height {
|
||||
for column in 0..self.width {
|
||||
result.set(row, column, intermediate[row][column + self.width].clone());
|
||||
}
|
||||
}
|
||||
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for OctetMatrix {
|
||||
@ -237,7 +133,6 @@ mod tests {
|
||||
|
||||
use matrix::tests::rand::Rng;
|
||||
use matrix::OctetMatrix;
|
||||
use symbol::Symbol;
|
||||
use octet::Octet;
|
||||
|
||||
fn identity(size: usize) -> OctetMatrix {
|
||||
@ -259,48 +154,4 @@ mod tests {
|
||||
}
|
||||
assert_eq!(a.clone(), identity * a.clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mul_symbol() {
|
||||
let identity = identity(4);
|
||||
let mut symbols: Vec<Symbol> = vec![];
|
||||
for _ in 0..4 {
|
||||
let mut data = vec![];
|
||||
for _ in 0..3 {
|
||||
data.push(rand::thread_rng().gen());
|
||||
}
|
||||
symbols.push(Symbol::new(data));
|
||||
}
|
||||
assert_eq!(symbols.clone(), identity.mul_symbols(&symbols));
|
||||
|
||||
let mut a = OctetMatrix::new(4, 4);
|
||||
for i in 0..4 {
|
||||
for j in 0..4 {
|
||||
a.set(i, j, Octet::new(rand::thread_rng().gen()));
|
||||
}
|
||||
}
|
||||
// Statistically improbable that the random matrix, a, is the identity
|
||||
assert_ne!(symbols.clone(), a.mul_symbols(&symbols));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inverse() {
|
||||
Octet::static_init();
|
||||
let identity = identity(3);
|
||||
assert_eq!(identity, identity.clone() * identity.clone().inverse().unwrap());
|
||||
|
||||
let mut a = OctetMatrix::new(3, 3);
|
||||
a.set(0, 0, Octet::new(1));
|
||||
a.set(0, 1, Octet::new(2));
|
||||
a.set(0, 2, Octet::new(3));
|
||||
|
||||
a.set(1, 0, Octet::new(4));
|
||||
a.set(1, 1, Octet::new(5));
|
||||
a.set(1, 2, Octet::new(6));
|
||||
|
||||
a.set(2, 0, Octet::new(7));
|
||||
a.set(2, 1, Octet::new(8));
|
||||
a.set(2, 2, Octet::new(9));
|
||||
assert_eq!(identity, a.clone() * a.clone().inverse().unwrap());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user