質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Q&A

解決済

1回答

2531閲覧

numpy.linalg.solve でのエラー対処法について

hayatoU

総合スコア14

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

0グッド

0クリップ

投稿2017/09/05 03:20

python

1import numpy as np 2A = np.array( 3[[147, 420, 21] 4 [420, 1202, 60] 5 [21, 60, 3]]) 6b = np.array([-9443, -27060, -1349]) 7d = np.linalg.det(A) 8x = np.linalg.solve(A, b)

Aの行列式は本来0ですが,
d = 1.30562227696e-13
と出力されてしまいます.おかげでsolveはnp.linalg.linalg.LinAlgErrorをraiseしてくれず,とんちんかんな答えを出します.どうしたらよいでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

値が1.30562227696e-13ととんでもなく0に近いので、どこかで計算誤差が生じています。

numpyのリファレンスを見てみましょう。
numpy.linalg.detには、次のような記述があります。

See also:
slogdet Another way to representing the determinant, more suitable for large matrices where underflow/overflow may occur.

このアドバイスに従って、numpy.linalg.slogdetを使ってみます。

Python

1>>> np.linalg.slogdet(A) 2(1.0, -30.984227930851471)

リファレンスを見ると、この結果の捉え方がわかります。

In all cases, the determinant is equal to sign * np.exp(logdet).

つまり、行列式はnumpy.e**-31と計算されたわけです。
slogdetの力を借りても、正しく計算することは出来ませんでした。


でも、悲観する必要はありません。
解が不定であることを確かめるためには、階数を計算すればよいです。

Python

1>>> np.linalg.matrix_rank(A) 22

solveを呼び出す前に階数を計算して分岐させましょう。


あるいは、次のような強引な方法も案外柔軟かもしれません。

Python

1try: 2 if np.linalg.matrix_rank(A) < A.shape[0]: 3 raise np.linalg.linalg.LinAlgError 4 else: 5 np.linalg.solve(A, b) 6except: 7 print('解は不定です')

投稿2017/09/06 17:55

編集2017/09/07 08:25
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayatoU

2017/09/08 15:54

rankのことを忘れていました。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問