Matrix functionality
Basic matrix functionality
As well as the Ring and Matrix interfaces, the following functions are provided to manipulate matrices and to set and retrieve entries and other basic data associated with the matrices.
It is possible to create matrices directly, without first creating a corresponding matrix space. The following constructors are necessary, because unfortunately, Julia's matrices and linear algebra cannot be made to work in our context due to two independent problems:
- In empty matrices (0 rows or columns) all that is known is the type of the matrix entries,
however for the complex types used in AbstractAlgebra, this information is not sufficient to create elements, hence zero(T) or friends cannot work
- Many functions (e.g.
det) assume that all types used embed into the real or complex numbers,
in Julia det(ones(Int, (1,1))) == 1.0, so the fact that this is exactly the integer 1 is lost. Furthermore, more general rings cannot be embedded into the reals at all.
matrix(R::Ring, arr::Matrix{T}) where T <: RingElementGiven an $m\times n$ Julia matrix of entries, construct the corresponding AbstractAlgebra.jl matrix over the given ring R, assuming all the entries can be coerced into R.
matrix(R::Ring, r::Int, c::Int, A::Vector{T}) where T <: RingElementConstruct the given $r\times c$ AbstractAlgebra.jl matrix over the ring R whose $(i, j)$ entry is given by A[c*(i - 1) + j], assuming that all the entries can be coerced into R.
zero_matrix(R::Ring, r::Int, c::Int)Construct the $r\times c$ AbstractAlgebra.jl zero matrix over the ring R.
Examples
julia> M = matrix(ZZ, BigInt[3 1 2; 2 0 1])
[3 1 2]
[2 0 1]
julia> N = matrix(ZZ, 3, 2, BigInt[3, 1, 2, 2, 0, 1])
[3 1]
[2 2]
[0 1]
julia> P = zero_matrix(ZZ, 3, 2)
[0 0]
[0 0]
[0 0]number_of_rows — Method
number_of_rows(a::MatrixElem{T}) where T <: NCRingElementReturn the number of rows of the given matrix.
sourcenumber_of_columns — Method
number_of_columns(a::MatrixElem{T}) where T <: NCRingElementReturn the number of columns of the given matrix.
sourceidentity_matrix — Method
identity_matrix — Method
identity_matrix(M::MatElem{T}) where T <: NCRingElementConstruct the identity matrix in the same matrix space as M, i.e. with ones down the diagonal and zeroes elsewhere. M must be square. This is an alias for one(M).
ones_matrix — Method
scalar_matrix — Method
scalar_matrix(R::NCRing, n::Int, a::NCRingElement)
scalar_matrix(n::Int, a::NCRingElement)Return the $n \times n$ matrix over R with a along the main diagonal and zeroes elsewhere. If R is not specified, it defaults to parent(a).
diagonal_matrix — Method
diagonal_matrix(x::NCRingElement, m::Int, [n::Int])Return the $m \times n$ matrix over $R$ with x along the main diagonal and zeroes elsewhere. If n is not specified, it defaults to m.
Examples
julia> diagonal_matrix(ZZ(2), 2, 3)
[2 0 0]
[0 2 0]
julia> diagonal_matrix(QQ(-1), 3)
[-1//1 0//1 0//1]
[ 0//1 -1//1 0//1]
[ 0//1 0//1 -1//1]sourcezero — Method
zero(x::MatElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement
zero(x::MatElem{T}, r::Int, c::Int) where T <: NCRingElement
zero(x::MatElem{T}, R::NCRing) where T <: NCRingElement
zero(x::MatElem{T}) where T <: NCRingElementCreate an zero matrix over the given ring and dimensions, with defaults based upon the given source matrix x.
transpose — Method
transpose(x::MatrixElem{T}) where T <: NCRingElementReturn the transpose of the given matrix.
Examples
julia> R, t = polynomial_ring(QQ, :t)
(Univariate polynomial ring in t over rationals, t)
julia> S = matrix_space(R, 3, 3)
Matrix space of 3 rows and 3 columns
over univariate polynomial ring in t over rationals
julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
[t + 1 t 1]
[ t^2 t t]
[ -2 t + 2 t^2 + t + 1]
julia> B = transpose(A)
[t + 1 t^2 -2]
[ t t t + 2]
[ 1 t t^2 + t + 1]
sourcetr — Method
tr(x::MatrixElem{T}) where T <: NCRingElementReturn the trace of the matrix $a$, i.e. the sum of the diagonal elements. We require the matrix to be square.
Examples
julia> R, t = polynomial_ring(QQ, :t)
(Univariate polynomial ring in t over rationals, t)
julia> S = matrix_space(R, 3, 3)
Matrix space of 3 rows and 3 columns
over univariate polynomial ring in t over rationals
julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
[t + 1 t 1]
[ t^2 t t]
[ -2 t + 2 t^2 + t + 1]
julia> b = tr(A)
t^2 + 3*t + 2
sourcelower_triangular_matrix — Method
lower_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}Return the $n$ by $n$ matrix whose entries on and below the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $n(n+1)/2$.
An exception is thrown if there is no integer $n$ with this property.
Examples
julia> lower_triangular_matrix([1, 2, 3])
[1 0]
[2 3]sourceupper_triangular_matrix — Method
upper_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}Return the $n$ by $n$ matrix whose entries on and above the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $n(n+1)/2$.
An exception is thrown if there is no integer $n$ with this property.
Examples
julia> upper_triangular_matrix([1, 2, 3])
[1 2]
[0 3]sourcestrictly_lower_triangular_matrix — Method
strictly_lower_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}Return the $n$ by $n$ matrix whose entries below the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $(n-1)n/2$.
An exception is thrown if there is no integer $n$ with this property.
Examples
julia> strictly_lower_triangular_matrix([1, 2, 3])
[0 0 0]
[1 0 0]
[2 3 0]sourcestrictly_upper_triangular_matrix — Method
strictly_upper_triangular_matrix(L::AbstractVector{T}) where {T <: NCRingElement}Return the $n$ by $n$ matrix whose entries above the main diagonal are the elements of L, and which has zeroes elsewhere. The value of $n$ is determined by the condition that L has length $(n-1)n/2$.
An exception is thrown if there is no integer $n$ with this property.
Examples
julia> strictly_upper_triangular_matrix([1, 2, 3])
[0 1 2]
[0 0 3]
[0 0 0]sourceis_lower_triangular — Method
is_lower_triangular(A::MatrixElem)Return true if $A$ is an lower triangular matrix, that is, all entries above the main diagonal are zero. Note that this definition also applies to non-square matrices.
Alias for LinearAlgebra.istril.
Examples
julia> is_lower_triangular(QQ[1 2 ; 0 4])
false
julia> is_lower_triangular(QQ[1 0 ; 3 4])
true
julia> is_lower_triangular(QQ[1 2 ;])
false
julia> is_lower_triangular(QQ[1 ; 2])
truesourceis_upper_triangular — Method
is_upper_triangular(A::MatrixElem)Return true if $A$ is an upper triangular matrix, that is, all entries below the main diagonal are zero. Note that this definition also applies to non-square matrices.
Alias for LinearAlgebra.istriu.
Examples
julia> is_upper_triangular(QQ[1 2 ; 0 4])
true
julia> is_upper_triangular(QQ[1 0 ; 3 4])
false
julia> is_upper_triangular(QQ[1 2 ;])
true
julia> is_upper_triangular(QQ[1 ; 2])
falsesourceis_diagonal — Method
is_diagonal(A::MatrixElem)Return true if $A$ is a diagonal matrix, that is, all entries off the main diagonal are zero. Note that this definition also applies to non-square matrices.
Alias for LinearAlgebra.isdiag.
Examples
julia> is_diagonal(QQ[1 0 ; 0 4])
true
julia> is_diagonal(QQ[1 2 ; 3 4])
false
julia> is_diagonal(QQ[1 0 ;])
truesourcechange_base_ring — Method
change_base_ring(R::NCRing, M::MatrixElem{T}) where T <: NCRingElementReturn the matrix obtained by coercing each entry into R.
Inverse
is_invertible — Method
is_invertible(A::MatrixElem{T}) where {T <: RingElement}Return true if a given square matrix is invertible, false otherwise. If the inverse should also be computed, use is_invertible_with_inverse.
is_invertible_with_inverse — Method
is_invertible_with_inverse(A::MatrixElem{T}; side::Symbol = :left) where {T <: RingElement}Given an $n \times m$ matrix $A$ over a ring, return a tuple (flag, B). If side is :right and flag is true, $B$ is a right inverse of $A$ i.e. $A B$ is the $n \times n$ unit matrix. If side is :left and flag is true, $B$ is a left inverse of $A$ i.e. $B A$ is the $m \times m$ unit matrix. If flag is false, no right or left inverse exists.
To get the space of all inverses, note that if $B$ and $C$ are both right inverses, then $A (B - C) = 0$, and similar for left inverses. Hence from one inverse one can find all by making suitable use of kernel.
pseudo_inv — Method
pseudo_inv(M::MatrixElem{T}) where {T <: RingElement}Given a non-singular $n\times n$ matrix $M$ over a ring return a tuple $X, d$ consisting of an $n\times n$ matrix $X$ and a denominator $d$ such that $MX = dI_n$, where $I_n$ is the $n\times n$ identity matrix. The denominator will be the determinant of $M$ up to sign. If $M$ is singular an exception is raised.
sourceExamples
julia> M = matrix(QQ, 3, 3, [1 2 3;4 5 6;0 0 1])
[1//1 2//1 3//1]
[4//1 5//1 6//1]
[0//1 0//1 1//1]
julia> X = inv(M)
[-5//3 2//3 1//1]
[ 4//3 -1//3 -2//1]
[ 0//1 0//1 1//1]
julia> is_invertible(M)
true
julia> is_invertible_with_inverse(M)
(true, [-5//3 2//3 1; 4//3 -1//3 -2; 0 0 1])
julia> pseudo_inv(M)
([5 -2 -3; -4 1 6; 0 0 -3], -3//1)Submatrices
Submatrices are only available for matrix spaces, not for matrix algebras and generally only available for generic matrices built on Julia arrays.
Submatrices return a new matrix with the same entries as the submatrix with the given range of rows and columns. They are best illustrated with examples.
Examples
julia> M = matrix(ZZ, BigInt[1 2 3; 2 3 4; 3 4 5])
[1 2 3]
[2 3 4]
[3 4 5]
julia> N1 = M[1:2, :]
[1 2 3]
[2 3 4]
julia> N2 = M[:, :]
[1 2 3]
[2 3 4]
[3 4 5]
julia> N3 = M[2:3, 2:3]
[3 4]
[4 5]As per Julia, AbstractAlgebra supports the construction of matrix views. These allow one to work with a submatrix of a given matrix. Modifying the submatrix also modifies the original matrix.
The syntax for views is as for Julia's own views.
Examples
julia> M = matrix(ZZ, 3, 3, BigInt[1, 2, 3, 2, 3, 4, 3, 4, 5])
[1 2 3]
[2 3 4]
[3 4 5]
julia> N1 = @view M[1:2, :]
[1 2 3]
[2 3 4]
julia> N2 = @view M[:, 1:2]
[1 2]
[2 3]
[3 4]
julia> R = N1*N2
[14 20]
[20 29]Elementary row and column operations
add_column — Method
add_column(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, rows = 1:nrows(a)) where T <: RingElementCreate a copy of $a$ and add $s$ times the $i$-th row to the $j$-th row of $a$.
By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.
add_column! — Method
add_column!(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, rows = 1:nrows(a)) where T <: RingElementAdd $s$ times the $i$-th row to the $j$-th row of $a$.
By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.
add_row — Method
add_row(a::MatrixElem{T}, s::RingElement, i::Int, j::Int, cols = 1:ncols(a)) where T <: RingElementCreate a copy of $a$ and add $s$ times the $i$-th row to the $j$-th row of $a$.
By default, the transformation is applied to all columns of $a$. This can be changed using the optional cols argument.
multiply_column — Method
multiply_column(a::MatrixElem{T}, s::RingElement, i::Int, rows = 1:nrows(a)) where T <: RingElementCreate a copy of $a$ and multiply the $i$th column of $a$ with $s$.
By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.
multiply_column! — Method
multiply_column!(a::MatrixElem{T}, s::RingElement, i::Int, rows = 1:nrows(a)) where T <: RingElementMultiply the $i$th column of $a$ with $s$.
By default, the transformation is applied to all rows of $a$. This can be changed using the optional rows argument.
multiply_row — Method
multiply_row(a::MatrixElem{T}, s::RingElement, i::Int, cols = 1:ncols(a)) where T <: RingElementCreate a copy of $a$ and multiply the $i$th row of $a$ with $s$.
By default, the transformation is applied to all columns of $a$. This can be changed using the optional cols argument.
multiply_row! — Method
multiply_row!(a::MatrixElem{T}, s::RingElement, i::Int, cols = 1:ncols(a)) where T <: RingElementMultiply the $i$th row of $a$ with $s$.
By default, the transformation is applied to all columns of $a$. This can be changed using the optional cols argument.
Examples
julia> M = ZZ[1 2 3; 2 3 4; 4 5 5]
[1 2 3]
[2 3 4]
[4 5 5]
julia> add_column(M, 2, 3, 1)
[ 7 2 3]
[10 3 4]
[14 5 5]
julia> add_row(M, 1, 2, 3)
[1 2 3]
[2 3 4]
[6 8 9]
julia> multiply_column(M, 2, 3)
[1 2 6]
[2 3 8]
[4 5 10]
julia> multiply_row(M, 2, 3)
[1 2 3]
[2 3 4]
[8 10 10]Swapping rows and columns
swap_rows — Method
swap_rows(a::MatrixElem{T}, i::Int, j::Int) where T <: NCRingElementReturn a matrix $b$ with the entries of $a$, where the $i$th and $j$th row are swapped.
Examples
julia> M = identity_matrix(ZZ, 3)
[1 0 0]
[0 1 0]
[0 0 1]
julia> swap_rows(M, 1, 2)
[0 1 0]
[1 0 0]
[0 0 1]
julia> M # was not modified
[1 0 0]
[0 1 0]
[0 0 1]sourceswap_rows! — Method
swap_rows!(a::MatrixElem{T}, i::Int, j::Int) where T <: NCRingElementSwap the $i$th and $j$th row of $a$ in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).
Examples
julia> M = identity_matrix(ZZ, 3)
[1 0 0]
[0 1 0]
[0 0 1]
julia> swap_rows!(M, 1, 2)
[0 1 0]
[1 0 0]
[0 0 1]
julia> M # was modified
[0 1 0]
[1 0 0]
[0 0 1]sourceswap_cols! — Method
swap_cols!(a::MatrixElem{T}, i::Int, j::Int) where T <: NCRingElementSwap the $i$th and $j$th column of $a$ in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).
sourceSwap the rows of M in place. The function returns the mutated matrix (since matrices are assumed to be mutable in AbstractAlgebra.jl).
Concatenation
The following are only available for matrix spaces, not for matrix algebras.
hcat(M::T, N::T) where T <: MatElemReturn the horizontal concatenation of $M$ and $N$. It is assumed that the number of rows of $M$ and $N$ are the same.
vcat(M::T, N::T) where T <: MatElemReturn the vertical concatenation of $M$ and $N$. It is assumed that the number of columns of $M$ and $N$ are the same.
Examples
julia> M = matrix(ZZ, BigInt[1 2 3; 2 3 4; 3 4 5])
[1 2 3]
[2 3 4]
[3 4 5]
julia> N = matrix(ZZ, BigInt[1 0 1; 0 1 0; 1 0 1])
[1 0 1]
[0 1 0]
[1 0 1]
julia> P = hcat(M, N)
[1 2 3 1 0 1]
[2 3 4 0 1 0]
[3 4 5 1 0 1]
julia> Q = vcat(M, N)
[1 2 3]
[2 3 4]
[3 4 5]
[1 0 1]
[0 1 0]
[1 0 1]
Linear solving
Block diagonal matrix constructors
It is also possible to create block diagonal matrices from a vector of existing matrices. It is also possible to construct them from Julia matrices if one supplies the base ring.
Note that if the input matrices are not square, the output matrix may not be square.
block_diagonal_matrix — Method
block_diagonal_matrix(V::Vector{<:MatElem{T}}) where T <: NCRingElementCreate the block diagonal matrix whose blocks are given by the matrices in V. There must be at least one matrix in V.
block_diagonal_matrix(xs::Vector{SMat})Return the block diagonal matrix with the matrices in xs on the diagonal. Requires all blocks to have the same base ring.
block_diagonal_matrix — Method
block_diagonal_matrix(R::NCRing, V::Vector{<:Matrix{T}}) where T <: NCRingElementCreate the block diagonal matrix over the ring R whose blocks are given by the matrices in V. Entries are coerced into R upon creation.
Examples
julia> block_diagonal_matrix(ZZ, [[1 2; 3 4], [4 5 6; 7 8 9]])
[1 2 0 0 0]
[3 4 0 0 0]
[0 0 4 5 6]
[0 0 7 8 9]
julia> M = matrix(ZZ, [1 2; 3 4])
[1 2]
[3 4]
julia> N = matrix(ZZ, [4 5 6; 7 8 9])
[4 5 6]
[7 8 9]
julia> block_diagonal_matrix([M, N])
[1 2 0 0 0]
[3 4 0 0 0]
[0 0 4 5 6]
[0 0 7 8 9]Similar and zero
Both similar and zero construct new matrices, but the entries are either undefined with similar or zero-initialized with zero.
similar(x::MatElem, R::Ring=base_ring(x))
zero(x::MatElem, R::Ring=base_ring(x))Construct the matrix with the same dimensions as the given matrix, and the same base ring unless explicitly specified.
similar(x::MatElem, R::Ring, r::Int, c::Int)
similar(x::MatElem, r::Int, c::Int)
zero(x::MatElem, R::Ring, r::Int, c::Int)
zero(x::MatElem, r::Int, c::Int)Construct the $r\times c$ matrix with R as base ring (which defaults to the base ring of the the given matrix). If $x$ belongs to a matrix algebra and $r \neq c$, an exception is raised, and it's also possible to specify only one Int as the order (e.g. similar(x, n)).
Base.isassigned(M::MatElem, i, j)Test whether the given matrix has a value associated with indices i and j.
Examples
julia> M = matrix(ZZ, BigInt[3 1 2; 2 0 1])
[3 1 2]
[2 0 1]
julia> isassigned(M, 1, 2)
true
julia> isassigned(M, 4, 4)
false
julia> A = similar(M)
[#undef #undef #undef]
[#undef #undef #undef]
julia> isassigned(A, 1, 2)
false
julia> B = zero(M)
[0 0 0]
[0 0 0]
julia> C = similar(M, 4, 5)
[#undef #undef #undef #undef #undef]
[#undef #undef #undef #undef #undef]
[#undef #undef #undef #undef #undef]
[#undef #undef #undef #undef #undef]
julia> base_ring(B)
Integers
julia> D = zero(M, QQ, 2, 2)
[0//1 0//1]
[0//1 0//1]
julia> base_ring(D)
RationalsLU factorisation
lu — Method
lu(A::MatrixElem{T}, P = SymmetricGroup(nrows(A))) where {T <: FieldElement}Return a tuple $r, p, L, U$ consisting of the rank of $A$, a permutation $p$ of $A$ belonging to $P$, a lower triangular matrix $L$ and an upper triangular matrix $U$ such that $p(A) = LU$, where $p(A)$ stands for the matrix whose rows are the given permutation $p$ of the rows of $A$.
sourcefflu — Method
fflu(A::MatrixElem{T}, P = SymmetricGroup(nrows(A))) where {T <: RingElement}Return a tuple $r, d, p, L, U$ consisting of the rank of $A$, a denominator $d$, a permutation $p$ of $A$ belonging to $P$, a lower triangular matrix $L$ and an upper triangular matrix $U$ such that $p(A) = LDU$, where $p(A)$ stands for the matrix whose rows are the given permutation $p$ of the rows of $A$ and such that $D$ is the diagonal matrix diag$(p_1, p_1p_2, \ldots, p_{n-2}p_{n-1}, p_{n-1}p_n)$ where the $p_i$ are the inverses of the diagonal entries of $L$. The denominator $d$ is set to $\pm \mathrm{det}(S)$ where $S$ is an appropriate submatrix of $A$ ($S = A$ if $A$ is square and nonsingular) and the sign is decided by the parity of the permutation.
sourceExamples
julia> M = matrix(QQ, 3, 3, [1 2 3;4 5 6;0 0 1])
[1//1 2//1 3//1]
[4//1 5//1 6//1]
[0//1 0//1 1//1]
julia> r, P, L, U = lu(M)
(3, (), [1 0 0; 4 1 0; 0 0 1], [1 2 3; 0 -3 -6; 0 0 1])
julia> r, d, P, L, U = fflu(M)
(3, -3//1, (), [1 0 0; 4 -3 0; 0 0 -3], [1 2 3; 0 -3 -6; 0 0 -3])Reduced row-echelon form
rref_rational — Method
rref_rational(M::MatrixElem{T}) where {T <: RingElement}Return a tuple $(r, A, d)$ consisting of the rank $r$ of $M$ and a denominator $d$ in the base ring of $M$ and a matrix $A$ such that $A/d$ is the reduced row echelon form of $M$. Note that the denominator is not usually minimal.
sourceExamples
julia> M = matrix(QQ, 3, 3, [1 2 3;4 5 6;0 0 1])
[1//1 2//1 3//1]
[4//1 5//1 6//1]
[0//1 0//1 1//1]
julia> r1, A = rref(M)
(3, [1 0 0; 0 1 0; 0 0 1])
julia> N = matrix(ZZ, 3, 3, [1 2 3;4 5 6;0 0 1])
[1 2 3]
[4 5 6]
[0 0 1]
julia> r2, B = rref_rational(N)
(3, [-3 0 0; 0 -3 0; 0 0 -3], -3)
julia> is_rref(A)
true
julia> is_rref(B)
trueOther functionality
Symmetry testing
is_symmetric — Method
is_symmetric(M::MatrixElem)Return true if the given matrix is symmetric with respect to its main diagonal, i.e., transpose(M) == M, otherwise return false.
Alias for LinearAlgebra.issymmetric.
Examples
julia> M = matrix(ZZ, [1 2 3; 2 4 5; 3 5 6])
[1 2 3]
[2 4 5]
[3 5 6]
julia> is_symmetric(M)
true
julia> N = matrix(ZZ, [1 2 3; 4 5 6; 7 8 9])
[1 2 3]
[4 5 6]
[7 8 9]
julia> is_symmetric(N)
falsesourceis_skew_symmetric — Method
is_skew_symmetric(M::MatrixElem)Return true if the given matrix is skew symmetric with respect to its main diagonal, i.e., transpose(M) == -M, otherwise return false.
Examples
julia> M = matrix(ZZ, [0 -1 -2; 1 0 -3; 2 3 0])
[0 -1 -2]
[1 0 -3]
[2 3 0]
julia> is_skew_symmetric(M)
true
sourcePowering
powers — Method
powers(a::Union{NCRingElement, MatElem}, d::Int)Return an array $M$ of "powers" of a where $M[i + 1] = a^i$ for $i = 0..d$.
Examples
julia> M = ZZ[1 2 3; 2 3 4; 4 5 5]
[1 2 3]
[2 3 4]
[4 5 5]
julia> A = powers(M, 4)
5-element Vector{AbstractAlgebra.Generic.MatSpaceElem{BigInt}}:
[1 0 0; 0 1 0; 0 0 1]
[1 2 3; 2 3 4; 4 5 5]
[17 23 26; 24 33 38; 34 48 57]
[167 233 273; 242 337 394; 358 497 579]
[1725 2398 2798; 2492 3465 4044; 3668 5102 5957]
sourceGram matrix
gram — Method
gram(x::MatElem)Return the Gram matrix of $x$, i.e. if $x$ is an $r\times c$ matrix return the $r\times r$ matrix whose entries $i, j$ are the dot products of the $i$-th and $j$-th rows, respectively.
Examples
julia> R, t = polynomial_ring(QQ, :t)
(Univariate polynomial ring in t over rationals, t)
julia> S = matrix_space(R, 3, 3)
Matrix space of 3 rows and 3 columns
over univariate polynomial ring in t over rationals
julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
[t + 1 t 1]
[ t^2 t t]
[ -2 t + 2 t^2 + t + 1]
julia> B = gram(A)
[2*t^2 + 2*t + 2 t^3 + 2*t^2 + t 2*t^2 + t - 1]
[t^3 + 2*t^2 + t t^4 + 2*t^2 t^3 + 3*t]
[ 2*t^2 + t - 1 t^3 + 3*t t^4 + 2*t^3 + 4*t^2 + 6*t + 9]
sourceContent
content — Method
content(x::MatrixElem{T}) where T <: RingElementReturn the content of the matrix $a$, i.e. the greatest common divisor of all its entries, assuming it exists.
Examples
julia> R, t = polynomial_ring(QQ, :t)
(Univariate polynomial ring in t over rationals, t)
julia> S = matrix_space(R, 3, 3)
Matrix space of 3 rows and 3 columns
over univariate polynomial ring in t over rationals
julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
[t + 1 t 1]
[ t^2 t t]
[ -2 t + 2 t^2 + t + 1]
julia> b = content(A)
1
sourcePermutation
* — Method
*(P::Perm, x::MatrixElem{T}) where T <: NCRingElementApply the pemutation $P$ to the rows of the matrix $x$ and return the result.
Examples
julia> R, t = polynomial_ring(QQ, :t)
(Univariate polynomial ring in t over rationals, t)
julia> S = matrix_space(R, 3, 3)
Matrix space of 3 rows and 3 columns
over univariate polynomial ring in t over rationals
julia> G = SymmetricGroup(3)
Full symmetric group over 3 elements
julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
[t + 1 t 1]
[ t^2 t t]
[ -2 t + 2 t^2 + t + 1]
julia> P = G([1, 3, 2])
(2,3)
julia> B = P*A
[t + 1 t 1]
[ -2 t + 2 t^2 + t + 1]
[ t^2 t t]
sourceNilpotency
is_nilpotent — Method
is_nilpotent(A::MatrixElem{T}) where {T <: RingElement}Return if A is nilpotent, i.e. if there exists a natural number $k$ such that $A^k = 0$. If A is not square an exception is raised.
Minors
Exterior power
exterior_power — Method
exterior_power(A::MatElem, k::Int) -> MatElemReturn the k-th exterior power of A.
Examples
julia> A = matrix(ZZ, 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
julia> exterior_power(A, 2)
[-3 -6 -3]
[-6 -12 -6]
[-3 -6 -3]sourcePfaffian
Examples
julia> R, x = polynomial_ring(QQ, ["x$i" for i in 1:6])
(Multivariate polynomial ring in 6 variables over rationals, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}[x1, x2, x3, x4, x5, x6])
julia> M = R[0 x[1] x[2] x[3]; -x[1] 0 x[4] x[5]; -x[2] -x[4] 0 x[6]; -x[3] -x[5] -x[6] 0]
[ 0 x1 x2 x3]
[-x1 0 x4 x5]
[-x2 -x4 0 x6]
[-x3 -x5 -x6 0]
julia> pfaffian(M)
x1*x6 - x2*x5 + x3*x4
julia> pfaffians(M, 2)
6-element Vector{AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}:
x1
x2
x4
x3
x5
x6
Nullspace
nullspace — Method
nullspace(M::MatElem{T}) where {T <: RingElement}Return a tuple $(\nu, N)$ consisting of the nullity $\nu$ of $M$ and a basis $N$ (consisting of column vectors) for the right nullspace of $M$, i.e. such that $MN$ is the zero matrix. If $M$ is an $m\times n$ matrix $N$ will be an $n\times \nu$ matrix. Note that the nullspace is taken to be the vector space kernel over the fraction field of the base ring if the latter is not a field. In AbstractAlgebra we use the name "kernel" for a function to compute an integral kernel.
Examples
julia> R, x = polynomial_ring(ZZ, :x)
(Univariate polynomial ring in x over integers, x)
julia> S = matrix_space(R, 4, 4)
Matrix space of 4 rows and 4 columns
over univariate polynomial ring in x over integers
julia> M = S([-6*x^2+6*x+12 -12*x^2-21*x-15 -15*x^2+21*x+33 -21*x^2-9*x-9;
-8*x^2+8*x+16 -16*x^2+38*x-20 90*x^2-82*x-44 60*x^2+54*x-34;
-4*x^2+4*x+8 -8*x^2+13*x-10 35*x^2-31*x-14 22*x^2+21*x-15;
-10*x^2+10*x+20 -20*x^2+70*x-25 150*x^2-140*x-85 105*x^2+90*x-50])
[ -6*x^2 + 6*x + 12 -12*x^2 - 21*x - 15 -15*x^2 + 21*x + 33 -21*x^2 - 9*x - 9]
[ -8*x^2 + 8*x + 16 -16*x^2 + 38*x - 20 90*x^2 - 82*x - 44 60*x^2 + 54*x - 34]
[ -4*x^2 + 4*x + 8 -8*x^2 + 13*x - 10 35*x^2 - 31*x - 14 22*x^2 + 21*x - 15]
[-10*x^2 + 10*x + 20 -20*x^2 + 70*x - 25 150*x^2 - 140*x - 85 105*x^2 + 90*x - 50]
julia> n, N = nullspace(M)
(2, [1320*x^4-330*x^2-1320*x-1320 1056*x^4+1254*x^3+1848*x^2-66*x-330; -660*x^4+1320*x^3+1188*x^2-1848*x-1056 -528*x^4+132*x^3+1584*x^2+660*x-264; 396*x^3-396*x^2-792*x 0; 0 396*x^3-396*x^2-792*x])sourcenullspace(M::MatElem{T}) where {T <: FieldElement}Return a tuple $(\nu, N)$ consisting of the nullity $\nu$ of $M$ and a basis $N$ (consisting of column vectors) for the right nullspace of $M$, i.e. such that $MN$ is the zero matrix. If $M$ is an $m\times n$ matrix $N$ will be an $n\times \nu$ matrix.
sourceHessenberg form
hessenberg — Method
hessenberg(A::MatrixElem{T}) where {T <: RingElement}Return the Hessenberg form of $M$, i.e. an upper Hessenberg matrix which is similar to $M$. The upper Hessenberg form has nonzero entries above and on the diagonal and in the diagonal line immediately below the diagonal.
sourceis_hessenberg — Method
is_hessenberg(A::MatrixElem{T}) where {T <: RingElement}Return true if $M$ is in Hessenberg form, otherwise returns false.
Examples
julia> R, = residue_ring(ZZ, 7);
julia> M = matrix(R, 4, 4, [1 2 4 3; 2 5 1 0;6 1 3 2; 1 1 3 5])
[1 2 4 3]
[2 5 1 0]
[6 1 3 2]
[1 1 3 5]
julia> A = hessenberg(M)
[1 5 5 3]
[2 1 1 0]
[0 1 3 2]
[0 0 2 2]
julia> is_hessenberg(A)
trueCharacteristic polynomial
charpoly — Method
charpoly(Y::MatrixElem{T}) where {T <: RingElement}
charpoly(S::PolyRing{T}, Y::MatrixElem{T}) where {T <: RingElement}Return the characteristic polynomial $p$ of the square matrix $Y$. If a polynomial ring $S$ over the same base ring as $Y$ is supplied, the resulting polynomial is an element of it.
Examples
julia> R, = residue_ring(ZZ, 7);
julia> S = matrix_space(R, 4, 4)
Matrix space of 4 rows and 4 columns
over residue ring of integers modulo 7
julia> T, y = polynomial_ring(R, :y)
(Univariate polynomial ring in y over R, y)
julia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);
R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])
[1 2 4 3]
[2 5 1 0]
[6 1 3 2]
[1 1 3 5]
julia> A = charpoly(T, M)
y^4 + 2*y^2 + 6*y + 2
julia> A = charpoly(M)
x^4 + 2*x^2 + 6*x + 2sourceMinimal polynomial
minpoly — Method
minpoly(M::MatElem{T}) where {T <: RingElement}
minpoly(S::PolyRing{T}, M::MatElem{T}) where {T <: RingElement}Return the minimal polynomial $p$ of the square matrix $M$. If a polynomial ring $S$ over the same base ring as $Y$ is supplied, the resulting polynomial is an element of it.
Examples
julia> R = GF(13)
Finite field F_13
julia> S, y = polynomial_ring(R, :y)
(Univariate polynomial ring in y over R, y)
julia> M = R[7 6 1;
7 7 5;
8 12 5]
[7 6 1]
[7 7 5]
[8 12 5]
julia> A = minpoly(S, M)
y^2 + 10*y
julia> A = minpoly(M)
x^2 + 10*x
sourceTransforms
similarity! — Method
similarity!(A::MatrixElem{T}, r::Int, d::T) where {T <: RingElement}Applies a similarity transform to the $n\times n$ matrix $M$ in-place. Let $P$ be the $n\times n$ identity matrix that has had all zero entries of row $r$ replaced with $d$, then the transform applied is equivalent to $M = P^{-1}MP$. We require $M$ to be a square matrix. A similarity transform preserves the minimal and characteristic polynomials of a matrix.
Examples
julia> R, = residue_ring(ZZ, 7);
julia> S = matrix_space(R, 4, 4)
Matrix space of 4 rows and 4 columns
over residue ring of integers modulo 7
julia> M = S([R(1) R(2) R(4) R(3); R(2) R(5) R(1) R(0);
R(6) R(1) R(3) R(2); R(1) R(1) R(3) R(5)])
[1 2 4 3]
[2 5 1 0]
[6 1 3 2]
[1 1 3 5]
julia> similarity!(M, 1, R(3))
sourceHermite normal form
hnf_with_transform — Method
hnf_with_transform(A)Return the tuple $H, U$ consisting of the upper right row Hermite normal form $H$ of $A$ together with invertible matrix $U$ such that $UA = H$.
sourceExamples
julia> A = matrix(ZZ, [2 3 -1; 3 5 7; 11 1 12])
[ 2 3 -1]
[ 3 5 7]
[11 1 12]
julia> H = hnf(A)
[1 0 255]
[0 1 17]
[0 0 281]
julia> is_hnf(H)
true
julia> H, U = hnf_with_transform(A)
([1 0 255; 0 1 17; 0 0 281], [-47 28 1; -3 2 0; -52 31 1])
julia> U*A
[1 0 255]
[0 1 17]
[0 0 281]Smith normal form
snf_with_transform — Method
snf_with_transform(A)Return the tuple $S, T, U$ consisting of the Smith normal form $S$ of $A$ together with invertible matrices $T$ and $U$ such that $TAU = S$.
sourceExamples
julia> A = matrix(ZZ, [2 3 -1; 3 5 7; 11 1 12])
[ 2 3 -1]
[ 3 5 7]
[11 1 12]
julia> S = snf(A)
[1 0 0]
[0 1 0]
[0 0 281]
julia> S, T, U = snf_with_transform(A)
([1 0 0; 0 1 0; 0 0 281], [1 0 0; 7 1 0; 229 31 1], [0 -3 26; 0 2 -17; -1 0 1])
julia> T*A*U
[1 0 0]
[0 1 0]
[0 0 281](Weak) Popov form
AbstractAlgebra.jl provides algorithms for computing the (weak) Popov of a matrix with entries in a univariate polynomial ring over a field.
is_weak_popov — Method
is_weak_popov(P::MatrixElem{T}, rank::Int) where T <: PolyRingElemReturn true if $P$ is a matrix in weak Popov form of the given rank.
weak_popov — Method
weak_popov_with_transform — Method
weak_popov_with_transform(A::MatElem{T}) where {T <: PolyRingElem}Compute a tuple $(P, U)$ where $P$ is the weak Popov form of $A$ and $U$ is a transformation matrix so that $P = UA$.
sourcepopov_with_transform — Method
popov_with_transform(A::MatElem{T}) where {T <: PolyRingElem}Compute a tuple $(P, U)$ where $P$ is the Popov form of $A$ and $U$ is a transformation matrix so that $P = UA$.
sourceExamples
julia> R, x = polynomial_ring(QQ, :x);
julia> A = matrix(R, map(R, Any[1 2 3 x; x 2*x 3*x x^2; x x^2+1 x^3+x^2 x^4+x^2+1]))
[1 2 3 x]
[x 2*x 3*x x^2]
[x x^2 + 1 x^3 + x^2 x^4 + x^2 + 1]
julia> P = weak_popov(A)
[ 1 2 3 x]
[ 0 0 0 0]
[-x^3 -2*x^3 + x^2 - 2*x + 1 -2*x^3 + x^2 - 3*x 1]
julia> P, U = weak_popov_with_transform(A)
([1 2 3 x; 0 0 0 0; -x^3 -2*x^3+x^2-2*x+1 -2*x^3+x^2-3*x 1], [1 0 0; -x 1 0; -x^3-x 0 1])
julia> U*A
[ 1 2 3 x]
[ 0 0 0 0]
[-x^3 -2*x^3 + x^2 - 2*x + 1 -2*x^3 + x^2 - 3*x 1]