| """ | |
| 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 | |