图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.9 KiB

  1. """
  2. Routines for computing eigenvectors with DomainMatrix.
  3. """
  4. from sympy.core.symbol import Dummy
  5. from ..agca.extensions import FiniteExtension
  6. from ..factortools import dup_factor_list
  7. from ..polyroots import roots
  8. from ..polytools import Poly
  9. from ..rootoftools import CRootOf
  10. from .domainmatrix import DomainMatrix
  11. def dom_eigenvects(A, l=Dummy('lambda')):
  12. charpoly = A.charpoly()
  13. rows, cols = A.shape
  14. domain = A.domain
  15. _, factors = dup_factor_list(charpoly, domain)
  16. rational_eigenvects = []
  17. algebraic_eigenvects = []
  18. for base, exp in factors:
  19. if len(base) == 2:
  20. field = domain
  21. eigenval = -base[1] / base[0]
  22. EE_items = [
  23. [eigenval if i == j else field.zero for j in range(cols)]
  24. for i in range(rows)]
  25. EE = DomainMatrix(EE_items, (rows, cols), field)
  26. basis = (A - EE).nullspace()
  27. rational_eigenvects.append((field, eigenval, exp, basis))
  28. else:
  29. minpoly = Poly.from_list(base, l, domain=domain)
  30. field = FiniteExtension(minpoly)
  31. eigenval = field(l)
  32. AA_items = [
  33. [Poly.from_list([item], l, domain=domain).rep for item in row]
  34. for row in A.rep.to_ddm()]
  35. AA_items = [[field(item) for item in row] for row in AA_items]
  36. AA = DomainMatrix(AA_items, (rows, cols), field)
  37. EE_items = [
  38. [eigenval if i == j else field.zero for j in range(cols)]
  39. for i in range(rows)]
  40. EE = DomainMatrix(EE_items, (rows, cols), field)
  41. basis = (AA - EE).nullspace()
  42. algebraic_eigenvects.append((field, minpoly, exp, basis))
  43. return rational_eigenvects, algebraic_eigenvects
  44. def dom_eigenvects_to_sympy(
  45. rational_eigenvects, algebraic_eigenvects,
  46. Matrix, **kwargs
  47. ):
  48. result = []
  49. for field, eigenvalue, multiplicity, eigenvects in rational_eigenvects:
  50. eigenvects = eigenvects.rep.to_ddm()
  51. eigenvalue = field.to_sympy(eigenvalue)
  52. new_eigenvects = [
  53. Matrix([field.to_sympy(x) for x in vect])
  54. for vect in eigenvects]
  55. result.append((eigenvalue, multiplicity, new_eigenvects))
  56. for field, minpoly, multiplicity, eigenvects in algebraic_eigenvects:
  57. eigenvects = eigenvects.rep.to_ddm()
  58. l = minpoly.gens[0]
  59. eigenvects = [[field.to_sympy(x) for x in vect] for vect in eigenvects]
  60. degree = minpoly.degree()
  61. minpoly = minpoly.as_expr()
  62. eigenvals = roots(minpoly, l, **kwargs)
  63. if len(eigenvals) != degree:
  64. eigenvals = [CRootOf(minpoly, l, idx) for idx in range(degree)]
  65. for eigenvalue in eigenvals:
  66. new_eigenvects = [
  67. Matrix([x.subs(l, eigenvalue) for x in vect])
  68. for vect in eigenvects]
  69. result.append((eigenvalue, multiplicity, new_eigenvects))
  70. return result