Coverage for /usr/lib/python3/dist-packages/sympy/polys/matrices/eigen.py: 17%

53 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1""" 

2 

3Routines for computing eigenvectors with DomainMatrix. 

4 

5""" 

6from sympy.core.symbol import Dummy 

7 

8from ..agca.extensions import FiniteExtension 

9from ..factortools import dup_factor_list 

10from ..polyroots import roots 

11from ..polytools import Poly 

12from ..rootoftools import CRootOf 

13 

14from .domainmatrix import DomainMatrix 

15 

16 

17def dom_eigenvects(A, l=Dummy('lambda')): 

18 charpoly = A.charpoly() 

19 rows, cols = A.shape 

20 domain = A.domain 

21 _, factors = dup_factor_list(charpoly, domain) 

22 

23 rational_eigenvects = [] 

24 algebraic_eigenvects = [] 

25 for base, exp in factors: 

26 if len(base) == 2: 

27 field = domain 

28 eigenval = -base[1] / base[0] 

29 

30 EE_items = [ 

31 [eigenval if i == j else field.zero for j in range(cols)] 

32 for i in range(rows)] 

33 EE = DomainMatrix(EE_items, (rows, cols), field) 

34 

35 basis = (A - EE).nullspace() 

36 rational_eigenvects.append((field, eigenval, exp, basis)) 

37 else: 

38 minpoly = Poly.from_list(base, l, domain=domain) 

39 field = FiniteExtension(minpoly) 

40 eigenval = field(l) 

41 

42 AA_items = [ 

43 [Poly.from_list([item], l, domain=domain).rep for item in row] 

44 for row in A.rep.to_ddm()] 

45 AA_items = [[field(item) for item in row] for row in AA_items] 

46 AA = DomainMatrix(AA_items, (rows, cols), field) 

47 EE_items = [ 

48 [eigenval if i == j else field.zero for j in range(cols)] 

49 for i in range(rows)] 

50 EE = DomainMatrix(EE_items, (rows, cols), field) 

51 

52 basis = (AA - EE).nullspace() 

53 algebraic_eigenvects.append((field, minpoly, exp, basis)) 

54 

55 return rational_eigenvects, algebraic_eigenvects 

56 

57 

58def dom_eigenvects_to_sympy( 

59 rational_eigenvects, algebraic_eigenvects, 

60 Matrix, **kwargs 

61): 

62 result = [] 

63 

64 for field, eigenvalue, multiplicity, eigenvects in rational_eigenvects: 

65 eigenvects = eigenvects.rep.to_ddm() 

66 eigenvalue = field.to_sympy(eigenvalue) 

67 new_eigenvects = [ 

68 Matrix([field.to_sympy(x) for x in vect]) 

69 for vect in eigenvects] 

70 result.append((eigenvalue, multiplicity, new_eigenvects)) 

71 

72 for field, minpoly, multiplicity, eigenvects in algebraic_eigenvects: 

73 eigenvects = eigenvects.rep.to_ddm() 

74 l = minpoly.gens[0] 

75 

76 eigenvects = [[field.to_sympy(x) for x in vect] for vect in eigenvects] 

77 

78 degree = minpoly.degree() 

79 minpoly = minpoly.as_expr() 

80 eigenvals = roots(minpoly, l, **kwargs) 

81 if len(eigenvals) != degree: 

82 eigenvals = [CRootOf(minpoly, l, idx) for idx in range(degree)] 

83 

84 for eigenvalue in eigenvals: 

85 new_eigenvects = [ 

86 Matrix([x.subs(l, eigenvalue) for x in vect]) 

87 for vect in eigenvects] 

88 result.append((eigenvalue, multiplicity, new_eigenvects)) 

89 

90 return result