【发布时间】:2013-05-12 17:24:09
【问题描述】:
我将编写一些代码来计算方阵 (nxn) 的行列式,使用 Wikipedia's Laplace Expansion 所写的拉普拉斯算法(均值递归算法)。
我已经有了 Matrix 类,其中包括 init、setitem、getitem、repr 和我需要计算行列式的所有东西(包括minor(i,j))。
所以我尝试了下面的代码:
def determinant(self,i=0) # i can be any of the matrix's rows
assert isinstance(self,Matrix)
n,m = self.dim() # Q.dim() returns the size of the matrix Q
assert n == m
if (n,m) == (1,1):
return self[0,0]
det = 0
for j in range(n):
det += ((-1)**(i+j))*(self[i,j])*((self.minor(i,j)).determinant())
return det
正如预期的那样,在每个递归调用中,self 都会变成适当的次要。但是当从递归调用返回时,它不会变回原来的矩阵。
这会在for 循环中引起麻烦(当函数到达(n,m)==(1,1) 时,返回矩阵的这个值,但在for 循环中,self 仍然是一个 1x1 矩阵 - 为什么?)
【问题讨论】:
-
self.minor(i,j)是否真的转换了self? -
是的。你说得对。我会改变它并再次检查。谢谢
-
我建议不要像这样使用
asserts。第一个 (assert isinstance(self, Matrix)) 没有做任何事情 - 它是Matrix上的一个方法,所以你肯定知道self是一个Matrix。第二个可以更好地使用if n != m: raise ValueError("Matrix is not square")之类的东西,因为异常更具体地说明了问题(并且可以更容易地被捕获)。 -
另外,您真的希望用户能够将
i作为参数传入吗?行列式是矩阵的一个属性,与您使用它的行或列无关。所以让用户选择是没有意义的(因为无论他们选择什么结果都是一样的)。