web-dev-qa-db-ja.com

左行列除算とNumpySolve

\演算子を含むコードをMatlab(Octave)からPythonに変換しようとしています。サンプルコード

B = [2;4]
b = [4;4]
B \ b

これは機能し、答えとして1.2を生成します。このWebページの使用

http://mathesaurus.sourceforge.net/matlab-numpy.html

私はそれを次のように翻訳しました:

import numpy as np
import numpy.linalg as lin
B = np.array([[2],[4]])
b = np.array([[4],[4]])
print lin.solve(B,b)

これは私にエラーを与えました:

numpy.linalg.linalg.LinAlgError: Array must be square

Matlab \がBの非正方行列で機能するのはなぜですか?

これに対する解決策はありますか?

15
BBDynSys

から MathWorksドキュメント 左行列除算の場合:

Aがm〜 = nのm行n列の行列で、Bがm個の成分を持つ列ベクトル、またはそのような列がいくつかある行列の場合、X = A\Bは最小二乗法での解です-または過剰決定系の連立方程式AX = B。言い換えると、Xはノルム(A * X-B)、つまりベクトルAX-Bの長さを最小化します。

Numpyの同等物は np.linalg.lstsq

In [15]: B = np.array([[2],[4]])

In [16]: b = np.array([[4],[4]])

In [18]: x,resid,rank,s = np.linalg.lstsq(B,b)

In [19]: x
Out[19]: array([[ 1.2]])
15
unutbu

\演算子を使用すると、Matlabは、関係する行列の形状に応じて、実際にはさまざまな操作を実行します(詳細については、 ここ を参照してください)。あなたの例では、Matlabは、正方行列で発生するように線形方程式を直接解くのではなく、最小二乗解を返します。 numpyで同じ動作を得るには、次のようにします。

import numpy as np
import numpy.linalg as lin
B = np.array([[2],[4]])
b = np.array([[4],[4]])
print np.linalg.lstsq(B,b)[0]

これにより、Matlabと同じソリューションが得られるはずです。

8
talonmies

左逆を形成することができます:

_import numpy as np
import numpy.linalg as lin
B = np.array([[2],[4]])
b = np.array([[4],[4]])

B_linv = lin.solve(B.T.dot(B), B.T)
c = B_linv.dot(b)
print('c\n', c)
_

結果:

_c
 [[ 1.2]]
_

実際には、次のように、逆関数を形成せずに、ソルバーを1回実行するだけで済みます。

_c = lin.solve(B.T.dot(B), B.T.dot(b))
print('c\n', c)
_

結果:

_c
 [[ 1.2]]
_

.... 従来通り

どうして?理由:

我々は持っています:

enter image description here

_B.T_を掛けると、次のようになります。

enter image description here

現在、B.T.dot(B)は正方形で、フルランクであり、逆行列があります。したがって、B.T.dot(B)の逆数を掛けるか、上記のようにソルバーを使用してcを取得できます。

2
Hugh Perkins