如何将两个fock基础与其索引连接?

时间:2017-01-21 17:27:11

标签: python numpy indexing scipy

我为具有给定数量的粒子N和网站Mtot的bosson生成Fock基础(量子力学),它只是构建一组包含必须Mtot个位置的列表覆盖N项(请参阅下面的代码)。然后我构建了另一个列表,列表包含M个站点(Mtot = 2 * M),并且所有可能的粒子/项目n = 0,1,2 ... N. (在我的代码中,我的工作是N = 2,M = 2以简化)

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内其他状态的可能状态的索引。例如,使用此前面的代码,我们将获得:

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

因此,reduced_basi的{​​{1}}的第一项可以与[0, 0][0, 0, 2, 0][0, 0, 1, 1]相关联,然后[0, 0, 0, 2]它可能与[1,0] ...有关,因此,我要构建的列表必须具有第一个组件:[1, 0, 1, 0], [1, 0, 0, 1](其中7,8,9是{{1}的对应索引}状态遵循相同的顺序)和第二个:index_list[0] = [7,8,9]。最后它必须以sistematically方式完成,因此我必须为这个特殊情况获得以下列表(我已经手动计算过):

basis

知道如何实现这个?

1 个答案:

答案 0 :(得分: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))

接下来,你可以简单地使用列表理解:

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

python中产生:

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