Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 57
Visibility: Unlisted (only visible to those who know the link)
Kernel: SageMath 9.0

Représenter des systèmes de racines avec Ipyvolume

import numpy as np import ipyvolume as ipv

On voudrait représenter le système de racines d'un groupe de Coxeter à 4 ou 5 générateurs, mais il vit en dimension 4, ou 5. On peut réduire la dimension en mettant les racines dans un espace projectif, ce qui diminue la dimension de 1, puis en projetant.

Un fois que l'on s'est ramené à la dimension 3, Ipyvolume prend la main.

On commence par calculer les racines

def racines_projectives(dim, tresses, profondeur): ''' Calcule le système de racine du groupe de Coxeter à dim générateurs, avec les relation tresses, jusqu'à la profondeur profondeur''' #Description du groupe B = np.eye(dim, dtype = float) for i in range(0,dim): for j in range(i+1,dim): B[i,j] = tresses.pop() B[j,i] = B[i,j] #Forme bilinéaire associée B = -2 * np.cos(np.pi/B) #Base où on représentera les racines base = Matrix(QQbar, [[1 for k in range(dim)]] + [[1 if i == k else 0 for i in range(dim)] for k in range(1, dim)]) base = n(base.gram_schmidt(orthonormal = True)[0]) P = np.array(base) #Racines initiales rac = np.array(np.eye(dim)) #Pour compter les racines de chaque profondeur begin = 0 i = dim end = dim #Pour visiter les racines une seule fois res = set() for d in range(profondeur): for r in rac[begin:end]: #le poset est gradué : on considère seulement #la dernière génération de racines for j in range(dim): y = r - rac[j].dot(B).dot(r) * rac[j] #On applique les générateurs if (not tuple(y) in res) and (y >= 0).all(): res.add(tuple(y)) rac = np.append(rac, y.reshape((1,dim)), axis = 0) i += 1 begin = end end = i rac = P.dot(rac.transpose()) #On exprime dans la base voulue rac /= rac[0] #On normalise la première coordonnée return rac

En 3D...

profondeur = 6 rac = racines_projectives(4, [4]*6, profondeur) ipv.clear() ipv.scatter(x = rac[1], y = rac[2], z = rac[3], size=1, marker = "circle_2d") ipv.show()

Et la même chose en 4D !

# On va afficher le système de racines du groupe à 5 générateurs # où toutes les relations sont d'ordre 7 # jusqu'à la profondeur 6 rac = racines_projectives(5, [7]*10, 6) ipv.clear() ipv.scatter(rac[1],rac[2],rac[3], marker = 'point_2d', size = 10) ipv.show()

L'angle n'est pas très joli : on pourrait peut-être le faire tourner ?

Et elle tourne !

# Une matrice de raotion en 4D T = 20 theta = n(2*pi/T) c, s = cos(theta), sin(theta) Rotation = np.array([[c,-s,0,0], [s,c,0,0], [0,0,c,-s], [0,0,s,c]]) # Un tableau nb de frame * dimension * nb de points animation4D = np.zeros((T, 4, rac.shape[1])) animation4D[0] = rac[1:] # animation4D[i] contient la position des points au temps i for i in range(1, T): animation4D[i] = Rotation.dot(animation4D[i-1])
ipv.clear() # Pour faire une animation, on passe des tableaux # nb_de_frames * nb_de_points pour chaque coordonnée s = ipv.scatter(animation4D[:,1],animation4D[:,2],animation4D[:,3], size=0.5, marker = "circle_2d") ipv.animation_control(s) ipv.show()