找到矩阵单位根的(部分)列表



我正在寻找一种方法来构建1和-1的矩阵平方根列表。我只对尺寸2到4感兴趣,甚至不需要一个完整的集合,只需要一个实用的集合(这意味着我可以在某个时候停止循环(。这是我(非常(低效的解决方案

def racines(n, dim, field='real'):
if field == 'real':
unites = [1, 0, -1]
elif field == 'complex':
unites = [1, 0, -1, 1j, -1j]
if dim == 2:
liste = [np.array([[a,b], [c,d]]) for a in unites
for b in unites for c in unites 
for d in unites]
elif dim == 3:
liste = [np.array([[a, b, c], [d, e, f], [g, h, i]])
for a in unites for b in unites for c in unites 
for d in unites for e in unites for f in unites
for g in unites for h in unites for i in unites]
elif dim == 4:
liste = [np.array([[a,b,c,d], [e,f,g,h], [i,j,k,l], [m,o,p,q]])
for a in unites for b in unites for c in unites for d in unites
for e in unites for f in unites for g in unites for h in unites
for i in unites for j in unites for k in unites for l in unites
for m in unites for o in unites for p in unites for q in unites]
liste = [m for m in liste if np.linalg.det(m) != 0]
liste = [m for m in liste if np.array_equal(np.matmul(m, m), np.identity(dim, dtype='int')*n)]
return(liste)

工作良好,直到4d,当然它变得太难处理了。。。如何让它更快?

您可以递归执行。例如,如果我想要0到4之间的n个数字的列表,你可以使用

def get_lists(size, max_it, accumulator = [], lists = []):
if size ==0:
lists.append(accumulator)
else:
for i in range(5):
if len(lists) == max_it:
break
l = accumulator.copy()
l.append(i)
get_lists(size-1,max_it, l, lists)

def lists(size,max_it=-1):
l = []  
get_lists(size,max_it, [], l)
return l        
print(lists(3,10))

max_it是您想要的不同列表的数量(如果您想要所有列表,则设置为-1(

对于那些需要它的人来说,以下是诀窍。仍然不漂亮,但它在4d 中工作得更快

def racines(n, dim, field='real'):
unites = [1, 0, -1]
if field == 'complex':
unites += [1j, -1j]
elif field != 'real':
print('Unknown field !')
return([])
if dim == 2:
liste = [np.array([[a,b], [c,d]]) for a in unites
for b in unites for c in unites 
for d in unites]
elif dim == 3:
liste = [np.array([[a, b, c], [d, e, f], [g, h, i]])
for a in unites for b in unites for c in unites 
for d in unites for e in unites for f in unites
for g in unites for h in unites for i in unites]
elif dim == 4:
roots_2d = racines(n, 2, field=field)
neg_roots_2d = racines(-n, 2, field=field)
other = [np.identity(2, dtype='int'), np.identity(2, dtype='int')*-1, np.zeros([2,2], dtype='int')]
unites = roots_2d + neg_roots_2d + other
liste = [np.hstack([np.vstack([a,b]), np.vstack([c,d])])
for a in unites for b in unites for c in unites for d in unites]
else:
print('No can do !')
return([])
liste = [m for m in liste if np.linalg.det(m) != 0]
liste = [m for m in liste if np.array_equal(np.matmul(m, m), np.identity(dim, dtype='int')*n)]
return(liste)
# res = racines(1, 4, field='real') # 2.43s
# res = racines(1, 4, field='complex') # 2min 18s

最新更新