Подтвердить что ты не робот

Выясните, является ли матрица положительно определенной с numpy

Мне нужно выяснить, соответствует ли матрица положительно определенному. Моя матрица имеет матрицу. Я ожидал найти какой-либо связанный метод в библиотеке numpy, но без успеха. Я ценю любую помощь.

4b9b3361

Ответ 1

Вы также можете проверить, положительны ли все собственные значения матрицы, если матрица положительно определена:

import numpy as np

def is_pos_def(x):
    return np.all(np.linalg.eigvals(x) > 0)

Ответ 2

Вы можете попробовать вычислить разложение Cholesky (numpy.linalg.cholesky). Это повысит LinAlgError, если матрица не будет положительно определенной.

Ответ 3

Я не знаю, почему решение NPE настолько недооценено. Это лучший способ сделать это. Я нашел в Wkipedia, что сложность кубическая.

Кроме того, там сказано, что он более численно устойчив, чем разложение Lu. И разложение Lu более устойчиво, чем метод нахождения всех собственных значений.

И это очень элегантное решение, потому что это факт:

Матрица имеет разложение Холецкого тогда и только тогда, когда оно симметрично положительно.

Так почему бы не использовать математику? Возможно, некоторые люди боятся повышения исключения, но это тоже факт, очень полезно программировать с исключениями.

Ответ 4

Кажется, что во всех вышеперечисленных ответах есть небольшая путаница (по крайней мере, по поводу вопроса).

Для реальных матриц тесты на положительные собственные значения и положительные старшие члены в np.linalg.cholesky применяются только в том случае, если матрица симметрична. Поэтому сначала нужно проверить, симметрична ли матрица, а затем применить один из этих методов (положительные собственные значения или разложение Холецкого).

Например:

import numpy as np

#A nonsymmetric matrix
A = np.array([[9,7],[6,14]])

#check that all eigenvalues are positive:
np.all(np.linalg.eigvals(A) > 0)

#take a 'Cholesky' decomposition:
chol_A = np.linalg.cholesky(A)

Матрица A не симметрична, но собственные значения положительны, а Numpy возвращает неправильное определение Холески. Вы можете проверить, что:

chol_A.dot(chol_A.T)

отличается от A.

Вы также можете проверить, что все вышеперечисленные функции python будут проверять положительный результат на "положительную определенность". Это потенциально может быть серьезной проблемой, если вы пытались использовать декомпозицию Cholesky для вычисления обратного, поскольку:

>np.linalg.inv(A)
array([[ 0.16666667, -0.08333333],
   [-0.07142857,  0.10714286]])

>np.linalg.inv(chol_A.T).dot(np.linalg.inv(chol_A))
array([[ 0.15555556, -0.06666667],
   [-0.06666667,  0.1       ]])

разные.

В заключение я бы предложил добавить строку к любой из вышеперечисленных функций, чтобы проверить, симметрична ли матрица, например:

def is_pos_def(A):
    if np.array_equal(A, A.T):
        try:
            np.linalg.cholesky(A)
            return True
        except LinAlgError:
            return False
    else:
        return False

Вы можете заменить np.array_equal (A, A.T) в приведенной выше функции для np.allclose(A, A.T), чтобы избежать различий, связанных с ошибками с плавающей запятой.

Ответ 5

Чтобы проиллюстрировать ответ @NPE на некоторый готовый к использованию код:

импортировать numpy как np

def is_pd(K):
    try:
        np.linalg.cholesky(K)
        return 1 
    except np.linalg.linalg.LinAlgError as err:
        if 'Matrix is not positive definite' in err.message:
            return 0
        else:
    raise 

Ответ 6

Для вещественной матрицы $A $имеем $x ^ TAx =\frac {1} {2} (x ^ T (A + A ^ T) x) $, а $A + A ^ T $- симметричная вещественная матрица. Таким образом, $A $положительно определен, если $A + A ^ T $положительно определена, если все собственные значения $A + A ^ T $положительны.

import numpy as np

def is_pos_def(A):
    M = np.matrix(A)
    return np.all(np.linalg.eigvals(M+M.transpose()) > 0)