A kernel vector by elimination #
Let A be a matrix with r rows and n columns over a field. Gaussian elimination finds a
nonzero vector v with A v = 0 whenever one exists. This module records a branch-free variant
that suits circuits: it maintains n vectors N i spanning the common kernel of the rows
processed so far, starting from the unit vectors. To process a row a it computes the values
b i = a ⬝ N i, takes the first index j with b j ≠ 0 (the pivot), and replaces each N i
by N i - (b i / b j) • N j. The new vectors are killed by a, and every vector of the old span
killed by a lies in their span (Cslib.LinearAlgebra.kernelStep). When b = 0 no pivot exists;
the pivot value and pivot vector are then zero, and since division by zero is zero in a field the
update leaves N unchanged. After all rows the vectors span the kernel of A
(Cslib.LinearAlgebra.kernelBasis), and the first nonzero one is the output
(Cslib.LinearAlgebra.kernelVec): it lies in the kernel (Cslib.LinearAlgebra.mulVec_kernelVec)
and it is nonzero whenever the kernel is (Cslib.LinearAlgebra.kernelVec_ne_zero).
Pivots are selected by the indicator Cslib.LinearAlgebra.firstFlags b of the first nonzero entry
of b, so every step is a fixed arithmetic expression in the entries, with tests for zero and no
other branching. Processing a row costs O(n ^ 2) field operations. The procedure is Gaussian
elimination organized for straight-line evaluation, as needed to count its gates in circuits.
Main definitions #
Cslib.LinearAlgebra.firstFlags: the indicator of the first nonzero entry.Cslib.LinearAlgebra.firstNonzero: the first nonzero entry of a vector, as a value.Cslib.LinearAlgebra.rowValues: the valuesa ⬝ N iof a row on the vectors of the family.Cslib.LinearAlgebra.pivotVec: the pivot vector, the member of the family at the first nonzero row value, or zero.Cslib.LinearAlgebra.kernelStep: process one row.Cslib.LinearAlgebra.kernelBasisUpTo: process the firstkrows, starting from the unit vectors.Cslib.LinearAlgebra.kernelBasis: process all rows, starting from the unit vectors.Cslib.LinearAlgebra.kernelVec: the first nonzero vector of the final family.
Main results #
Cslib.LinearAlgebra.mulVec_kernelVec: the output lies in the kernel.Cslib.LinearAlgebra.kernelVec_ne_zero: the output is nonzero when the kernel is nontrivial.
References #
The first nonzero entry #
firstFlags b i is one at the first index i with b i ≠ 0 and zero elsewhere; it is zero
everywhere when b = 0.
Instances For
The flags of the zero vector are zero.
For b ≠ 0, firstFlags b is the indicator of the first index j with b j ≠ 0.
Weighting a family by firstFlags b selects its member at the first nonzero entry of b,
or gives zero when b = 0.
The first nonzero entry as a value #
The first nonzero entry of a vector, or zero for the zero vector.
Instances For
The first nonzero entry vanishes only for the zero vector.
Scaling a vector scales its first nonzero entry.
A nonzero vector u is firstNonzero u times its normalization (firstNonzero u)⁻¹ • u.
Elimination #
The pivot vector: the member of the family at the first nonzero row value, or zero.
Instances For
One elimination step. Replace each vector N i of the family by
N i - (b i / β) • P, where b are the row values, P the pivot vector and β = a ⬝ P the
pivot value.
Instances For
A kernel vector. The first nonzero vector of kernelBasis A, or zero if all of them are
zero.