3 votes

Comment connecter deux bases de fock avec leurs indices ?

Je génère une base de Fock (mécanique quantique) pour les bosons avec un nombre donné de particules N et de sites Mtot, il s'agit simplement de construire un ensemble de listes contenant Mtot places qui doivent être couvertes avec N éléments (voir le code ci-dessous). Ensuite, je construis une autre liste de listes avec M sites (Mtot = 2*M) et avec toutes les combinaisons possibles de particules/éléments n = 0,1,2...N. (dans mon code je travaille pour N=2, M=2 pour simplifier)

import numpy as np
from scipy.special import binom

M = 2
Mtot = 2*M
N = 2

def generate(N,nb):
        states = np.zeros((int(binom(nb+N-1, nb)), N), dtype=int)
        states[0, 0]=nb
        ni = 0  # init
        for i in xrange(1, states.shape[0]):
            states[i,:N-1] = states[i-1, :N-1]
            states[i,ni] -= 1
            states[i,ni+1] += 1+states[i-1, N-1]
            if ni >= N-2:
                if np.any(states[i, :N-1]):
                    ni = np.nonzero(states[i, :N-1])[0][-1]
            else:
                ni += 1
        return states.tolist()
basis = generate(Mtot,N)

reduced_basi = [] 
for i in xrange(N+1):
    reduced_basi.append(generate(M,i))

Maintenant, ce que je veux, c'est obtenir une liste contenant l'indice des états possibles à l'intérieur de reduced_basi qui peuvent être connectés aux autres états à l'intérieur de basis. Par exemple, en utilisant le code précédent, nous obtiendrons :

basis = [[2, 0, 0, 0], [1, 1, 0, 0], [1, 0, 1, 0], [1, 0, 0, 1], [0, 2, 0, 0], [0, 1, 1, 0], [0, 1, 0, 1], [0, 0, 2, 0], [0, 0, 1, 1], [0, 0, 0, 2]]
reduced_basi = [[[0, 0]], [[1, 0], [0, 1]], [[2, 0], [1, 1], [0, 2]]]

Ainsi, avec le premier élément de reduced_basi qui est [0, 0] peut être relié à [0, 0, 2, 0], [0, 0, 1, 1] et [0, 0, 0, 2], puis pour [1,0] il peut être relié à [1, 0, 1, 0], [1, 0, 0, 1] ... ainsi, la liste que je veux construire doit avoir comme premier composant : index_list[0] = [7,8,9] (où 7,8,9 sont les indices correspondants des états de basis suivant le même ordre) et le deuxième : index_list[1] = [2,3]. À la fin, cela doit être fait de manière systématique et le résultat doit être la liste suivante pour ce cas particulier (je l'ai calculée à la main) :

index_list = [[7,8,9],[2,3],[5,6],[0],[1],[4]]

Une idée de comment cela peut être implémenté ?

2voto

CommuSoft Points 6439

Vous pourriez définir une fonction :

def samestart(pattern,sequence):
    for i,d in enumerate(pattern):
        if d != sequence[i]:
            return False
    return True

En fait, vous pouvez le réécrire comme suit :

def samestart(pattern,sequence):
    return all(x == y for x,y in zip(pattern,sequence))

Ensuite, vous pouvez simplement utiliser la compréhension de liste :

[[i for i,sequence in enumerate(basis) if samestart(pattern,sequence)] for patterns in reduced_basi for pattern in patterns]

Dans python, cela produit :

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def samestart(pattern,sequence):
...     for i,d in enumerate(pattern):
...         if d != sequence[i]:
...             return False
...     return True
... 
>>> basis = [[2, 0, 0, 0], [1, 1, 0, 0], [1, 0, 1, 0], [1, 0, 0, 1], [0, 2, 0, 0], [0, 1, 1, 0], [0, 1, 0, 1], [0, 0, 2, 0], [0, 0, 1, 1], [0, 0, 0, 2]]
>>> reduced_basi = [[[0, 0]], [[1, 0], [0, 1]], [[2, 0], [1, 1], [0, 2]]]
>>> [[i for i,sequence in enumerate(basis) if samestart(pattern,sequence)] for patterns in reduced_basi for pattern in patterns]
[[7, 8, 9], [2, 3], [5, 6], [0], [1], [4]]

Ce n'est pas terriblement efficace : on peut certainement utiliser le hachage ici pour améliorer les performances.


Si vous pouvez faire l'hypothèse que tous les "patterns" ont une longueur de deux, vous pouvez simplement en déduire cela et construire un dictionnaire. Par exemple :

résultat = {}
pour idx,base dans enumerate(basis):
    pattern = tuple(base[0:2])
    patlist = result.get(pattern)
    if patlist n'est pas None:
        patlist.append(idx)
    else:
        result[pattern] = [idx]

Cela produira un dictionnaire résultat :

>>> résultat
{(0, 1): [5, 6], (2, 0): [0], (0, 0): [7, 8, 9], (1, 0): [2, 3], (1, 1): [1], (0, 2): [4]}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X