SymPy не может вычислить собственные значения этой матрицы - PullRequest
0 голосов
/ 15 мая 2018

Я хочу вычислить второе собственное значение матрицы Лапласа, чтобы проверить, связан ли соответствующий граф или нет, но когда я пытаюсь использовать eigenvals SymPy, часто случается, что он выдает ошибку

MatrixError: Could not compute eigenvalues for 
Matrix([[1.00000000000000, 0.0, 0.0, 0.0, -1.00000000000000, 0.0, 0.0, 0.0, 0.0, 0.0], 
        [0.0, 1.00000000000000, 0.0, 0.0, 0.0, -1.00000000000000, 0.0, 0.0, 0.0, 0.0], 
        [0.0, 0.0, 1.00000000000000, 0.0, 0.0, 0.0, 0.0, 0.0, -1.00000000000000, 0.0], 
        [0.0, 0.0, 0.0, 1.00000000000000, 0.0, 0.0, 0.0, 0.0, -1.00000000000000, 0.0], 
        [-1.00000000000000, 0.0, 0.0, 0.0, 1.00000000000000, 0.0, 0.0, 0.0, 0.0, 0.0], 
        [0.0, -1.00000000000000, 0.0, 0.0, 0.0, 3.00000000000000, 0.0, 0.0, -1.00000000000000, -1.00000000000000], 
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.00000000000000, 0.0, -1.00000000000000], 
        [0.0, 0.0, -1.00000000000000, -1.00000000000000, 0.0, -1.00000000000000, 0.0, 0.0, 3.00000000000000, 0.0], 
        [0.0, 0.0, 0.0, 0.0, 0.0, -1.00000000000000, 0.0, -1.00000000000000, 0.0, 2.00000000000000]])

Оглядываясь вокруг, я обнаружил, что, поскольку SymPy выполняет символические вычисления, для него могут быть проблемы с плавающей запятой. Итак, я попробовал:

  1. Чтобы уменьшить точность с плавающей точкой Float(tmp[i][j], 3), но это не помогло.
  2. Я пытался преобразовать числа с плавающей точкой в ​​Rational list(map(nsimplify, tmp[i])), но это не помогло.
  3. Я пытался преобразовать числа с плавающей точкой в ​​int list(map(int, tmp[i])), но это тоже не помогло.

Я действительно не могу понять, почему это не сработает, даже если я преобразую каждый элемент в int.

1 Ответ

0 голосов
/ 16 мая 2018

Поскольку лапласиан является целочисленной матрицей, давайте использовать целые числа:

L = Matrix([[ 1,  0,  0,  0, -1,  0, 0,  0,  0,  0],
            [ 0,  1,  0,  0,  0, -1, 0,  0,  0,  0],
            [ 0,  0,  1,  0,  0,  0, 0,  0, -1,  0],
            [ 0,  0,  0,  1,  0,  0, 0,  0, -1,  0],
            [-1,  0,  0,  0,  1,  0, 0,  0,  0,  0],
            [ 0, -1,  0,  0,  0,  3, 0,  0, -1, -1],
            [ 0,  0,  0,  0,  0,  0, 0,  0,  0,  0],
            [ 0,  0,  0,  0,  0,  0, 0,  1,  0, -1],
            [ 0,  0, -1, -1,  0, -1, 0,  0,  3,  0],
            [ 0,  0,  0,  0,  0, -1, 0, -1,  0,  2]])

Вычисление собственных значений :

>>> L.eigenvals()
{0: 3, 1: 1, 2: 1}

Это очень странно , так как матрица 10 на 10, а не 5 на 5.

Я пытался вычислить нормальную форму Джордана, но не смог этого сделать, так как функция jordan_form выдавала сообщение об ошибке IndexError: list index out of range.

Вычисление характеристического полинома :

>>> s = Symbol('s')
>>> p = (s * eye(10) - L).det()
>>> p
s**10 - 14*s**9 + 77*s**8 - 214*s**7 + 321*s**6 - 256*s**5 + 99*s**4 - 14*s**3

Обратите внимание, что моном низшей степени является кубическим. Это позволяет сделать вывод, что кратность собственного значения 0 равна 3, и, таким образом, график является несвязанным .

Попробуем найти корни характеристического полинома:

>>> solve(p,s)
[0, 0, 0, 1, 2, CRootOf(s**5 - 11*s**4 + 42*s**3 - 66*s**2 + 39*s - 7, 0), CRootOf(s**5 - 11*s**4 + 42*s**3 - 66*s**2 + 39*s - 7, 1), CRootOf(s**5 - 11*s**4 + 42*s**3 - 66*s**2 + 39*s - 7, 2), CRootOf(s**5 - 11*s**4 + 42*s**3 - 66*s**2 + 39*s - 7, 3), CRootOf(s**5 - 11*s**4 + 42*s**3 - 66*s**2 + 39*s - 7, 4)]

Обратите внимание, что на самом деле было найдено только 5 корней (eigenvals также дало только 5 собственных значений). 5 недостающих корней - это корни квинтики s**5 - 11*s**4 + 42*s**3 - 66*s**2 + 39*s - 7.

С 19-го века известно, что не все многочлены степени 5 (или выше) имеют корни, которые можно выразить с помощью арифметических операций и радикалов. Следовательно, мы можем попросить SymPy сделать невозможный . Лучше использовать NumPy для вычисления приблизительных значений 10 собственных значений.

...