在python上用莱布尼兹公式求nxn矩阵的行列式



我试着用python编写排列代码。我正在寻找关于如何在python 3.7 中使用莱布尼兹公式对行列式进行编码的建议

如果你愿意使用numpy,你可以使用numpy.linalg.det()找到行列式

我建议不要使用莱布尼兹公式。这不是很有效。如果必须的话,你可以使用我从这个问题中提取的代码:

def determinant_leibnitz(self):
assert self.dim()[0] == self.dim()[1] # O(1)
dim = self.dim()[0] # O(1)
det,mul = 0,1 # O(1)
for perm in permutations([num for num in range(dim)]):
for i in range(dim):
mul *= self[i,perm[i]] # O(1)
det += perm_parity(perm)*mul # O(n) ?
mul = 1 # O(1)
return det

嵌套函数定义如下:

def perm_parity(lst):
parity = 1
lst = lst[:]
for i in range(0,len(lst) - 1):
if lst[i] != i:
parity *= -1
mn = argmin(lst[i:]) + i
lst[i],lst[mn] = lst[mn],lst[i]
return parity 
def argmin(lst):
return lst.index(min(lst))
def permutations(lst):
if len(lst) <= 1:
return [lst]
templst = []
for i in range(len(lst)):
part = lst[:i] + lst[i+1:]
for j in permutations(part):
templst.append(lst[i:i+1] + j)
return templst

使用Python自己的代码(在C中,但Python描述仍然可用(,只需添加一个非常小的奇偶校验:,就可以在生成排列的同时计算排列奇偶校验

#https://github.com/python/cpython/blob/main/Modules/itertoolsmodule.c
def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n: return
indices = list(range(n))
cycles = list(range(n, n-r, -1))
parity = 0
yield tuple(pool[i] for i in indices[:r]), parity
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
if ((n-i) & 1) == 0: parity = 1 - parity
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
parity, indices[i], indices[-j] = 1 - parity, indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r]), parity
break
else: return
def determinant(mat):
import functools
n = len(mat)
print(list(permutations(range(n))))
def dosign(parity, x): return -x if parity else x
return sum(dosign(parity, functools.reduce(lambda x, y: x * y, (mat[i][sigma[i]] for i in range(n)))) for sigma, parity in permutations(range(n)))
print(determinant([[-2, -1, 2], [2, 1, 4], [-3, 3, -1]]))

对于实际的行列式计算,几乎只有一行:(。

最新更新