Использование scipy.linalg.solve с матрицей коэффициентов симметрии c (предположим, что a = sym) - PullRequest
2 голосов
/ 10 января 2020

Я пытаюсь решить систему линейных уравнений A * x = b для неизвестного x, используя функцию scipy linalg.solve . Вот пример, который отлично работает:

import numpy as np
import scipy.linalg as linalg

A = np.array([[ 0.18666667, 0.06222222, -0.01777778],
              [ 0.01777778, 0.18666667,  0.01777778],
              [-0.01777778, 0.06222222,  0.18666667]])
b = np.array([0.26666667, -0.26666667, -0.4])
x = linalg.solve(A, b, assume_a='gen')

В результате получается x = [1.77194417, -1.4555256, -1.48892533], что является правильным решением. Это может быть проверено путем вычисления A.dot(x), что приводит к [0.26666667, -0.26666667, -0.4]. Поскольку это то же самое, что и b, решение является правильным.

Однако матрица коэффициентов A является симметричной, то есть значения выше и ниже главной диагонали одинаковы. Если я правильно понимаю документацию, для более эффективного решения такой проблемы функция solve позволяет установить аргумент assume_a='sym'. К сожалению, использование следующего кода (с учетом тех же A и b) приводит к неправильному решению:

x = linalg.solve(A, b, assume_a='sym')

Это приводит к x = [1.88811181, -1.88811181, -1.78321672], что отличается от решения выше. Вычисление A.dot(x) приводит к [0.26666667, -0.35058274, -0.48391607]. Поскольку это отличается от b, решение кажется неправильным.

Мне интересно, есть ли какие-либо проблемы с моим кодом или мое понимание симметричных c матриц или ожидаемый результат просто неправильно !? Может быть, матрица должна удовлетворять дополнительным ограничениям для использования вместе с assume_a='sym'?

Я ценю ваши ответы. Заранее спасибо!

1 Ответ

0 голосов
/ 10 января 2020

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

Несимметричный c A

import numpy as np
import scipy.linalg as linalg

A = np.array([[ 0.18666667, 0.06222222, -0.01777778],
              [ 0.01777778, 0.18666667,  0.01777778],
              [-0.01777778, 0.06222222,  0.18666667]])
b = np.array([0.26666667, -0.26666667, -0.4])
x = linalg.solve(A, b, assume_a='gen')
np.allclose(A @ x,b)

Out:

True

Что показывает, что решатель работает хорошо.

Симметрия c A

# use you upper triangular A to get a symmetric matrix
A_symm = (np.triu(A) + np.triu(A).T -np.diag(A.diagonal()))

# solve the equations
x = linalg.solve(A_symm, b, assume_a='sym')
np.allclose(A_symm @ x,b)

Out:

True

It все еще работает.

Если вы передадите решающему несимметричную c матрицу A, а затем укажите assume_a = 'sym', то решатель будет использовать только верхнюю три angular матрицу из A, см. ниже:

x = linalg.solve(A, b, assume_a='sym')
np.allclose(A @ x,b),x

Out:

(False, массив ([1.88811181, -1.88811181, -1.78321672]))

Результат показывает, что солвер работает "неправильно", но результат x совпадает с результатом linalg.solve(A_symm, b, assume_a='sym')

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