Проверяет ли scipy.linalg.inv диагональ матрицы? - PullRequest
3 голосов
/ 28 июня 2019

Получение обратной диагональной матрицы очень просто и не требует сложных методов. scipy.linalg.inv проверяет, является ли матрица диагональной, прежде чем применять более сложные методы, или мне нужно проверить это самостоятельно?

Ответы [ 2 ]

2 голосов
/ 28 июня 2019

Как вы можете видеть код Github scipy.linalg.inv, функция inv первые вызовы

getrf, getri, getri_lwork = get_lapack_funcs(('getrf', 'getri','getri_lwork'),

Затем функция getrf выполняет задание для разложения LU искоро.Теперь нам нужно выяснить, как функция getrf дает разложение LU.Потому что, если он проверяет диагональ, прежде чем обрабатывать входную матрицу, то нет необходимости проверять ее самостоятельно.

Функция getrf получается путем вызова _get_funcs, но я не могу идти дальше (_get_funcs вызывается со следующими аргументами _get_funcs(names, arrays, dtype, "LAPACK", _flapack, _clapack, "flapack", "clapack", _lapack_alias)).

Я предлагаю вам провести эксперимент с большой диагональной матрицей, чтобы сравнить время, отведенное для плевания выхода с linalg и инверсией вручную.


Обновление (автор вопроса):

import numpy as np
from scipy.linalg import inv
a = np.diag(np.random.random(19999))
b = a.copy()
np.fill_diagonal(a, 1/a.diagonal())
c = inv(b)

даже не требует инструмента измерения времени: очень очевидно, что inv намного медленнее ... (что удивительно разочаровывает).

1 голос
/ 28 июня 2019

Пожалуйста, проверьте: scipy.linalg.inv Если вы попытаетесь использовать scipy.linalg.inv, за исключением случаев, когда он вызывает LinAlgError, когда матрица a является единственной.Определитель для особой матрицы это ноль.

try:
    # your code that will (maybe) throw  scipy.linalg.inv(your matrix)

except np.linalg.LinAlgError as err:
    # It shows your matrix is singular
    # Its determinant of a matrix is equal to zero
    # The matrix does not have an inverse.
    # You can conclude if the matrix is diagonal or not

Если определитель матрицы равен нулю:

Матрица меньше полного ранга.Матрица единственного числа.Матрица не имеет обратной.

Как вручную:

def is_diagonal(matrix):
    #create a dummy matrix
    dummy_matrix = np.ones(matrix.shape, dtype=np.uint8)
    # Fill the diagonal of dummy matrix with 0.
    np.fill_diagonal(dummy_matrix, 0)

    return np.count_nonzero(np.multiply(dummy_matrix, matrix)) == 0

diagonal_matrix = np.array([[3, 0, 0],
                            [0, 7, 0],
                            [0, 0, 4]])
print is_diagonal(diagonal_matrix)
>>> True

random_matrix = np.array([[3, 8, 0],
                          [1, 7, 8],
                          [5, 0, 4]])
print is_diagonal(random_matrix)
>>> False

scipy.sparse.dia_matrix.diagonal возвращает k-ю диагональ матрицы.

from scipy.sparse import csr_matrix
A = csr_matrix([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
A.diagonal()
array([1, 0, 5])
A.diagonal(k=1)
array([2, 3])

Кроме того, из scipy.linalg import block_diag создает диагональную матрицу, если входные массивы квадратные, поэтому, если они не квадратные, она не может создать диагональную матрицу.

Пожалуйста, учтите, что в Jupyter вы можете узнать сложность времени.% timeit yourfunctionname

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...