Kano001's picture
Upload 3077 files
6a86ad5 verified
raw
history blame
3.02 kB
"""
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