查找 n x n 矩阵行列式的程序不起作用
Program to find determinant of a n x n matrix not working
当我给出一个 3X3 矩阵作为输入时,returns 行的索引错误:m[0][0]*m[1][1]-m[0][1]*m [1][0]
import copy
def matrixdeterminant(m):
if len(m)==1:
return m[0]
elif len(m)==2:
return m[0][0]*m[1][1]-m[0][1]*m[1][0]
else:
matrixdeterminantlist=copy.deepcopy(m)
determinantlist=[]
m.pop(0)
for i in range(len(matrixdeterminantlist[0])):
for j in range(len(m)):
m[j].pop(i)
determinantlist.append(matrixdeterminantlist[0][i]*matrixdeterminant(m)*(-1)**(i+2))
m=copy.deepcopy(matrixdeterminantlist)
return sum(determinantlist)
我能发现的第一个问题:对于 len(m) == 1
.
的情况,您写的是 return m[0]
而不是 return m[0][0]
如果 m
是一个 1x1 矩阵,那么 m
看起来像 [[x]]
,而你想要 return x
,而不是 [x]
, 所以你必须 return m[0][0]
, 而不是 m[0]
.
代码中的另一个重要问题是从 m
弹出元素然后尝试从其副本恢复 m
的方式。这太复杂了,你在循环中错误地恢复了 m
,所以在某些时候 m
的维度都被搞砸了。我建议完全避免使用 .pop
,而是使用 list comprehensions.
构建子矩阵
这是一个简化版本:
def matrixdeterminant(m):
if len(m)==1:
return m[0][0]
elif len(m)==2:
return m[0][0]*m[1][1]-m[0][1]*m[1][0]
else:
determinantlist=[]
sign = 1
for i in range(len(m)):
submatrix = [row[1:] for j,row in enumerate(m) if j != i]
minor = matrixdeterminant(submatrix)
determinantlist.append(sign * m[i][0] * minor)
sign *= -1
return sum(determinantlist)
这是另一个版本:
from itertools import cycle
def matdet(m):
if len(m) == 1:
return m[0][0]
else:
return sum(
s * mj[0] * matdet([row[1:] for i,row in enumerate(m) if i != j])
for s,(j,mj) in zip(cycle([1,-1]), enumerate(m))
)
一旦它生成数值而不是错误消息,我强烈建议您通过比较它在大随机矩阵上的输出与标准 python 模块的矩阵行列式函数的输出来测试行列式函数例如 numpy
或 sympy
或 scipy
:
当我给出一个 3X3 矩阵作为输入时,returns 行的索引错误:m[0][0]*m[1][1]-m[0][1]*m [1][0]
import copy
def matrixdeterminant(m):
if len(m)==1:
return m[0]
elif len(m)==2:
return m[0][0]*m[1][1]-m[0][1]*m[1][0]
else:
matrixdeterminantlist=copy.deepcopy(m)
determinantlist=[]
m.pop(0)
for i in range(len(matrixdeterminantlist[0])):
for j in range(len(m)):
m[j].pop(i)
determinantlist.append(matrixdeterminantlist[0][i]*matrixdeterminant(m)*(-1)**(i+2))
m=copy.deepcopy(matrixdeterminantlist)
return sum(determinantlist)
我能发现的第一个问题:对于 len(m) == 1
.
return m[0]
而不是 return m[0][0]
如果 m
是一个 1x1 矩阵,那么 m
看起来像 [[x]]
,而你想要 return x
,而不是 [x]
, 所以你必须 return m[0][0]
, 而不是 m[0]
.
代码中的另一个重要问题是从 m
弹出元素然后尝试从其副本恢复 m
的方式。这太复杂了,你在循环中错误地恢复了 m
,所以在某些时候 m
的维度都被搞砸了。我建议完全避免使用 .pop
,而是使用 list comprehensions.
这是一个简化版本:
def matrixdeterminant(m):
if len(m)==1:
return m[0][0]
elif len(m)==2:
return m[0][0]*m[1][1]-m[0][1]*m[1][0]
else:
determinantlist=[]
sign = 1
for i in range(len(m)):
submatrix = [row[1:] for j,row in enumerate(m) if j != i]
minor = matrixdeterminant(submatrix)
determinantlist.append(sign * m[i][0] * minor)
sign *= -1
return sum(determinantlist)
这是另一个版本:
from itertools import cycle
def matdet(m):
if len(m) == 1:
return m[0][0]
else:
return sum(
s * mj[0] * matdet([row[1:] for i,row in enumerate(m) if i != j])
for s,(j,mj) in zip(cycle([1,-1]), enumerate(m))
)
一旦它生成数值而不是错误消息,我强烈建议您通过比较它在大随机矩阵上的输出与标准 python 模块的矩阵行列式函数的输出来测试行列式函数例如 numpy
或 sympy
或 scipy
: