私はPythonにかなり慣れていないので、次の違いは何だろうと思っています。
inv(A)
と
A.I
どちらも、行列Aの逆行列を含むNumpy配列を返します。
A.I
行列の逆行列を格納する行列クラスから変数にアクセスしているように見えます。ただし、これは、 Aが変更されるたびに、 Aの逆数を再計算する必要があることを意味します(これは私には論理的ではないようです)。
A.I
とnumpy.linalg.inv
同じではありません。
A.I
matrix.getIを呼び出すプロパティです:
def getI(self):
M,N = self.shape
if M == N:
from numpy.dual import inv as func
else:
from numpy.dual import pinv as func
return asmatrix(func(self))
したがって、行列の形状に応じて、 numpy.dual.inv (正方行列の乗法逆行列) またはnumpy.dual.pinv (Moore-Penrose 疑似逆行列) をgetI
呼び出します。
( dual.py 内の) 定義をたどると、 numpy.dual.inv
isnumpy.linalg.inv
とnumpy.dual.pinv
is が見つかります
numpy.linalg.pinv
。
In [69]: s = np.random.random((3,4))
In [70]: t = np.matrix(s)
In [71]: t.I
Out[71]:
matrix([[ 1.09509751, -0.56685735, 0.51704085],
[-1.59777153, 0.2777383 , 1.25579378],
[ 0.81899054, 0.7594223 , -0.82760378],
[ 0.02845906, 0.50418885, -0.2091376 ]])
In [72]: np.linalg.inv(t)
...
LinAlgError: Array must be square
さらに、np.linalg.inv
numpy 配列に適用する (および numpy 配列を返す) ことも、numpy マトリックスに適用することもできます。プロパティは numpy 行列に固有であり、matrix.I
別の numpy 行列を返します。
In [60]: x = np.random.random((3,3))
In [62]: y = np.matrix(x)
In [64]: type(y.I)
Out[64]: <class 'numpy.matrixlib.defmatrix.matrix'>
In [65]: type(np.linalg.inv(x))
Out[65]: <type 'numpy.ndarray'>
のようなプロパティは、A.I
構文的には属性のように見えますが、実際には関数 (この場合はA.getI
) を呼び出します。そのため、逆数の値は保存されていません。Python が を評価するたびA.I
に、関数A.getI()
が呼び出され、関数の結果が返されます。
プロパティの詳細については、プロパティ: get/set メソッドによって管理される属性を参照してください。
Pythonのバージョンに応じて、、numpy
(I
および同様T
になど)は、、@property
または同じもののカスタム実装のいずれかです。
これをこれまでに見たことがない場合は、データ属性(別名「メンバー変数」)のようなものを作成できますが、アクセスするたびにgetterメソッドを呼び出します。
したがって、A.I
変更するたびに再計算する必要A
はなく、にアクセスするたびに再計算する必要がありますA.I
。
もちろん、使用パターンによっては、これ以上良くない場合もあります。さらに悪いかもしれません。ただし、他の方法と同様に、numpy
メモ化(結果のキャッシュ)が役立つ場合は、それを止めることはできません。
裏では、のゲッターA.I
はA.getI()
であるため、これらは同等であり、両方ともおそらくと同等inv(A)
です。(同じことを行う無料の関数foo(A)
とメソッドを持つA.foo()
ことは、至る所でかなり一般的numpy
です。)unutbuが指摘するように、inv
;と呼ばれる複数のメソッドがあることを除いて。A.I
それらの1つと同等ですが、メインの名前空間に直接インポートしたものと必ずしも同じではありません。