2017-01-21 5 views
3

粒子数がN、サイト数がMtotのボッサンのFock基底(量子力学)を生成するには、Mtot個の項目を含むリストを作成してください。これはN個の項目に含まれています。次に、Mサイト(Mtot = 2 * M)を持つリストと、すべての可能なパーティクル/アイテムn = 0,1,2 ... Nを持つリストのリストを作成します。 (私のコードでは、私は簡単にするため、N = 2、M = 2のために働いています)2つのFock基底をインデックスに結びつけるにはどうすればいいですか?

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)) 

さて、ポイントは私がすることができreduced_basi内部の可能な状態のインデックスを含むリストを取得したいということですbasis内の他の状態に接続されています。 [0, 0]が、その後[1,0]ことが[1, 0, 1, 0], [1, 0, 0, 1]に関連することができ、[0, 0, 2, 0][0, 0, 1, 1][0, 0, 0, 2]に関連することが可能であるreduced_basiの最初の項目とそう

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]]] 

...:例えば、我々が得られます。この前のコードを使用してそのため、構築したいリストは、最初のコンポーネントとしてindex_list[0] = [7,8,9](ここで、7,8,9は、同じ順序に従うbasis状態の対応するインデックスです)と2番目のもの:index_list[1] = [2,3]が必要です。終わりに、それはsistematically行わなければならないと私は、この特定のケースについて、次のリストを取得する必要があり、結果として、(私は手でそれを計算しています):

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

任意のアイデアはどのようにこれを実装することができますか?

+1

ですから、基本的には同じ起動シーケンスを共有するインデックスをしたいですか? –

+0

はい、まさにこれです – Joe

+0

'reduce_basi'は階層的にパックされているのはなぜですか?あなたはそれを維持したいですか? –

答えて

2

あなたは関数を定義することができます:

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

をあなたは実際にようにそれを書き換えることができます:

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

次は、単純にリストの内包表記を使用することができます。pythonこの中

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

を生産:

$ 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]] 

これは大変効率的ではありません。ここでは、パフォーマンスを向上させるためにここでハッシュを使用することは間違いありません。


あなたはすべての「パターン」は、長さ2を持っているという仮定を作ることができ場合、あなたは、単にこれを導出し、辞書を構築することができます。例えば:

result = {} 
for idx,base in enumerate(basis): 
    pattern = tuple(base[0:2]) 
    patlist = result.get(pattern) 
    if patlist is not None: 
     patlist.append(idx) 
    else: 
     result[pattern] = [idx] 

これは辞書resultが生成されます:

>>> result 
{(0, 1): [5, 6], (2, 0): [0], (0, 0): [7, 8, 9], (1, 0): [2, 3], (1, 1): [1], (0, 2): [4]} 
+0

大丈夫、それは完璧に動作し、非常にありがとう! – Joe

+0

@Joe:歓迎です:)。 –

関連する問題