#[repr(transparent)]pub struct Subspace {
matrix: Matrix,
}Expand description
A subspace of a vector space.
In general, a method is defined on the Subspace if it is a meaningful property of the
subspace itself. Otherwise, users can dereference the subspace to gain read-only access to the
underlying matrix object.
§Fields
matrix- A matrix in reduced row echelon, whose number of columns is the dimension of the ambient space and each row is a basis vector of the subspace.
Fields§
§matrix: MatrixImplementations§
Source§impl Subspace
impl Subspace
pub fn new(p: ValidPrime, dim: usize) -> Self
Sourcepub fn from_matrix(matrix: Matrix) -> Self
pub fn from_matrix(matrix: Matrix) -> Self
Create a new subspace from a matrix. The matrix does not have to be in row echelon form.
Sourcepub fn update_then_row_reduce<T, F: FnOnce(&mut Matrix) -> T>(
&mut self,
f: F,
) -> T
pub fn update_then_row_reduce<T, F: FnOnce(&mut Matrix) -> T>( &mut self, f: F, ) -> T
Run a closure on the matrix and then ensure it is row-reduced.
pub fn from_bytes(p: ValidPrime, data: &mut impl Read) -> Result<Self>
pub fn to_bytes(&self, buffer: &mut impl Write) -> Result<()>
pub fn entire_space(p: ValidPrime, dim: usize) -> Self
Sourcepub fn add_vector(&mut self, row: FpSlice<'_>) -> usize
pub fn add_vector(&mut self, row: FpSlice<'_>) -> usize
This adds a vector to the subspace. This function assumes that the last row of the matrix is zero, i.e. the dimension of the current subspace is strictly less than the number of rows. This can be achieved by setting the number of rows to be the dimension plus one when creating the subspace.
§Returns
The new dimension of the subspace
Sourcepub fn add_vectors(
&mut self,
rows: impl for<'a> FnMut(FpSliceMut<'a>) -> Option<()>,
)
pub fn add_vectors( &mut self, rows: impl for<'a> FnMut(FpSliceMut<'a>) -> Option<()>, )
This adds some rows to the subspace
§Arguments
rows: A function that writes the row to be added to the given FpSliceMut. This returnsNoneif it runs out of rows,Some(())otherwise.
pub fn add_basis_elements(&mut self, rows: impl Iterator<Item = usize>)
Sourcepub fn reduce(&self, vector: FpSliceMut<'_>)
pub fn reduce(&self, vector: FpSliceMut<'_>)
Projects a vector to a complement of the subspace. The complement is the set of vectors
that have a 0 in every column where there is a pivot in matrix
pub fn contains(&self, vector: FpSlice<'_>) -> bool
pub fn contains_space(&self, other: &Self) -> bool
pub fn dimension(&self) -> usize
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether the subspace is empty. This assumes the subspace is row reduced.
pub fn ambient_dimension(&self) -> usize
Sourcepub fn set_to_zero(&mut self)
pub fn set_to_zero(&mut self)
Sets the subspace to be the zero subspace.
Sourcepub fn set_to_entire(&mut self)
pub fn set_to_entire(&mut self)
Sets the subspace to be the entire subspace.
pub fn iter(&self) -> impl Iterator<Item = FpSlice<'_>>
Sourcepub fn iter_all_vectors(&self) -> impl Iterator<Item = FpVector> + '_
pub fn iter_all_vectors(&self) -> impl Iterator<Item = FpVector> + '_
Iterate over all vectors in the subspace.
§Example
let subspace = Subspace::from_matrix(Matrix::from_vec(
ValidPrime::new(3),
&[vec![1, 0, 0], vec![0, 1, 2]],
));
let mut all_vectors = subspace.iter_all_vectors().map(|v| (&v).into());
assert_eq!(all_vectors.next(), Some(vec![0, 0, 0]));
assert_eq!(all_vectors.next(), Some(vec![0, 1, 2]));
assert_eq!(all_vectors.next(), Some(vec![0, 2, 1]));
assert_eq!(all_vectors.next(), Some(vec![1, 0, 0]));
assert_eq!(all_vectors.next(), Some(vec![1, 1, 2]));
assert_eq!(all_vectors.next(), Some(vec![1, 2, 1]));
assert_eq!(all_vectors.next(), Some(vec![2, 0, 0]));
assert_eq!(all_vectors.next(), Some(vec![2, 1, 2]));
assert_eq!(all_vectors.next(), Some(vec![2, 2, 1]));
assert_eq!(all_vectors.next(), None);pub fn sum(&self, other: &Self) -> Self
Methods from Deref<Target = Matrix>§
pub fn to_bytes(&self, data: &mut impl Write) -> Result<()>
pub fn prime(&self) -> ValidPrime
Sourcepub(crate) fn physical_rows(&self) -> usize
pub(crate) fn physical_rows(&self) -> usize
Gets the physical number of rows allocated (for BLAS operations).
pub(crate) fn stride(&self) -> usize
pub(crate) fn data(&self) -> &[u64]
pub fn pivots(&self) -> &[isize]
Sourcepub fn to_vec(&self) -> Vec<Vec<u32>>
pub fn to_vec(&self) -> Vec<Vec<u32>>
let matrix_vec = vec![vec![1, 0], vec![0, 1]];
assert_eq!(Matrix::from_vec(TWO, &matrix_vec).to_vec(), matrix_vec);pub fn is_zero(&self) -> bool
pub fn row(&self, row: usize) -> FpSlice<'_>
pub fn iter(&self) -> impl Iterator<Item = FpSlice<'_>>
Sourcepub fn find_first_row_in_block(&self, first_column: usize) -> usize
pub fn find_first_row_in_block(&self, first_column: usize) -> usize
Given a row reduced matrix, find the first row whose pivot column is after (or at)
first_column.
Sourcepub fn compute_quasi_inverse(
&self,
last_target_col: usize,
first_source_col: usize,
) -> QuasiInverse
pub fn compute_quasi_inverse( &self, last_target_col: usize, first_source_col: usize, ) -> QuasiInverse
Computes the quasi-inverse of a matrix given a rref of [A|0|I], where 0 is the zero padding as usual.
§Arguments
last_target_col- the last column of Afirst_source_col- the first column of I
§Example
let p = ValidPrime::new(3);
let input = [
vec![1, 2, 1, 1, 0],
vec![1, 0, 2, 1, 1],
vec![2, 2, 0, 2, 1],
];
let (padded_cols, mut m) = Matrix::augmented_from_vec(p, &input);
m.row_reduce();
let qi = m.compute_quasi_inverse(input[0].len(), padded_cols);
let preimage = [vec![0, 1, 0], vec![0, 2, 2]];
assert_eq!(qi.preimage(), &Matrix::from_vec(p, &preimage));Sourcepub fn compute_image(
&self,
last_target_col: usize,
first_source_col: usize,
) -> Subspace
pub fn compute_image( &self, last_target_col: usize, first_source_col: usize, ) -> Subspace
Computes the quasi-inverse of a matrix given a rref of [A|0|I], where 0 is the zero padding as usual.
§Arguments
last_target_col- the last column of Afirst_source_col- the first column of I
§Example
let p = ValidPrime::new(3);
let input = [
vec![1, 2, 1, 1, 0],
vec![1, 0, 2, 1, 1],
vec![2, 2, 0, 2, 1],
];
let (padded_cols, mut m) = Matrix::augmented_from_vec(p, &input);
m.row_reduce();
let computed_image = m.compute_image(input[0].len(), padded_cols);
let image = [vec![1, 0, 2, 1, 1], vec![0, 1, 1, 0, 1]];
assert_eq!(*computed_image, Matrix::from_vec(p, &image));
assert_eq!(computed_image.pivots(), &vec![0, 1, -1, -1, -1]);Sourcepub fn compute_kernel(&self, first_source_column: usize) -> Subspace
pub fn compute_kernel(&self, first_source_column: usize) -> Subspace
Computes the kernel from an augmented matrix in rref. To compute the kernel of a matrix A, produce an augmented matrix of the form
[A | I]An important thing to note is that the number of columns of A should be a multiple of the
number of entries per limb in an FpVector, and this is often achieved by padding columns
with 0. The padded length can be obtained from FpVector::padded_dimension.
After this matrix is set up, perform row reduction with Matrix::row_reduce, and then
apply compute_kernel.
§Arguments
column_to_pivot_row- This is the list of pivotsrow_reducegave you.first_source_column- The column where theIpart of the augmented matrix starts.
§Example
let p = ValidPrime::new(3);
let input = [
vec![1, 2, 1, 1, 0],
vec![1, 0, 2, 1, 1],
vec![2, 2, 0, 2, 1],
];
let (padded_cols, mut m) = Matrix::augmented_from_vec(p, &input);
m.row_reduce();
let ker = m.compute_kernel(padded_cols);
let mut target = vec![0; 3];
assert_eq!(ker.row(0).iter().collect::<Vec<u32>>(), vec![1, 1, 2]);Sourcepub fn apply(&self, result: FpSliceMut<'_>, coeff: u32, input: FpSlice<'_>)
pub fn apply(&self, result: FpSliceMut<'_>, coeff: u32, input: FpSlice<'_>)
Applies a matrix to a vector.
§Example
let p = ValidPrime::new(7);
let input = [vec![1, 3, 6], vec![0, 3, 4]];
let m = Matrix::from_vec(p, &input);
let v = FpVector::from_slice(p, &vec![3, 1]);
let mut result = FpVector::new(p, 3);
let desired_result = FpVector::from_slice(p, &vec![3, 5, 1]);
m.apply(result.as_slice_mut(), 1, v.as_slice());
assert_eq!(result, desired_result);pub fn as_tile(&self) -> MatrixTileSlice<'_>
pub fn naive_mul(&self, rhs: &Self) -> Self
pub fn fast_mul_sequential(&self, other: &Self) -> Self
pub fn fast_mul_sequential_order<L: LoopOrder>(&self, other: &Self) -> Self
pub fn fast_mul_concurrent(&self, other: &Self) -> Self
pub fn fast_mul_concurrent_blocksize<const M: usize, const N: usize>( &self, other: &Self, ) -> Self
pub fn fast_mul_concurrent_blocksize_order<const M: usize, const N: usize, L: LoopOrder>( &self, other: &Self, ) -> Self
Trait Implementations§
Source§impl Arbitrary for Subspace
impl Arbitrary for Subspace
Source§type Parameters = SubspaceArbParams
type Parameters = SubspaceArbParams
arbitrary_with accepts for configuration
of the generated Strategy. Parameters must implement Default.Source§type Strategy = BoxedStrategy<Subspace>
type Strategy = BoxedStrategy<Subspace>
Strategy used to generate values of type Self.Source§fn arbitrary_with(args: Self::Parameters) -> Self::Strategy
fn arbitrary_with(args: Self::Parameters) -> Self::Strategy
Source§impl<'de> Deserialize<'de> for Subspace
impl<'de> Deserialize<'de> for Subspace
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl From<Subspace> for AffineSubspace
impl From<Subspace> for AffineSubspace
impl Eq for Subspace
impl StructuralPartialEq for Subspace
Auto Trait Implementations§
impl Freeze for Subspace
impl RefUnwindSafe for Subspace
impl Send for Subspace
impl Sync for Subspace
impl Unpin for Subspace
impl UnwindSafe for Subspace
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more