Sparse binary linear algebra¶
Binary matrix¶
-
class
pyqec.sparse.
BinaryMatrix
¶ A sparse binary matrix with efficient row access.
- Parameters
num_columns (Int) – The number of columns in the matrix. Must be a non-negative integer.
rows (Seq[Seq[Int]]) – Each sequence in the outer sequence represents a row of the matrix. The inner sequences contain the positions (columns) of entries with value 1 in the corresponding row.
Example
>>> from pyqec.sparse import BinaryMatrix, to_dense >>> matrix = BinaryMatrix(3, [[0, 2], [1], [0, 1]]) >>> to_dense(matrix) array([[1, 0, 1], [0, 1, 0], [1, 1, 0]], dtype=int32)
- Raises
If the number of columns is negative or –
if a position in a row is out of bound. –
-
bitwise_xor
(other)¶ Returns the bitwise xor sum of self and other.
Example
>>> from pyqec.sparse import BinaryMatrix, BinaryVector >>> matrix1 = BinaryMatrix(4, [[0, 1, 2], [1, 2, 3], [1, 2]]) >>> matrix2 = BinaryMatrix(4, [[0, 1], [1, 2], [0, 1, 3]]) >>> matrix.bitwise_xor(matrix2) [2] [3] [0, 2, 3]
- Raises
ValueError – The shapes of the matrices are different.
-
dot_with_matrix
(matrix)¶ Returns the dot product between self and the given matrix.
Example
>>> from pyqec.sparse import BinaryMatrix, BinaryVector >>> matrix1 = BinaryMatrix(4, [[0, 1, 2], [1, 2, 3], [1, 2]]) >>> matrix2 = BinaryMatrix(3, [[0, 1], [1, 2], [0, 1], [1, 2]) >>> matrix.dot_with_matrix(matrix2) [1, 2] [0, 1] [0, 2]
- Raises
ValueError – Number of columns of self is not the same as the number of rows of the other matrix.
-
dot_with_vector
(vector)¶ Returns the dot product between self and the given vector.
Example
>>> from pyqec.sparse import BinaryMatrix, BinaryVector >>> matrix = BinaryMatrix(4, [[0, 1, 2], [1, 2, 3], [1, 2]]) >>> vector = BinaryVector(4, [1, 3]) >>> matrix.dot_with_vector(vector) [0, 2]
- Raises
ValueError – The vector length is not the same as the matrix number of columns.
-
echelon_form
()¶ Performs Gaussian elimination to return the matrix in echelon form.
Example
>>> from pyqec.sparse import BinaryMatrix >>> matrix = BinaryMatrix(4, [[0, 1, 2], [1, 3], [0, 2], [0, 2, 3]]) >>> matrix.echelon_form() [0, 1, 2] [1, 3] [3]
-
element
(row, column)¶ Returns the element at the given row and column.
- Raises
IndexError – The row or column is out of bound.
-
static
empty
()¶ An empty matrix.
Mostly useful as a placeholder since it allocate a minimal amount of memory.
Example
>>> from pyqec.sparse import BinaryMatrix >>> matrix = BinaryMatrix.empty() >>> matrix.num_rows() 0 >>> matrix.num_columns() 0
-
horizontal_concat_with
(other)¶ Returns the horizontal concatenation of self and other matrix.
If the matrices have a different number of rows, the smallest one is padded with zeros.
Example
>>> from pyqec.sparse import BinaryMatrix >>> matrix = BinaryMatrix(4, [[0, 1, 2], [1, 2, 3]]) >>> matrix.horizontal_concat_with(BinaryMatrix.identity(3)) [0, 1, 2, 4] [1, 2, 3, 5] [6]
-
static
identity
(length)¶ An identity matrix of the given length.
Example
>>> from pyqec.sparse import BinaryMatrix, to_dense >>> matrix = BinaryMatrix.identity(3) >>> to_dense(matrix) array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=int32)
-
is_empty
()¶ Checks if the matrix has shape (0, 0).
-
is_one_at
(row, column)¶ Check if the given element has value 1.
- Raises
IndexError – The row or column is out of bound.
-
is_zero
()¶ Checks if all the elements have value 0.
-
is_zero_at
(row, column)¶ Check if the given element has value 0.
- Raises
IndexError – The row or column is out of bound.
-
nullspace
()¶ Returns an orthogonal matrix where the rows generate the nullspace of self.
Example
>>> from pyqec.sparse import BinaryMatrix >>> matrix = BinaryMatrix(4, [[0, 1, 2], [1, 2, 3]]) >>> matrix.nullspace() [1, 2] [0, 1, 3]
-
num_columns
()¶ Returns the number of columns in the matrix.
-
num_ones
()¶ Returns the number of elements with value 1.
-
num_rows
()¶ Returns the number of rows in the matrix.
-
num_zeros
()¶ Returns the number of elements with value 0.
-
rank
()¶ Computes the number of linearly independent rows (or columns) of the matrix.
Example
>>> from pyqec.sparse import BinaryMatrix >>> matrix = BinaryMatrix(4, [[0, 1, 2], [1, 3], [0, 2], [0, 2, 3]]) >>> matrix.rank() 3
-
row
(row)¶ Returns the given row as a BinaryVector.
- Raises
IndexError – The row is out of bound.
-
rows
()¶ >>> from pyqec.sparse import BinaryMatrix, to_dense >>> matrix = BinaryMatrix(3, [[0, 2], [1], [0, 1]]) >>> for row in matrix.rows(): ... print(row) [0, 2] [1] [0, 1]
-
shape
()¶ Returns a tuple of the numbers of rows and columns.
-
transposed
()¶ Returns the transpose of the matrix.
Example
>>> from pyqec.sparse import BinaryMatrix >>> matrix = BinaryMatrix(3, [[0, 2], [1], [0, 1]]) >>> matrix.transpose() [0, 2] [1, 2] [0]
-
vertical_concat_with
(other)¶ Returns the vertical concatenation of self and other matrix.
If the matrices have a different number of columns, the smallest one is padded with zeros.
Example
>>> from pyqec.sparse import BinaryMatrix >>> matrix = BinaryMatrix(4, [[0, 1, 2], [1, 2, 3]]) >>> matrix.vertical_concat_with(BinaryMatrix.identity(3)) [0, 1, 2] [1, 2, 3] [0] [1] [2]
-
static
zeros
(num_rows, num_columns)¶ A matrix filled with zeros.
Example
>>> from pyqec.sparse import BinaryMatrix, to_dense >>> matrix = BinaryMatrix.zeros(2, 3) >>> to_dense(matrix) array([[0, 0, 0], [0, 0, 0]], dtype=int32)
Binary vector¶
-
class
pyqec.sparse.
BinaryVector
¶ A sparse binary vector.
- Parameters
length (Int) – The number of elements in the vector. Must be a non-negative integer.
positions (Seq[Int]) – The positions of entries with value 1.
Example
>>> from pyqec.sparse import BinaryVector, to_dense >>> vector = BinaryVector(3, [0, 2]) >>> to_dense(vector) array([1, 0, 1], dtype=int32)
- Raises
ValueError – If the length is negative or if a position is out of bound.
-
bitwise_xor
(other)¶ Computes the bitwise xor sum of two vectors.
Example
>>> from pyqec.sparse import BinaryVector >>> left = BinaryVector(5, [0, 2, 4]) >>> right = BinaryVector(5, [1, 2, 3]) >>> left.bitwise_xor(right) [0, 1, 3, 4]
- Raises
ValueError – If the vectors have different lengths.
-
concat
(other)¶ Concatenates self with other.
Example
>>> from pyqec.sparse import BinaryVector >>> left = BinaryVector(5, [0, 2, 4]) >>> right = BinaryVector(4, [1, 3]) >>> left.concat(right) [0, 2, 4, 6, 8]
-
dot_with_matrix
(matrix)¶ Computes the dot product between self and a matrix.
This assume that the vector is in row shape and compute v * M.
Example
>>> from pyqec.sparse import BinaryVector, PyBinaryMatrix >>> vector = BinaryVector(3, [0, 2]) >>> matrix = PyBinaryMatrix(4, [[0, 3]], [0, 1, 2], [1, 3]]) >>> vector.dot_with_matrix(matrix) [0, 1]
- Raises
ValueError – If the vector length is the not the same as the matrix number of rows.
-
dot_with_vector
(other)¶ Computes the dot product between two vectors.
Example
>>> from pyqec.sparse import BinaryVector >>> left = BinaryVector(5, [0, 2, 4]) >>> right = BinaryVector(5, [1, 3]) >>> left.dot_with_vector(right) 0
- Raises
ValueError – If the vectors have different length.
-
element
(position)¶ Returns the value of the element at the given position.
- Raises
IndexError – The position is out of bound.
-
static
empty
()¶ Constructs a vector of length 0.
This is useful as a placeholder since it allocates a minimal amount of memory.
-
is_empty
()¶ Checks if the length of the vector is 0.
-
is_one_at
(position)¶ Checks if the element at the given position is one.
- Raises
IndexError – The position is out of bound.
-
is_zero
()¶ Checks if all elements are 0.
-
is_zero_at
(position)¶ Checks if the element at the given position is zero.
- Raises
IndexError – The position is out of bound.
-
len
()¶ Returns the number of elements in the vector.
-
non_trivial_position
(index)¶ Index the given value in the list of non-trivial positions.
Example
>>> from pyqec.sparse import BinaryVector >>> vector = BinaryVector(5, [0, 2, 4]) >>> vector.non_trivial_position(0) 0 >>> vector.non_trivial_position(1) 2 >>> vector.non_trivial_position(2) 4
- Raises
IndexError – The index is greater or equal to the weight.
-
weight
()¶ Returns the number of elements with value 1.
-
static
zeros
(length)¶ Constructs a vector of the given length filled with zeros.
Conversion to Numpy¶
-
pyqec.sparse.
to_dense
(sparse_bin_array)¶ Converts a sparse matrix or vector to a dense numpy representation.
- Parameters
sparse_bin_array (Union[BinaryMatrix, BinaryVector]) – The array to convert.
Example
>>> from pyqec.sparse import BinaryMatrix, to_dense >>> to_dense(BinaryMatrix.identity(3)) array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=int32)
General operations¶
-
pyqec.sparse.
dot
(left, right)¶ Computes the dot product between two sparse binary arrays.
- Parameters
left (Union[BinaryMatrix, BinaryVector]) – The left hand side of the product.
right (Union[BinaryMatrix, BinaryVector]) – The right hand side of the product.
Examples
>>> from pyqec.sparse import BinaryMatrix, BinaryVector, dot >>> matrix1 = BinaryMatrix(3, [[0, 1], [1, 2]]) >>> matrix2 = BinaryMatrix(2, [[0], [1], [0, 1]]) >>> dot(matrix1, matrix2) [0, 1] [0] >>> vector = BinaryVector(3, [0, 2]) >>> dot(matrix1, vector) [0, 1] >>> dot(vector, matrix2) [1]