Internal APIs
Most users should not need to read this section: it's primarily intended for those who would like to contribute to the package.
Docstrings for internal functions and other objects begin with NormalForms
, in contrast with the public API.
Factorizations
NormalForms.hnf_ma!
— FunctionNormalForms.hnf_ma!(
A::AbstractMatrix{<:Integer},
R::RoundingMode = NegativeOffDiagonal
) -> Tuple{typeof(A), typeof(A), LinearAlgebra.BlasInt}
A modified version of HermiteNormalForm._hnf_like!()
that calculates the column-style Hermite normal form of a matrix in-place, returning A
, the unimodular matrix U
such that H == A*U
, and the factorization info (zero if success - matching LinearAlgebra factorizations).
The original implementation of HermiteNormalForm._hnf_like!()
was written by Yingbo Ma, and may be found here: https://github.com/YingboMa/HermiteNormalForm.jl/
NormalForms.snf_ma!
— FunctionNormalForms.snf_ma!(A::AbstractMatrix{<:Integer})
-> Tuple{typeof(A), typeof(A), typeof(A), LinearAlgebra.BlasInt}
A modified version of HermiteNormalForm._hnf_like!()
that calculates the Smith normal form of a matrix in-place, returning A
, the unimodular matrices U
and V
such that S == U*A*V
, and the factorization info (zero if success - matching LinearAlgebra factorizations).
The original implementation of HermiteNormalForm._hnf_like!()
was written by Yingbo Ma, and may be found here: https://github.com/YingboMa/HermiteNormalForm.jl/
Algorithms
NormalForms.eye
— FunctionNormalForms.eye(T::Type, sz)
Generates an identity matrix of size sz
with elements of type T
.
NormalForms.eye(M::AbstractMatrix, dim)
Generates an identity matrix of the same dimension as dimension dim
of M
.
NormalForms.gcd_kb
— FunctionNormalForms.gcd_kb(x::Integer, y::Integer) -> NTuple{3,promote_type(typeof(x),typeof(y))}
Calculates the gcd r
and Bézout coefficients (p, q)
with the Kannan-Bachem modification. This ensures that abs(q) ≤ max(abs(x), abs(y))
.
If x == y
, this function returns (x, 1, 0)
- this differs from Julia's gcdx()
, which returns (x, 0, 1)
. This modification is needed to prevent snf_ma!()
from looping infinitely when zeroing rows and columns.
NormalForms.detb!
— FunctionNormalForms.detb!(M::AbstractMatrix{T<:Number}) -> T
Calculates the determinant of a matrix using the Bareiss algorithm using in-place operations. This algorithm returns exact integer determinants for integer matrices, which is useful when checking whether a matrix is unimodular.
This is a verbatim reimplementation of LinearAlgebra.det_bareiss()
used to ensure compatibility with Julia 1.6, which does not have this function. ```
NormalForms.detb
— FunctionNormalForms.detb(M::AbstractMatrix) -> eltype(M)
Calculates the determinant of a matrix using the Bareiss Algorithm without modifying M
.
NormalForms.swapcols!
— FunctionNormalForms.swapcols!(A::AbstractMatrix, x, y)
Swaps columns of x
and y
of the matrix A
.
Bounds checks are implmented and may be disabled with @inbounds
. However, if x
and y
reference the same index, no error is thrown, even if they are not valid indices of the array.
Unlike the implementation in Base, for convenience, A
is returned.
NormalForms.swaprows!
— FunctionNormalForms.swaprows!(A::AbstractMatrix, x, y)
Swaps rows of x
and y
of the matrix A
.
Bounds checks are implmented and may be disabled with @inbounds
. However, if x
and y
reference the same index, no error is thrown, even if they are not valid indices of the array.
Unlike the implementation in Base, for convenience, A
is returned.
NormalForms.find_pivot
— FunctionNormalForms.find_pivot(A::AbstractMatrix{<:Integer}, k::Integer)
Finds a suitable pivot element for the Smith or Hermite normal form algorithms. If none can be found, it returns 0.
NormalForms.is_row_zero_after
— FunctionNormalForms.is_row_zero_after(A::AbstractMatrix, k::Integer) -> Bool
NormalForms.is_column_zero_after(A::AbstractMatrix, k::Integer) -> Bool
Checks if all entries of row or column k
superseding A[k,k]
are zero.
NormalForms.is_col_zero_after
— FunctionNormalForms.is_row_zero_after(A::AbstractMatrix, k::Integer) -> Bool
NormalForms.is_column_zero_after(A::AbstractMatrix, k::Integer) -> Bool
Checks if all entries of row or column k
superseding A[k,k]
are zero.
NormalForms.zero_row!
— FunctionNormalForms.zero_row!(
A::AbstractMatrix{<:Integer},
U::AbstractMatrix{<:Integer},
k::Integer
ki::Integer = k
)
Zeroes the elements along the row A[k,k+1:end]
(all elements right of A[k,k]
). Changes to A
are tracked in the matrix U
, which will only undergo unimodular transforms.
NormalForms.zero_col!
— FunctionNormalForms.zero_col!(
A::AbstractMatrix{<:Integer},
U::AbstractMatrix{<:Integer},
k::Integer
ki::Integer = k
)
Zeroes the elements along the column A[k+1:end,k]
(all elements below A[k,k]
). Changes to A
are tracked in the matrix U
, which will only undergo unimodular transforms.
NormalForms.reduce_cols_off_diagonal!
— FunctionNormalForms.reduce_cols_off_diagonal!(
A::AbstractMatrix{<:Integer},
U::AbstractMatrix{<:Integer},
R::RoundingMode
)
Performs an off-diagonal reduction of elements in A
in-place by columns. This also ensures that diagonal elements are positive by multiplying the columns by -1 if needed. Changes to A
are tracked in the matrix U
, which will only undergo unimodular transforms.
If the RoundingMode
is set to RoundUp
or NegativeOffDiagonal
(the default), the off-diagonal elements will be negative. If set to RoundDown
or PositiveOffDiagonal
, they will be positive.
NormalForms.zero_row_and_col!
— FunctionNormalForms.zero_row_and_col!(
A::AbstractMatrix,
U::AbstractMatrix,
V::AbstractMatrix,
k::Integer,
ki::Integer = k
)
Zeros row and column k
of matrix A
, tracking the changes in left unimodular matrix U
and right unimodular matrix V
.
NormalForms.enforce_divisibility!
— FunctionNormalForms.enforce_divisibility!(
A::AbstractMatrix,
U::AbstractMatrix,
V::AbstractMatrix,
k::Integer
)
Ensures that diagonal element k
is a multiple of diagonal element k-1
by mutating A
as well as the pre-multiplied matrix U
and post-multiplied matrix V
.