Python NumPy Linalg Solver: неправильный ответ - PullRequest
1 голос
/ 17 октября 2019

У меня проблемы с np.linalg.solve (и я тоже пробовал с scipy), но для некоторой линейной системы ответ неверен. Пример системы, которая генерируется в моей программе:

Матрица A:

[[7.03894408e + 00 1.34629120e + 10 2.00000000e + 10 1.14564392e + 10 1.82002747e + 10 1.73205081e + 10] [1.34629120e + 10 7.03894408e + 00 1.82002747e + 10 2.000000ee + 10 2.23606798e + 10 2.07665597e + 10] [2.00000000e + 10 1.82002747e + 10 7.03894408e + 00 1.67705098e10 1.67705098e + 10 2.23606798e + 10] [1.14564392e + 10 2.00000000e + 10 1.67705098e + 10 7.03894408e + 00 1.73205081e + 10 1.34629120e + 10] [1.82002747e + 10 2.23606798e + 10 1.67705098e + 10 1.67705098e + 10 1.67705098e + 10e + 10 7.03894408e + 00 1.95256242e + 10] [1.73205081e + 10 2.07665597e + 10 2.23606798e + 10 1.34629120e + 10 1.95256242e + 10 7.03894408e + 00]]

Вектор b:

[5.49316406e + 42 9.62786249e + 22 5.49316406e + 42 8.66507624e + 23 1.38770661e + 25 7.66220239e + 24]

Вектор x из x = np.linalg.solve (A, b)

[- 4,06597524e + 32 2,80218361e + 32 -2,68178425e + 32 2,82035894e + 32 1,75304606e + 32 3,82470510e + 31]

A * x от np.dot (Aх) это должно быть равно b

[5.49316406e + 42 9.28455029e + 26 5.49316406e + 42 6.18970020e + 26 -6.18970020e + 26 -1.23794004e + 27]

для некоторых систем больше номеровэлементы равны в обоих векторах b и A * x

некоторые проверки:

условное число: np.linalg.cond (A) = 11.283698804140434

определитель A: np.linalg.det (A) = -1.146617874355366e + 62

норма A: np.linalg.norm (A) = 99310120330.20604

норма inv (A): np. linalg.norm (np.linalg.inv (A)) = 1.6365102872452848e-10

Некоторые системы работают нормально, и решатель дает правильный ответ.

Спасибо.

1 Ответ

2 голосов
/ 17 октября 2019

Вы получите не неправильный ответ. Действительно, сравнивая исходную b с восстановленной br ...

A
# array([[7.03894408e+00, 1.34629120e+10, 2.00000000e+10, 1.14564392e+10,
#         1.82002747e+10, 1.73205081e+10],
#        [1.34629120e+10, 7.03894408e+00, 1.82002747e+10, 2.00000000e+10,
#         2.23606798e+10, 2.07665597e+10],
#        [2.00000000e+10, 1.82002747e+10, 7.03894408e+00, 1.67705098e+10,
#         1.67705098e+10, 2.23606798e+10],
#        [1.14564392e+10, 2.00000000e+10, 1.67705098e+10, 7.03894408e+00,
#         1.73205081e+10, 1.34629120e+10],
#        [1.82002747e+10, 2.23606798e+10, 1.67705098e+10, 1.73205081e+10,
#         7.03894408e+00, 1.95256242e+10],
#        [1.73205081e+10, 2.07665597e+10, 2.23606798e+10, 1.34629120e+10,
#         1.95256242e+10, 7.03894408e+00]])
b
# array([5.49316406e+42, 9.62786249e+22, 5.49316406e+42, 8.66507624e+23,
#        1.38770661e+25, 7.66220239e+24])

br = A@np.linalg.solve(A,b)

abserr = np.sqrt((br-b)@(br-b))
relerr = abserr / np.sqrt(b@b) 
relerr
# 4.914258035606803e-16

... мы получаем относительную ошибку, примерно в 2,2 раза превышающую точность станка ...

np.finfo(float).eps
# 2.220446049250313e-16

... что на самом деле довольно точно.

...