Eigenvalues and -spaces
OSCAR can compute eigenvalues and -spaces exactly and numerically over rings and fields as follows.
Eigenvalues
Let us define a matrix over the rationals and ask OSCAR to compute its exact eigenvalues.
julia> A = QQ[0 -1 0; 1 0 0; 0 0 2]
[0 -1 0]
[1 0 0]
[0 0 2]
julia> eigenvalues(A)
1-element Vector{QQFieldElem}:
2Note, however, that this only returns the eigenvalues of the matrix over its base field (the rationals in this example). In order to obtain the eigenvalues over a larger field, we can either change the base field of the entries in the matrix or pass the desired field as the first argument. In the following, we consider all eigenvalues in the algebraic closure of the rationals.
julia> K = algebraic_closure(QQ)
Algebraic closure of rational field
julia> eigenvalues(K, A)
3-element Vector{QQBarFieldElem}:
{a1: 2.00000}
{a2: 1.00000*im}
{a2: -1.00000*im}
julia> A_K = change_base_ring(K, A)
[ {a1: 0} {a1: -1.00} {a1: 0}]
[{a1: 1.00} {a1: 0} {a1: 0}]
[ {a1: 0} {a1: 0} {a1: 2.00}]
julia> eigenvalues(A_K)
3-element Vector{QQBarFieldElem}:
{a1: 2.00000}
{a2: 1.00000*im}
{a2: -1.00000*im}In the following, we ask OSCAR to compute approximations of the eigenvalues of a matrix over the real numbers. The precision for the computation can be set by the user. Computing such approximations over the complex numbers works alike.
julia> B = QQ[0 2; 1 0]
[0 2]
[1 0]
julia> RR = real_field()
Real field
julia> set_precision!(RR,64)
64
julia> eigenvalues(RR,B)
2-element Vector{RealFieldElem}:
[-1.4142135623730950488 +/- 1.69e-21]
[1.4142135623730950488 +/- 1.69e-21]
julia> set_precision!(RR,128)
128
julia> eigenvalues(RR,B)
2-element Vector{RealFieldElem}:
[-1.41421356237309504880168872420969807857 +/- 3.29e-40]
[1.41421356237309504880168872420969807857 +/- 3.29e-40]eigenvalues — Method
eigenvalues(M::MatElem{T}) where T <: RingElemReturn the eigenvalues of M which lie in base_ring(M).
eigenvalues — Method
eigenvalues(L::Field, M::MatElem{T}) where T <: RingElemReturn the eigenvalues of M over the field L.
eigenvalues_simple — Function
eigenvalues_simple(A::AcbMatrix, algorithm::Symbol = :default)Returns the eigenvalues of A as a vector of AcbFieldElem. It is assumed that A has only simple eigenvalues.
The algorithm used can be changed by setting the algorithm keyword to :vdhoeven_mourrain or :rump.
This function is experimental.
eigenvalues_simple(A::ComplexMatrix, algorithm::Symbol = :default)Returns the eigenvalues of A as a vector of ComplexFieldElem. It is assumed that A has only simple eigenvalues.
The algorithm used can be changed by setting the algorithm keyword to :vdhoeven_mourrain or :rump.
This function is experimental.
eigenvalues_with_multiplicities — Method
eigenvalues_with_multiplicities(M::MatElem{T}) where T <: FieldElemReturn the eigenvalues of M (which lie in base_ring(M)) together with their algebraic multiplicities as a vector of tuples of (root, multiplicity).
eigenvalues_with_multiplicities — Method
eigenvalues_with_multiplicities(L::Field, M::MatElem{T}) where T <: RingElemReturn the eigenvalues of M over the field L together with their algebraic multiplicities as a vector of tuples.
Eigenspaces
Let us define a matrix over the rationals and ask OSCAR to compute its exact eigenspaces together with its corresponding eigenvalues.
julia> A = QQ[0 -1 0; 1 0 0; 0 0 2]
[0 -1 0]
[1 0 0]
[0 0 2]
julia> eigenspaces(A)
Dict{QQFieldElem, QQMatrix} with 1 entry:
2 => [0 0 1]Note, however, that this only returns the eigenvalues and -spaces of the matrix over its base field (the rationals in this example). In order to obtain the eigenspaces over a larger field, we can either change the base field of the entries in the matrix or pass the desired field as the first argument. In the following, we consider all eigenspaces in the algebraic closure of the rationals.
julia> K = algebraic_closure(QQ)
Algebraic closure of rational field
julia> eigenspaces(K, A)
Dict{QQBarFieldElem, AbstractAlgebra.Generic.MatSpaceElem{QQBarFieldElem}} with 3 entries:
{a1: 2.00} => [{a1: 0} {a1: 0} {a1: 1.00000}]
{a2: 1.00*im} => [{a2: -1.00000*im} {a1: 1.00000} {a1: 0}]
{a2: -1.00*im} => [{a2: 1.00000*im} {a1: 1.00000} {a1: 0}]
julia> A_K = change_base_ring(K, A)
[ {a1: 0} {a1: -1.00} {a1: 0}]
[{a1: 1.00} {a1: 0} {a1: 0}]
[ {a1: 0} {a1: 0} {a1: 2.00}]
julia> eigenspaces(A_K)
Dict{QQBarFieldElem, AbstractAlgebra.Generic.MatSpaceElem{QQBarFieldElem}} with 3 entries:
{a1: 2.00} => [{a1: 0} {a1: 0} {a1: 1.00000}]
{a2: 1.00*im} => [{a2: -1.00000*im} {a1: 1.00000} {a1: 0}]
{a2: -1.00*im} => [{a2: 1.00000*im} {a1: 1.00000} {a1: 0}]
We note that eigenspaces of floating point matrices are not well defined. Hence, their computation is forbidden in OSCAR.
eigenspace — Function
eigenspace(M::MatElem{T1}, lambda::T2; side::Symbol = :left)
where {T1 <: RingElem, T2 <: RingElement} -> MatElem{T}Return a matrix whose rows (if side == :left) or columns (if side == :right) give a basis of the eigenspace of $M$ with respect to the eigenvalue $\lambda$. If side is :right, the right eigenspace is computed, i.e. vectors $v$ such that $Mv = \lambda v$. If side is :left, the left eigenspace is computed, i.e. vectors $v$ such that $vM = \lambda v$.
Examples
julia> F = GF(3);
julia> m = matrix(F, [1 0 ; 1 1])
[1 0]
[1 1]
julia> eigenvalues(F, m) == [1]
true
julia> eigenspace(m, 1; side=:left)
[1 0]
julia> eigenspace(m, 1; side=:right)
[0]
[1]eigenspaces — Function
eigenspaces(M::MatElem{T}; side::Symbol = :left)
where T <: FieldElem -> Dict{T, MatElem{T}}Return a dictionary containing the eigenvalues of $M$ as keys and bases for the corresponding eigenspaces as values. If side is :right, the right eigenspaces are computed, if it is :left then the left eigenspaces are computed.
See also eigenspace.
eigenspaces(L::Field, M::MatElem{T}; side::Symbol = :left)
where T <: RingElem -> Dict{T, MatElem{T}}Return a dictionary containing the eigenvalues of $M$ over the field $L$ as keys and bases for the corresponding eigenspaces as values. If side is :right, the right eigenspaces are computed, if it is :left then the left eigenspaces are computed.
See also eigenspace.