如果矩阵是可逆的,则辅因子与逆有关:
def matrix_cofactor(matrix):
return np.linalg.inv(matrix).T * np.linalg.det(matrix)
这样可以大大提高速度(对于50x50矩阵,约为1000倍)。主要原因是根本的:这是一种O(n^3)
算法,而基于次要成绩的算法是O(n^5)
。
这也可能意味着对于不可逆矩阵,也有一些聪明的方法可以计算辅因子(即,不使用上面使用的数学公式,而是使用其他等效定义)。
如果您坚持使用基于det的方法,则可以执行以下操作:
大部分时间似乎都在里面度过det
。(检查line_profiler可以自己找到。)您可以尝试通过将Numpy与Intel MKL链接来加快这一部分的速度,但是除此之外,您还可以做很多事情。
您可以像这样加快代码的另一部分:
minor = np.zeros([nrows-1, ncols-1])
for row in xrange(nrows):
for col in xrange(ncols):
minor[:row,:col] = matrix[:row,:col]
minor[row:,:col] = matrix[row+1:,:col]
minor[:row,col:] = matrix[:row,col+1:]
minor[row:,col:] = matrix[row+1:,col+1:]
...
根据矩阵的大小,这将获得大约10-50%的总运行时间。原始代码具有Pythonrange
和列表操作,这比直接切片索引慢。您也可以尝试变得更聪明,只复制实际更改的未成年人的部分 —但是,在完成上述更改之后,内部已花费了将近100%的时间,numpy.linalg.det
因此无法进一步优化其他部分很有道理