Separate binary and octet matrix classes

This commit is contained in:
Christopher Berner 2020-01-11 15:06:57 -08:00
parent dbb0a7f7d3
commit 5d57d3751e
11 changed files with 150 additions and 87 deletions

@ -2,13 +2,13 @@ use raptorq::generate_constraint_matrix;
use raptorq::IntermediateSymbolDecoder;
use raptorq::Octet;
use raptorq::Symbol;
use raptorq::{extended_source_block_symbols, OctetMatrix, SparseOctetMatrix};
use raptorq::{extended_source_block_symbols, BinaryMatrix, SparseBinaryMatrix};
fn main() {
for elements in [10, 100, 1000, 10000, 40000, 56403].iter() {
let num_symbols = extended_source_block_symbols(*elements);
let indices: Vec<u32> = (0..num_symbols).collect();
let (a, hdpc) = generate_constraint_matrix::<SparseOctetMatrix>(num_symbols, &indices);
let (a, hdpc) = generate_constraint_matrix::<SparseBinaryMatrix>(num_symbols, &indices);
let mut density = 0;
let mut row_density = vec![0; a.height()];
for i in 0..a.height() {

@ -1,7 +1,7 @@
use crate::base::intermediate_tuple;
use crate::matrix::DenseOctetMatrix;
use crate::matrix::OctetMatrix;
use crate::matrix::BinaryMatrix;
use crate::octet::Octet;
use crate::octet_matrix::DenseOctetMatrix;
use crate::octets::{add_assign, fused_addassign_mul_scalar};
use crate::rng::rand;
use crate::systematic_constants::extended_source_block_symbols;
@ -129,7 +129,7 @@ fn generate_hdpc_rows(Kprime: usize, S: usize, H: usize) -> DenseOctetMatrix {
// Returns the HDPC rows separately. These logically replace the rows S..(S + H) of the constraint
// matrix. They are returned separately to allow easier optimizations.
#[allow(non_snake_case)]
pub fn generate_constraint_matrix<T: OctetMatrix>(
pub fn generate_constraint_matrix<T: BinaryMatrix>(
source_block_symbols: u32,
encoded_symbol_indices: &[u32],
) -> (T, DenseOctetMatrix) {

@ -5,9 +5,10 @@ use crate::base::ObjectTransmissionInformation;
use crate::constraint_matrix::enc_indices;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::encoder::SPARSE_MATRIX_THRESHOLD;
use crate::matrix::{DenseOctetMatrix, OctetMatrix};
use crate::matrix::{BinaryMatrix, DenseBinaryMatrix};
use crate::octet_matrix::DenseOctetMatrix;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::sparse_matrix::SparseOctetMatrix;
use crate::sparse_matrix::SparseBinaryMatrix;
use crate::symbol::Symbol;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_ldpc_symbols;
@ -146,7 +147,7 @@ impl SourceBlockDecoder {
fn try_pi_decode(
&mut self,
constraint_matrix: impl OctetMatrix,
constraint_matrix: impl BinaryMatrix,
hdpc_rows: DenseOctetMatrix,
symbols: Vec<Symbol>,
) -> Option<Vec<u8>> {
@ -253,13 +254,13 @@ impl SourceBlockDecoder {
}
if extended_source_block_symbols(self.source_block_symbols) >= self.sparse_threshold {
let (constraint_matrix, hdpc) = generate_constraint_matrix::<SparseOctetMatrix>(
let (constraint_matrix, hdpc) = generate_constraint_matrix::<SparseBinaryMatrix>(
self.source_block_symbols,
&encoded_indices,
);
return self.try_pi_decode(constraint_matrix, hdpc, d);
} else {
let (constraint_matrix, hdpc) = generate_constraint_matrix::<DenseOctetMatrix>(
let (constraint_matrix, hdpc) = generate_constraint_matrix::<DenseBinaryMatrix>(
self.source_block_symbols,
&encoded_indices,
);

@ -3,9 +3,9 @@ use crate::base::partition;
use crate::base::EncodingPacket;
use crate::base::PayloadId;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::matrix::DenseOctetMatrix;
use crate::matrix::DenseBinaryMatrix;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::sparse_matrix::SparseOctetMatrix;
use crate::sparse_matrix::SparseBinaryMatrix;
use crate::symbol::Symbol;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_hdpc_symbols;
@ -190,11 +190,11 @@ fn gen_intermediate_symbols(
let indices: Vec<u32> = (0..extended_source_symbols).collect();
if extended_source_symbols >= sparse_threshold {
let (A, hdpc) =
generate_constraint_matrix::<SparseOctetMatrix>(extended_source_symbols, &indices);
generate_constraint_matrix::<SparseBinaryMatrix>(extended_source_symbols, &indices);
return fused_inverse_mul_symbols(A, hdpc, D, extended_source_symbols).unwrap();
} else {
let (A, hdpc) =
generate_constraint_matrix::<DenseOctetMatrix>(extended_source_symbols, &indices);
generate_constraint_matrix::<DenseBinaryMatrix>(extended_source_symbols, &indices);
return fused_inverse_mul_symbols(A, hdpc, D, extended_source_symbols).unwrap();
}
}

@ -1,5 +1,5 @@
use crate::octet::Octet;
use crate::sparse_vec::{SparseOctetVec, SparseValuelessVec};
use crate::sparse_vec::{SparseBinaryVec, SparseValuelessVec};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
@ -158,7 +158,7 @@ pub struct OctetIter<'a> {
end_col: usize,
dense_elements: Option<&'a Vec<u8>>,
dense_index: usize,
sparse_elements: Option<&'a SparseOctetVec>,
sparse_elements: Option<&'a SparseBinaryVec>,
sparse_index: usize,
sparse_physical_col_to_logical: Option<&'a [usize]>,
}
@ -167,7 +167,7 @@ impl<'a> OctetIter<'a> {
pub fn new_sparse(
start_col: usize,
end_col: usize,
sparse_elements: &'a SparseOctetVec,
sparse_elements: &'a SparseBinaryVec,
sparse_physical_col_to_logical: &'a [usize],
) -> OctetIter<'a> {
OctetIter {

@ -8,6 +8,7 @@ mod encoder;
mod iterators;
mod matrix;
mod octet;
mod octet_matrix;
mod octets;
mod pi_solver;
mod rng;
@ -28,15 +29,15 @@ pub use crate::encoder::SourceBlockEncoder;
#[cfg(feature = "benchmarking")]
pub use crate::constraint_matrix::generate_constraint_matrix;
#[cfg(feature = "benchmarking")]
pub use crate::matrix::DenseOctetMatrix;
pub use crate::matrix::BinaryMatrix;
#[cfg(feature = "benchmarking")]
pub use crate::matrix::OctetMatrix;
pub use crate::matrix::DenseBinaryMatrix;
#[cfg(feature = "benchmarking")]
pub use crate::octet::Octet;
#[cfg(feature = "benchmarking")]
pub use crate::pi_solver::IntermediateSymbolDecoder;
#[cfg(feature = "benchmarking")]
pub use crate::sparse_matrix::SparseOctetMatrix;
pub use crate::sparse_matrix::SparseBinaryMatrix;
#[cfg(feature = "benchmarking")]
pub use crate::symbol::Symbol;
#[cfg(feature = "benchmarking")]

@ -5,7 +5,7 @@ use crate::octets::{add_assign, count_ones_and_nonzeros, mulassign_scalar};
use crate::util::get_both_indices;
use serde::{Deserialize, Serialize};
pub trait OctetMatrix: Clone {
pub trait BinaryMatrix: Clone {
fn new(height: usize, width: usize, trailing_dense_column_hint: usize) -> Self;
fn set(&mut self, i: usize, j: usize, value: Octet);
@ -58,36 +58,19 @@ pub trait OctetMatrix: Clone {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
pub struct DenseOctetMatrix {
pub struct DenseBinaryMatrix {
height: usize,
width: usize,
elements: Vec<Vec<u8>>,
}
impl DenseOctetMatrix {
pub fn fma_sub_row(&mut self, row: usize, start_col: usize, scalar: &Octet, other: &[u8]) {
if *scalar == Octet::one() {
add_assign(
&mut self.elements[row][start_col..(start_col + other.len())],
other,
);
} else {
fused_addassign_mul_scalar(
&mut self.elements[row][start_col..(start_col + other.len())],
other,
scalar,
);
}
}
}
impl OctetMatrix for DenseOctetMatrix {
fn new(height: usize, width: usize, _: usize) -> DenseOctetMatrix {
impl BinaryMatrix for DenseBinaryMatrix {
fn new(height: usize, width: usize, _: usize) -> DenseBinaryMatrix {
let mut elements: Vec<Vec<u8>> = Vec::with_capacity(height);
for _ in 0..height {
elements.push(vec![0; width]);
}
DenseOctetMatrix {
DenseBinaryMatrix {
height,
width,
elements,
@ -159,7 +142,7 @@ impl OctetMatrix for DenseOctetMatrix {
// other must be a rows x rows matrix
// sets self[0..rows][..] = X * self[0..rows][..]
fn mul_assign_submatrix(&mut self, other: &DenseOctetMatrix, rows: usize) {
fn mul_assign_submatrix(&mut self, other: &DenseBinaryMatrix, rows: usize) {
assert_eq!(rows, other.height());
assert_eq!(rows, other.width());
assert!(rows <= self.height());
@ -210,29 +193,29 @@ impl OctetMatrix for DenseOctetMatrix {
mod tests {
use rand::Rng;
use crate::matrix::{DenseOctetMatrix, OctetMatrix};
use crate::matrix::{BinaryMatrix, DenseBinaryMatrix};
use crate::octet::Octet;
use crate::sparse_matrix::SparseOctetMatrix;
use crate::sparse_matrix::SparseBinaryMatrix;
fn dense_identity(size: usize) -> DenseOctetMatrix {
let mut result = DenseOctetMatrix::new(size, size, 0);
fn dense_identity(size: usize) -> DenseBinaryMatrix {
let mut result = DenseBinaryMatrix::new(size, size, 0);
for i in 0..size {
result.set(i, i, Octet::one());
}
result
}
fn sparse_identity(size: usize) -> SparseOctetMatrix {
let mut result = SparseOctetMatrix::new(size, size, 0);
fn sparse_identity(size: usize) -> SparseBinaryMatrix {
let mut result = SparseBinaryMatrix::new(size, size, 0);
for i in 0..size {
result.set(i, i, Octet::one());
}
result
}
fn rand_dense_and_sparse(size: usize) -> (DenseOctetMatrix, SparseOctetMatrix) {
let mut dense = DenseOctetMatrix::new(size, size, 0);
let mut sparse = SparseOctetMatrix::new(size, size, 1);
fn rand_dense_and_sparse(size: usize) -> (DenseBinaryMatrix, SparseBinaryMatrix) {
let mut dense = DenseBinaryMatrix::new(size, size, 0);
let mut sparse = SparseBinaryMatrix::new(size, size, 1);
// Generate 50% filled random matrices
for _ in 0..(size * size / 2) {
let i = rand::thread_rng().gen_range(0, size);
@ -245,7 +228,7 @@ mod tests {
return (dense, sparse);
}
fn assert_matrices_eq<T: OctetMatrix, U: OctetMatrix>(matrix1: &T, matrix2: &U) {
fn assert_matrices_eq<T: BinaryMatrix, U: BinaryMatrix>(matrix1: &T, matrix2: &U) {
assert_eq!(matrix1.height(), matrix2.height());
assert_eq!(matrix1.width(), matrix2.width());
for i in 0..matrix1.height() {

78
src/octet_matrix.rs Normal file

@ -0,0 +1,78 @@
use crate::octet::Octet;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::{add_assign, mulassign_scalar};
use crate::util::get_both_indices;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
pub struct DenseOctetMatrix {
height: usize,
width: usize,
elements: Vec<Vec<u8>>,
}
impl DenseOctetMatrix {
pub fn new(height: usize, width: usize, _: usize) -> DenseOctetMatrix {
let mut elements: Vec<Vec<u8>> = Vec::with_capacity(height);
for _ in 0..height {
elements.push(vec![0; width]);
}
DenseOctetMatrix {
height,
width,
elements,
}
}
pub fn fma_sub_row(&mut self, row: usize, start_col: usize, scalar: &Octet, other: &[u8]) {
if *scalar == Octet::one() {
add_assign(
&mut self.elements[row][start_col..(start_col + other.len())],
other,
);
} else {
fused_addassign_mul_scalar(
&mut self.elements[row][start_col..(start_col + other.len())],
other,
scalar,
);
}
}
pub fn set(&mut self, i: usize, j: usize, value: Octet) {
self.elements[i][j] = value.byte();
}
pub fn height(&self) -> usize {
self.height
}
pub fn mul_assign_row(&mut self, row: usize, value: &Octet) {
mulassign_scalar(&mut self.elements[row], value);
}
pub fn get(&self, i: usize, j: usize) -> Octet {
Octet::new(self.elements[i][j])
}
pub fn swap_rows(&mut self, i: usize, j: usize) {
self.elements.swap(i, j);
}
pub fn swap_columns(&mut self, i: usize, j: usize, start_row_hint: usize) {
for row in start_row_hint..self.elements.len() {
self.elements[row].swap(i, j);
}
}
pub fn fma_rows(&mut self, dest: usize, multiplicand: usize, scalar: &Octet) {
assert_ne!(dest, multiplicand);
let (dest_row, temp_row) = get_both_indices(&mut self.elements, dest, multiplicand);
if *scalar == Octet::one() {
add_assign(dest_row, temp_row);
} else {
fused_addassign_mul_scalar(dest_row, temp_row, scalar);
}
}
}

@ -1,8 +1,8 @@
use crate::arraymap::UsizeArrayMap;
use crate::arraymap::{ArrayMap, BoolArrayMap};
use crate::matrix::DenseOctetMatrix;
use crate::matrix::OctetMatrix;
use crate::matrix::BinaryMatrix;
use crate::octet::Octet;
use crate::octet_matrix::DenseOctetMatrix;
use crate::symbol::Symbol;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_intermediate_symbols;
@ -45,7 +45,7 @@ struct FirstPhaseRowSelectionStats {
impl FirstPhaseRowSelectionStats {
#[inline(never)]
#[allow(non_snake_case)]
pub fn new<T: OctetMatrix>(matrix: &T, end_col: usize) -> FirstPhaseRowSelectionStats {
pub fn new<T: BinaryMatrix>(matrix: &T, end_col: usize) -> FirstPhaseRowSelectionStats {
let mut result = FirstPhaseRowSelectionStats {
original_degree: UsizeArrayMap::new(0, 0),
non_zeros_per_row: UsizeArrayMap::new(0, matrix.height()),
@ -87,7 +87,7 @@ impl FirstPhaseRowSelectionStats {
}
// Recompute all stored statistics for the given row
pub fn recompute_row<T: OctetMatrix>(&mut self, row: usize, matrix: &T) {
pub fn recompute_row<T: BinaryMatrix>(&mut self, row: usize, matrix: &T) {
let (ones, non_zero) = matrix.count_ones_and_nonzeros(row, self.start_col, self.end_col);
self.rows_with_single_nonzero.retain(|x| *x != row);
if non_zero == 1 {
@ -119,7 +119,7 @@ impl FirstPhaseRowSelectionStats {
// Set the valid columns, and recalculate statistics
// All values in column "start_col - 1" in rows start_row..end_row must be zero
#[inline(never)]
pub fn resize<T: OctetMatrix>(
pub fn resize<T: BinaryMatrix>(
&mut self,
start_row: usize,
end_row: usize,
@ -162,7 +162,7 @@ impl FirstPhaseRowSelectionStats {
}
#[inline(never)]
fn first_phase_graph_substep_build_adjacency<T: OctetMatrix>(
fn first_phase_graph_substep_build_adjacency<T: BinaryMatrix>(
&mut self,
rows_with_two_ones: &[usize],
matrix: &T,
@ -209,7 +209,7 @@ impl FirstPhaseRowSelectionStats {
}
#[inline(never)]
fn first_phase_graph_substep<T: OctetMatrix>(
fn first_phase_graph_substep<T: BinaryMatrix>(
&mut self,
start_row: usize,
end_row: usize,
@ -306,7 +306,7 @@ impl FirstPhaseRowSelectionStats {
// Helper method for decoder phase 1
// selects from [start_row, end_row) reading [start_col, end_col)
// Returns (the chosen row, and "r" number of non-zero values the row has)
pub fn first_phase_selection<T: OctetMatrix>(
pub fn first_phase_selection<T: BinaryMatrix>(
&mut self,
start_row: usize,
end_row: usize,
@ -359,7 +359,7 @@ impl FirstPhaseRowSelectionStats {
// See section 5.4.2.1
#[allow(non_snake_case)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct IntermediateSymbolDecoder<T: OctetMatrix> {
pub struct IntermediateSymbolDecoder<T: BinaryMatrix> {
A: T,
// If present, these are treated as replacing the last rows of A
// Errata 3 guarantees that these do not need to be included in X
@ -381,7 +381,7 @@ pub struct IntermediateSymbolDecoder<T: OctetMatrix> {
}
#[allow(non_snake_case)]
impl<T: OctetMatrix> IntermediateSymbolDecoder<T> {
impl<T: BinaryMatrix> IntermediateSymbolDecoder<T> {
pub fn new(
matrix: T,
hdpc_rows: DenseOctetMatrix,
@ -1150,7 +1150,7 @@ impl<T: OctetMatrix> IntermediateSymbolDecoder<T> {
// Fused implementation for self.inverse().mul_symbols(symbols)
// See section 5.4.2.1
pub fn fused_inverse_mul_symbols<T: OctetMatrix>(
pub fn fused_inverse_mul_symbols<T: BinaryMatrix>(
matrix: T,
hdpc_rows: DenseOctetMatrix,
symbols: Vec<Symbol>,
@ -1163,8 +1163,8 @@ pub fn fused_inverse_mul_symbols<T: OctetMatrix>(
mod tests {
use super::IntermediateSymbolDecoder;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::matrix::DenseOctetMatrix;
use crate::matrix::OctetMatrix;
use crate::matrix::BinaryMatrix;
use crate::matrix::DenseBinaryMatrix;
use crate::symbol::Symbol;
use crate::systematic_constants::{
extended_source_block_symbols, num_ldpc_symbols, num_lt_symbols,
@ -1178,7 +1178,7 @@ mod tests {
{
let num_symbols = extended_source_block_symbols(elements);
let indices: Vec<u32> = (0..num_symbols).collect();
let (a, hdpc) = generate_constraint_matrix::<DenseOctetMatrix>(num_symbols, &indices);
let (a, hdpc) = generate_constraint_matrix::<DenseBinaryMatrix>(num_symbols, &indices);
let symbols = vec![Symbol::zero(1usize); a.width()];
let mut decoder = IntermediateSymbolDecoder::new(a, hdpc, symbols, num_symbols);
decoder.execute();

@ -1,9 +1,9 @@
use crate::iterators::{BorrowedKeyIter, OctetIter};
use crate::matrix::OctetMatrix;
use crate::matrix::BinaryMatrix;
use crate::octet::Octet;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::{add_assign, mulassign_scalar};
use crate::sparse_vec::{SparseOctetVec, SparseValuelessVec};
use crate::sparse_vec::{SparseBinaryVec, SparseValuelessVec};
use crate::util::get_both_indices;
use serde::{Deserialize, Serialize};
use std::cmp::min;
@ -16,10 +16,10 @@ use std::cmp::min;
// | | columns |
// |---------------------------------------|
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
pub struct SparseOctetMatrix {
pub struct SparseBinaryMatrix {
height: usize,
width: usize,
sparse_elements: Vec<SparseOctetVec>,
sparse_elements: Vec<SparseBinaryVec>,
// Note these are stored with the right-most element first in the vec.
// That is, for a matrix with width 10 and num_dense 3, the last three will be stored in these
// Vecs, and will be in the order: [9, 8, 7]
@ -37,7 +37,7 @@ pub struct SparseOctetMatrix {
num_dense_columns: usize,
}
impl SparseOctetMatrix {
impl SparseBinaryMatrix {
#[cfg(debug_assertions)]
fn verify(&self) {
if self.column_index_disabled {
@ -53,10 +53,10 @@ impl SparseOctetMatrix {
}
}
impl OctetMatrix for SparseOctetMatrix {
fn new(height: usize, width: usize, trailing_dense_column_hint: usize) -> SparseOctetMatrix {
impl BinaryMatrix for SparseBinaryMatrix {
fn new(height: usize, width: usize, trailing_dense_column_hint: usize) -> SparseBinaryMatrix {
let mut col_mapping = vec![0; width];
let elements = vec![SparseOctetVec::with_capacity(10); height];
let elements = vec![SparseBinaryVec::with_capacity(10); height];
let mut row_mapping = vec![0; height];
#[allow(clippy::needless_range_loop)]
for i in 0..height {
@ -70,7 +70,7 @@ impl OctetMatrix for SparseOctetMatrix {
for i in 0..width {
col_mapping[i] = i;
}
SparseOctetMatrix {
SparseBinaryMatrix {
height,
width,
sparse_elements: elements,
@ -248,7 +248,7 @@ impl OctetMatrix for SparseOctetMatrix {
// other must be a rows x rows matrix
// sets self[0..rows][..] = X * self[0..rows][..]
fn mul_assign_submatrix(&mut self, other: &SparseOctetMatrix, rows: usize) {
fn mul_assign_submatrix(&mut self, other: &SparseBinaryMatrix, rows: usize) {
assert_eq!(rows, other.height());
assert_eq!(rows, other.width());
assert!(rows <= self.height());
@ -256,7 +256,7 @@ impl OctetMatrix for SparseOctetMatrix {
unimplemented!();
}
// Note: rows are logically indexed
let mut temp_sparse = vec![SparseOctetVec::with_capacity(10); rows];
let mut temp_sparse = vec![SparseBinaryVec::with_capacity(10); rows];
let mut temp_dense = vec![vec![0; self.num_dense_columns]; rows];
for row in 0..rows {
for (i, scalar) in other.get_row_iter(row, 0, rows) {

@ -3,14 +3,14 @@ use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
pub struct SparseOctetVec {
pub struct SparseBinaryVec {
// Kept sorted by the usize (key)
elements: Vec<(usize, Octet)>,
}
impl SparseOctetVec {
pub fn with_capacity(capacity: usize) -> SparseOctetVec {
SparseOctetVec {
impl SparseBinaryVec {
pub fn with_capacity(capacity: usize) -> SparseBinaryVec {
SparseBinaryVec {
elements: Vec::with_capacity(capacity),
}
}
@ -30,7 +30,7 @@ impl SparseOctetVec {
}
// Returns a vector of new column indices that this row contains
pub fn fma(&mut self, other: &SparseOctetVec, scalar: &Octet) -> Vec<usize> {
pub fn fma(&mut self, other: &SparseBinaryVec, scalar: &Octet) -> Vec<usize> {
// Fast path for a single value that's being eliminated
// TODO: Probably wouldn't need this if we implemented "Furthermore, the row operations
// required for the HDPC rows may be performed for all such rows in one
@ -198,13 +198,13 @@ mod tests {
use rand::Rng;
use crate::octet::Octet;
use crate::sparse_vec::SparseOctetVec;
use crate::sparse_vec::SparseBinaryVec;
#[test]
fn sparse_vec() {
let size = 100;
let mut dense = vec![0; size];
let mut sparse = SparseOctetVec::with_capacity(size);
let mut sparse = SparseBinaryVec::with_capacity(size);
for _ in 0..size {
let i = rand::thread_rng().gen_range(0, size);
let value = rand::thread_rng().gen();
@ -219,7 +219,7 @@ mod tests {
#[test]
fn sparse_vec_fma() {
let mut dense1 = vec![Octet::zero(); 8];
let mut sparse1 = SparseOctetVec::with_capacity(8);
let mut sparse1 = SparseBinaryVec::with_capacity(8);
for i in 0..4 {
let value = rand::thread_rng().gen();
dense1[i * 2] = Octet::new(value);
@ -237,7 +237,7 @@ mod tests {
}
let mut dense2 = vec![Octet::zero(); 8];
let mut sparse2 = SparseOctetVec::with_capacity(8);
let mut sparse2 = SparseBinaryVec::with_capacity(8);
for i in 0..4 {
let value = rand::thread_rng().gen();
dense2[i] = Octet::new(value);