我对 Python 还很陌生,我想知道两者之间有什么区别:
inv(A)
和
A.I
两者都返回一个 Numpy 数组,其中包含矩阵A的逆矩阵。
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))
因此,根据矩阵的形状,getI
要么调用numpy.dual.inv(方阵的乘法逆)或numpy.dual.pinv(Moore-Penrose 伪逆)。
如果您跟踪定义(在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 矩阵。该matrix.I
属性特定于 numpy 矩阵,并返回另一个 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'>
一个属性,likeA.I
在语法上看起来像一个属性,但它实际上调用了一个函数(在本例中为A.getI
)。所以倒数的值没有被存储。每次 Python 求值A.I
时,A.getI()
都会调用函数,并返回函数的结果。
有关属性的更多信息,请参阅属性:由 get/set 方法管理的属性。
根据您的 Python 版本和numpy
, I
(以及T
类似的等)是 a@property
或同一事物的自定义实现。
如果您以前从未见过这种情况,那么您的想法是您可以创建一些看起来像数据属性(也称为“成员变量”)的东西,但每次访问它时都会调用一个 getter 方法。
因此,不是A.I
每次更改都强制重新计算A
,而是每次访问时都强制重新计算A.I
。
当然,这可能不会更好,这取决于您的使用模式;它甚至可能更糟。但是,就像任何其他方法一样,numpy
如果有帮助的话,没有什么可以停止记忆(缓存结果)。
在幕后,getterA.I
是A.getI()
,所以它们是等价的,而且两者都可能等价于inv(A)
。(拥有做同样事情的自由函数foo(A)
和方法在全世界都很普遍。)除了,正如 unutbu 指出的那样,有不止一种方法叫做; 将等同于其中之一,但不一定与您直接导入到主命名空间中的相同。A.foo()
numpy
inv
A.I