Python 求所有可逆方阵
我想写一个函数,其中给定两个整数“n”和“p”,它生成所有n阶可逆矩阵,其中元素来自{0,1,…,p-1}。 我有以下代码:Python 求所有可逆方阵,python,numpy,matrix,algebra,Python,Numpy,Matrix,Algebra,我想写一个函数,其中给定两个整数“n”和“p”,它生成所有n阶可逆矩阵,其中元素来自{0,1,…,p-1}。 我有以下代码: import itertools import numpy as np def invertible_matrices(n, p): invertibleMatrices = set() # generates all the possible matrices x = [y for y in range(p)] a = [j for
import itertools
import numpy as np
def invertible_matrices(n, p):
invertibleMatrices = set()
# generates all the possible matrices
x = [y for y in range(p)]
a = [j for j in itertools.product(x, repeat=n)]
b = {k for k in itertools.product(a, repeat=n)}
for each in b:
if np.linalg.det(each) != 0:
invertibleMatrices.add(each)
return invertibleMatrices
对于n=2
和p=2
来说效果很好,但是对于n=2
和p=3
我得到50
,而答案是48
。
任何帮助都将不胜感激
p、 s:如果你熟悉群论,我想找到(有限域上p元素的一般线性群)的所有元素。我想你想要的是行列式模p(它是GL(n,p)上下文中的行列式,即有限域上p元素的行列式) 注:+1是为了避免小数值错误的缠绕。使用inspect_matrix()进行调试,使用集合理解来确定所有可逆矩阵,使用get_Inversible_matrix()来获得行列式为1的矩阵:
import itertools
import numpy as np
def inspect_matrix(n, p):
"""Examine a single, square matrix."""
a = list(itertools.product(list(range(p)), repeat=n))
matrices = {k
for k in itertools.product(a, repeat=n)
}
matrix = next(iter(matrices)) # Inspect one of the matrices
determinant = np.linalg.det(matrix)
print(f"{matrix = }\n{determinant = }")
print(f"inverse = {(inverse:=np.linalg.inv(matrix))}") if determinant != 0.0 else print("Matrix is not invertible")
return inverse
def get_invertible_matrices(n, p):
"""Generates all the possible matrices."""
a = list(itertools.product(list(range(p)), repeat=n))
invertible_matrices = {k
for k in itertools.product(a, repeat=n)
if not np.isclose((np.linalg.det(k) + 1) % p, 1)
}
print(f"{len(invertible_matrices) = }")
return invertible_matrices
def get_determinant_1_matrices(n, p):
"""Generates all the square matrices with determinant 1."""
a = list(itertools.product(list(range(p)), repeat=n))
if p==2:
det_1_matrices = {k
for k in itertools.product(a, repeat=n)
if np.isclose((np.linalg.det(k))%p,1)
}
else:
det_1_matrices = {k
for k in itertools.product(a, repeat=n)
if np.isclose((np.linalg.det(k)+1)%p,2)
}
print(f"{len(det_1_matrices) = }")
return det_1_matrices
def main():
print(get_invertible_matrices(n=2, p=2))
print(get_invertible_matrices(n=2, p=3))
print(get_determinant_1_matrices(n=2, p=2))
print(get_determinant_1_matrices(n=2, p=3))
if __name__ == '__main__':
main()
返回:
len(invertible_matrices) = 6
{((1, 1), (0, 1)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((0, 1), (1, 0)), ((0, 1), (1, 1)), ((1, 1), (1, 0))}
len(invertible_matrices) = 48
{((1, 0), (0, 1)), ((1, 2), (0, 2)), ((2, 1), (1, 0)), ((0, 2), (2, 0)), ((0, 1), (2, 0)), ((1, 1), (1, 0)), ((2, 1), (1, 1)), ((2, 2), (2, 0)), ((1, 1), (2, 1)), ((1, 2), (1, 0)), ((2, 1), (2, 2)), ((2, 0), (0, 2)), ((1, 2), (1, 1)), ((2, 2), (0, 2)), ((1, 0), (0, 2)), ((1, 1), (1, 2)), ((1, 2), (2, 2)), ((2, 1), (0, 1)), ((1, 1), (0, 1)), ((0, 2), (1, 0)), ((0, 1), (1, 0)), ((2, 0), (2, 1)), ((0, 2), (2, 1)), ((2, 2), (1, 0)), ((0, 1), (2, 1)), ((1, 2), (0, 1)), ((0, 2), (1, 1)), ((2, 0), (1, 1)), ((0, 1), (1, 1)), ((2, 2), (2, 1)), ((2, 0), (2, 2)), ((0, 2), (2, 2)), ((2, 1), (2, 0)), ((0, 1), (2, 2)), ((1, 0), (2, 1)), ((1, 0), (1, 1)), ((1, 1), (2, 0)), ((2, 0), (1, 2)), ((0, 2), (1, 2)), ((0, 1), (1, 2)), ((1, 0), (2, 2)), ((2, 0), (0, 1)), ((1, 2), (2, 0)), ((2, 2), (1, 2)), ((2, 1), (0, 2)), ((1, 0), (1, 2)), ((2, 2), (0, 1)), ((1, 1), (0, 2))}
len(det_1_matrices) = 6
{((0, 1), (1, 1)), ((0, 1), (1, 0)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((1, 1), (0, 1)), ((1, 1), (1, 0))}
len(det_1_matrices) = 24
{((2, 2), (0, 2)), ((0, 2), (1, 2)), ((1, 1), (0, 1)), ((1, 2), (2, 2)), ((2, 1), (2, 0)), ((1, 0), (0, 1)), ((2, 0), (2, 2)), ((2, 1), (1, 1)), ((1, 1), (2, 0)), ((1, 0), (2, 1)), ((1, 2), (0, 1)), ((1, 2), (1, 0)), ((2, 0), (0, 2)), ((1, 0), (1, 1)), ((1, 1), (1, 2)), ((0, 2), (1, 0)), ((0, 1), (2, 2)), ((0, 2), (1, 1)), ((0, 1), (2, 1)), ((2, 0), (1, 2)), ((0, 1), (2, 0)), ((2, 2), (2, 1)), ((2, 2), (1, 0)), ((2, 1), (0, 2))}
整整一学期我都没有意识到这一点,我觉得自己很愚蠢。非常感谢。如果我理解正确的话——这是因为GL(n,p)中的“可逆”表示“在有限域上具有p个元素的可逆”,而“det!=0”表示“在R^n上可逆”(我已经编辑以解释这一点,如果我弄错了,请还原或重新编辑)@ItamarMushkin我认为更正确的说法是(实际的)det是来自有限域的矩阵元素中的多项式。因此,从技术上讲,det只能取0和p-1之间的值。或者更简洁地说,det模p是有限域中的det(其余的都是隐式的)。为什么我们需要
x=[y代表范围(p)]
?在itertools.product(list(range(p)),repeat=n)中使用a=[j代表j会不会起作用?
?非常感谢。我对numpy非常陌生,我知道np。isclose(a,b)
用于比较两个矩阵,但我不明白它在这里是如何工作的?如果我想将条件从“可逆矩阵”更改为“行列式等于1的矩阵”我应该如何改变你对集合的理解?@ladypary我重新编写了代码,这样你就可以更容易地得到行列式==1或可逆矩阵,只需更新你在新的主函数中的调用。我修复了它为“.”生成所有带有行列式1的方阵。“@ladypary干得好!我在顶部添加了一个辅助函数,inspect\u matrix(),可用于一次测试一个矩阵。
len(invertible_matrices) = 6
{((1, 1), (0, 1)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((0, 1), (1, 0)), ((0, 1), (1, 1)), ((1, 1), (1, 0))}
len(invertible_matrices) = 48
{((1, 0), (0, 1)), ((1, 2), (0, 2)), ((2, 1), (1, 0)), ((0, 2), (2, 0)), ((0, 1), (2, 0)), ((1, 1), (1, 0)), ((2, 1), (1, 1)), ((2, 2), (2, 0)), ((1, 1), (2, 1)), ((1, 2), (1, 0)), ((2, 1), (2, 2)), ((2, 0), (0, 2)), ((1, 2), (1, 1)), ((2, 2), (0, 2)), ((1, 0), (0, 2)), ((1, 1), (1, 2)), ((1, 2), (2, 2)), ((2, 1), (0, 1)), ((1, 1), (0, 1)), ((0, 2), (1, 0)), ((0, 1), (1, 0)), ((2, 0), (2, 1)), ((0, 2), (2, 1)), ((2, 2), (1, 0)), ((0, 1), (2, 1)), ((1, 2), (0, 1)), ((0, 2), (1, 1)), ((2, 0), (1, 1)), ((0, 1), (1, 1)), ((2, 2), (2, 1)), ((2, 0), (2, 2)), ((0, 2), (2, 2)), ((2, 1), (2, 0)), ((0, 1), (2, 2)), ((1, 0), (2, 1)), ((1, 0), (1, 1)), ((1, 1), (2, 0)), ((2, 0), (1, 2)), ((0, 2), (1, 2)), ((0, 1), (1, 2)), ((1, 0), (2, 2)), ((2, 0), (0, 1)), ((1, 2), (2, 0)), ((2, 2), (1, 2)), ((2, 1), (0, 2)), ((1, 0), (1, 2)), ((2, 2), (0, 1)), ((1, 1), (0, 2))}
len(det_1_matrices) = 6
{((0, 1), (1, 1)), ((0, 1), (1, 0)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((1, 1), (0, 1)), ((1, 1), (1, 0))}
len(det_1_matrices) = 24
{((2, 2), (0, 2)), ((0, 2), (1, 2)), ((1, 1), (0, 1)), ((1, 2), (2, 2)), ((2, 1), (2, 0)), ((1, 0), (0, 1)), ((2, 0), (2, 2)), ((2, 1), (1, 1)), ((1, 1), (2, 0)), ((1, 0), (2, 1)), ((1, 2), (0, 1)), ((1, 2), (1, 0)), ((2, 0), (0, 2)), ((1, 0), (1, 1)), ((1, 1), (1, 2)), ((0, 2), (1, 0)), ((0, 1), (2, 2)), ((0, 2), (1, 1)), ((0, 1), (2, 1)), ((2, 0), (1, 2)), ((0, 1), (2, 0)), ((2, 2), (2, 1)), ((2, 2), (1, 0)), ((2, 1), (0, 2))}