表示排列的数组中1的位置是否有解析公式?

问题描述 投票:0回答:1

举例来说,我们有一个州有 N 个站点。这些位点中的每一个都可以容纳 0 或 1(其中没有粒子或有粒子)。

例如,对于 N = 3,可能的状态为 |0,0,0>; |1,0,0>; |0,1,0>; |0,0,1>; |1,1,0>; |1,0,1>; |0,1,1>; |1,1,1>

由于与这个问题无关的原因,这些是物理学中粒子状态的表示。更具体地说,这些是无旋费米子的排列。因此,它们是通过在单个状态之间进行张量积来构造的。 例如

|0,1,0> = |0> ⊗ |1> ⊗ |0> (2 号位点有 1 个费米子。1 号位点和 3 号位点为空)

其中每个状态都可以在其自己的空间中明确表示为向量。

|0> = (1,0)(费米子不存在于该 |k> 状态)这也称为真空状态

|1> = (0,1)(费米子存在于该 |k> 状态)

这允许我们进行数值乘积,输出将是最终状态向量,其维度为 2^(N)

所以:

|0,1,0> = |0> ⊗ |1> ⊗ |0> = (1,0) ⊗ (0,1) ⊗ (1,0) = (0, 0, 1, 0, 0, 0, 0, 0) 作为向量

|0,1,1> = |0> ⊗ |1> ⊗ |1> = (1,0) ⊗ (0,1) ⊗ (0,1) = (0, 0, 0, 0, 0, 0, 1, 0) 作为向量

问题是对于大量站点来说,计算所有这些张量乘积可能非常耗时。但值得注意的是,无论状态如何,最终的显式 Vector 都将是稀疏的。它在某个位置总是有一个“1”,其余的将保证为零。

我现在的问题是,是否有一个分析表达式可以提前知道唯一的“1”将落在哪里,以便我可以避免做产品?

值得注意的一件有趣的事情是,通过采用上面列举的 8 个状态,对于每个状态,当我们对组合进行排列时,“1”只是在向量中向下移动 1 个索引。而且顺序非常明显。我们首先将“1”元素沿 N 个位置移动。然后我们将第一个元素保留为 0,并将 1 沿着抽象状态的剩余尾部移动。我们重复这样做,直到达到我们的状态。

所以这里我们的 8 个向量形式的枚举状态是有序的:

(1, 0, 0, 0, 0, 0, 0, 0) = |0,0,0>
(0, 1, 0, 0, 0, 0, 0, 0) = |1,0,0>
(0, 0, 1, 0, 0, 0, 0, 0) = |0,1,0>
(0, 0, 0, 1, 0, 0, 0, 0) = |1,1,0>
(0, 0, 0, 0, 1, 0, 0, 0) = |0,0,1>
(0, 0, 0, 0, 0, 1, 0, 0) = |1,0,1>
(0, 0, 0, 0, 0, 0, 1, 0) = |0,1,1>
(0, 0, 0, 0, 0, 0, 0, 1) = |1,1,1>

看待这个问题的一种方法是,这条规则需要多少次排列才能实现我们的规则?如果我们知道这一点,我们就知道唯一的“1”元素将具有索引=这个排列数

这对于 N=3 个站点来说很容易做到。但对于 14 个粒子,这是用肉眼无法做到的。

algorithm permutation
1个回答
0
投票

感谢所有评论者,特别是@Bergi 启发的答案。

不幸的是,我不确定我是否完全同意,因为例如在 10010 -> 10010000 等状态下添加 0 将表示更大的二进制数(更大的索引),但在 1⊗0 和 1⊗0⊗0 之间进行显式张量积⊗0 不改变索引

再次,其中 1 是向量 (0,1),0 是 (1,0)。虽然它确实改变了整体维度。

话虽这么说,我是这样处理的。我将输入字符串中的第一个状态 0 或 1 对应于它自己的向量。如果状态为 0,则最终索引 = 0,如果 1 索引 = 1。我在字符串上向右移动,如果下一个条目是 0 状态,我只需将维度加倍并保持索引不变。但是,如果下一个状态是 1,我会将维度加倍并将其添加到当前索引。这表示如果将向量与 (0,1) 进行张量乘积,则会进行移位。代码如下:

create_fermions 创建 f_state 结构,它只是二进制字符串(这些是整数的原因是因为它们稍后将用于直接对角化。实际上它们应该是双精度数,但现在这不是问题)。该功能是为了方便用户输入状态

create_explicit_fermion 获取前一个函数的输出,并使用上面描述的技术返回指向显式向量/数组表示的指针。 “1”元素的索引似乎位于正确的位置。

%%cython
cimport cython
from libc.stdlib cimport malloc, free
from cython cimport sizeof
#import numpy as np
#cimport numpy as np



ctypedef struct f_state:
    int* state
    int size

cdef void free_fermions(f_state fstate) nogil:
    free(fstate.state)


cdef f_state create_fermions(str state, int space_size):
    cdef int* state_array = <int*>malloc(space_size*sizeof(int))
    if state_array is NULL:
        raise MemoryError("Failed to allocate memory for state_array")
    
    for i in range(space_size):
        if state[i] not in ('0', '1'):
            raise ValueError("spinless fermion states can only have 1 occupation or none 0")
        state_array[i] = <int>state[i]-48 #minus 48 because of ascii encoding from str to int. 0 is 48 in ascii. 1 is 49
    cdef f_state fstate
    fstate.state = state_array
    fstate.size = space_size
    return fstate

cdef int* create_explicit_fermions(f_state in_state):
    #start by allocating the vector
    cdef int total_size = 2**in_state.size
    #malloc this to mem
    #....to be completed
    cdef int tmp_dimension
    cdef int index
    if in_state.state[0] == 0:
        index = 0
    elif in_state.state[0] == 1:
        index = 1
    if (in_state.size > 1):
        for i in range(in_state.size):
            tmp_dimension = 2**(i+1)
            if (in_state.state[i+1] == 0):
                index = index
            elif (in_state.state[i+1] == 1):
                index = index + tmp_dimension
    cdef int* result = <int*>malloc(total_size*sizeof(int))
    for i in range(total_size):
        result[i] = 0
    result[index] = 1
    return result

    








#test unit 2

cdef str fermions = "001"
cdef int fsize = 3

cdef f_state fermion_state = create_fermions(fermions, fsize)
for i in range(fsize):
    print(fermion_state.state[i])

print("\nnow the explicit vector\n")
cdef int* fermion_vector = create_explicit_fermions(fermion_state)
for i in range(2**fsize):
    print(fermion_vector[i])
    
free_fermions(fermion_state)
free(fermion_vector)

以下测试单元给出


the state in diract notation
0
0
1

the state in an explicit Fock space vector

0
0
0
0
1
0
0
0

如果您手动计算张量积,这是正确的结果

更复杂的示例:

费米子=“010010” f 大小 = 6

给予

the state in diract notation
0
1
0
0
1
0

the state in an explicit Fock space vector

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

在索引 18

感谢这些,我现在可以计算创建-消灭运算符的完整矩阵

@Bergi 如果有办法按照您的建议或更有效地做到这一点,请随时提供代码。谢谢你的帮助

© www.soinside.com 2019 - 2024. All rights reserved.