我对 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.invisnumpy.linalg.inv和numpy.dual.pinvis 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()numpyinvA.I