Диагонализация символьной матрицы

Мне нужно диагонализовать символическую матрицу с помощью python. В Mathematica это делается легко, но при использовании модуля numpy.linalg возникают проблемы.

Для конкретности рассмотрим матрицу

[[2, x], [x, 3]]

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


person dapias    schedule 09.09.2013    source источник
comment
Что, если вы создадите x = sympy.Symbol('x'), а затем инициализируете пустую матрицу как A = np.array([[2, x], [x, 3]])?   -  person wflynny    schedule 09.09.2013
comment
@Bill Это не удается, поскольку numpy не может безопасно привести тип к тому, что он может обработать.   -  person Hooked    schedule 09.09.2013
comment
Matrix([[2,x],[x,3]]).diagonalize() должно быть достаточно. НЕ используйте для этого numpy, числовые алгоритмы совершенно не подходят для символьных вычислений, даже если вы используете dtype=object.   -  person Krastanov    schedule 10.09.2013
comment
@Krastanov, можете ли вы объяснить мне, почему я получаю две матрицы, используя Matrix([[2,x],[x,3]]).diagonalize()? Второй вариант правильный, а про первый понятия не имею. Спасибо   -  person dapias    schedule 10.09.2013
comment
@dapias смотрите мой ответ.   -  person asmeurer    schedule 10.09.2013


Ответы (2)


Вы можете вычислить его из собственных значений, но на самом деле есть метод, который сделает это за вас, diagonalize

In [13]: M.diagonalize()
Out[13]:
⎛                                        ⎡     __________                       ⎤⎞
⎜                                        ⎢    ╱    2                            ⎥⎟
⎜⎡      -2⋅x                2⋅x       ⎤  ⎢  ╲╱  4⋅x  + 1    5                   ⎥⎟
⎜⎢─────────────────  ─────────────────⎥, ⎢- ───────────── + ─          0        ⎥⎟
⎜⎢   __________         __________    ⎥  ⎢        2         2                   ⎥⎟
⎜⎢  ╱    2             ╱    2         ⎥  ⎢                                      ⎥⎟
⎜⎢╲╱  4⋅x  + 1  - 1  ╲╱  4⋅x  + 1  + 1⎥  ⎢                        __________    ⎥⎟
⎜⎢                                    ⎥  ⎢                       ╱    2         ⎥⎟
⎜⎣        1                  1        ⎦  ⎢                     ╲╱  4⋅x  + 1    5⎥⎟
⎜                                        ⎢         0           ───────────── + ─⎥⎟
⎝                                        ⎣                           2         2⎦⎠

M.diagonalize() возвращает пару матриц (P, D) таких, что M = P*D*P**-1. Если он не может вычислить достаточно собственных значений, либо из-за того, что матрица не диагонализируема, либо из-за того, что solve() не может найти все корни характеристического полинома, он поднимет MatrixError.

См. также этот раздел руководства по SymPy.

person asmeurer    schedule 09.09.2013

Предполагая, что матрица диагонализируема, вы можете получить собственные векторы и собственные значения с помощью

from sympy import *
x = Symbol('x')
M = Matrix([[2,x],[x,3]])
print M.eigenvects()
print M.eigenvals()

Предоставление:

[(-sqrt(4*x**2 + 1)/2 + 5/2, 1, [[-x/(sqrt(4*x**2 + 1)/2 - 1/2)]
[                            1]]), (sqrt(4*x**2 + 1)/2 + 5/2, 1, [[-x/(-sqrt(4*x**2 + 1)/2 - 1/2)]
[                             1]])]
{sqrt(4*x**2 + 1)/2 + 5/2: 1, -sqrt(4*x**2 + 1)/2 + 5/2: 1}

Вам следует ознакомиться с документацией, там есть много других декомпозиций.

Обратите внимание, что не каждую матрицу можно диагонализовать, но вы можете поместить каждую матрицу в нормальную форму Джордана, используя sympy команда .jordan_form.

person Hooked    schedule 09.09.2013
comment
Спасибо Зацепил, а то я уже запутался, почему у нас получилось три компоненты собственного вектора, если матрица 2х2. Предполагается, что собственные векторы не могут иметь большей размерности, чем матрица. Что ты думаешь? - person dapias; 10.09.2013
comment
Вы ссылаетесь на устаревшую версию документации. Замените версию на последнюю в URL-адресе, чтобы получить последнюю версию. - person asmeurer; 10.09.2013
comment
@asmeurer Исправлено, спасибо, я этого не знал. Это относится к серверной части, на которой он работает, т.е. работает ли это для других сайтов? - person Hooked; 10.09.2013
comment
@dapias Из документов: возвращаются три значения. Список троек (собственное число, кратность, базис). Если все, что вас интересует, это диагонализация, ответ asmeurer лучше (но обратите внимание на нормальную форму Джордана!). - person Hooked; 10.09.2013
comment
Нет, это то, что реализовано в документах SymPy. Бэкенд — это просто файлы, размещенные на страницах github. - person asmeurer; 10.09.2013