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!Function
NormalForms.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/

source
NormalForms.snf_ma!Function
NormalForms.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/

source

Algorithms

NormalForms.eyeFunction
NormalForms.eye(T::Type, sz)

Generates an identity matrix of size sz with elements of type T.

source
NormalForms.eye(M::AbstractMatrix, dim)

Generates an identity matrix of the same dimension as dimension dim of M.

source
NormalForms.gcd_kbFunction
NormalForms.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.

source
NormalForms.detb!Function
NormalForms.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. ```

source
NormalForms.swapcols!Function
NormalForms.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.

source
NormalForms.swaprows!Function
NormalForms.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.

source
NormalForms.find_pivotFunction
NormalForms.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.

source
NormalForms.is_row_zero_afterFunction
NormalForms.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.

source
NormalForms.is_col_zero_afterFunction
NormalForms.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.

source
NormalForms.zero_row!Function
NormalForms.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.

source
NormalForms.zero_col!Function
NormalForms.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.

source
NormalForms.reduce_cols_off_diagonal!Function
NormalForms.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.

source
NormalForms.zero_row_and_col!Function
NormalForms.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.

source
NormalForms.enforce_divisibility!Function
NormalForms.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.

source