Spaces:
Running
Running
""" | |
Routines for computing eigenvectors with DomainMatrix. | |
""" | |
from sympy.core.symbol import Dummy | |
from ..agca.extensions import FiniteExtension | |
from ..factortools import dup_factor_list | |
from ..polyroots import roots | |
from ..polytools import Poly | |
from ..rootoftools import CRootOf | |
from .domainmatrix import DomainMatrix | |
def dom_eigenvects(A, l=Dummy('lambda')): | |
charpoly = A.charpoly() | |
rows, cols = A.shape | |
domain = A.domain | |
_, factors = dup_factor_list(charpoly, domain) | |
rational_eigenvects = [] | |
algebraic_eigenvects = [] | |
for base, exp in factors: | |
if len(base) == 2: | |
field = domain | |
eigenval = -base[1] / base[0] | |
EE_items = [ | |
[eigenval if i == j else field.zero for j in range(cols)] | |
for i in range(rows)] | |
EE = DomainMatrix(EE_items, (rows, cols), field) | |
basis = (A - EE).nullspace(divide_last=True) | |
rational_eigenvects.append((field, eigenval, exp, basis)) | |
else: | |
minpoly = Poly.from_list(base, l, domain=domain) | |
field = FiniteExtension(minpoly) | |
eigenval = field(l) | |
AA_items = [ | |
[Poly.from_list([item], l, domain=domain).rep for item in row] | |
for row in A.rep.to_ddm()] | |
AA_items = [[field(item) for item in row] for row in AA_items] | |
AA = DomainMatrix(AA_items, (rows, cols), field) | |
EE_items = [ | |
[eigenval if i == j else field.zero for j in range(cols)] | |
for i in range(rows)] | |
EE = DomainMatrix(EE_items, (rows, cols), field) | |
basis = (AA - EE).nullspace(divide_last=True) | |
algebraic_eigenvects.append((field, minpoly, exp, basis)) | |
return rational_eigenvects, algebraic_eigenvects | |
def dom_eigenvects_to_sympy( | |
rational_eigenvects, algebraic_eigenvects, | |
Matrix, **kwargs | |
): | |
result = [] | |
for field, eigenvalue, multiplicity, eigenvects in rational_eigenvects: | |
eigenvects = eigenvects.rep.to_ddm() | |
eigenvalue = field.to_sympy(eigenvalue) | |
new_eigenvects = [ | |
Matrix([field.to_sympy(x) for x in vect]) | |
for vect in eigenvects] | |
result.append((eigenvalue, multiplicity, new_eigenvects)) | |
for field, minpoly, multiplicity, eigenvects in algebraic_eigenvects: | |
eigenvects = eigenvects.rep.to_ddm() | |
l = minpoly.gens[0] | |
eigenvects = [[field.to_sympy(x) for x in vect] for vect in eigenvects] | |
degree = minpoly.degree() | |
minpoly = minpoly.as_expr() | |
eigenvals = roots(minpoly, l, **kwargs) | |
if len(eigenvals) != degree: | |
eigenvals = [CRootOf(minpoly, l, idx) for idx in range(degree)] | |
for eigenvalue in eigenvals: | |
new_eigenvects = [ | |
Matrix([x.subs(l, eigenvalue) for x in vect]) | |
for vect in eigenvects] | |
result.append((eigenvalue, multiplicity, new_eigenvects)) | |
return result | |