Ejemplo n.º 1
0
def init_first_site(model: BaseModel, nrg_maxkeep: int,
                    meass: List[Tuple[str, int]]):
    '''初始化第一个site\n
    这个时候只有1和N上面的block,创建这两个block上面的升降算符\n
    还有以后观测要用的算符。
    meass中应该是[(1, 'sz'), (N, 'sz')](N是最后一个格子的编号)\n
    这样的内容
    '''
    conf = DMRGConfig(model, nrg_maxkeep)
    #
    left = first_leftblock(model.sites[0])
    #创建第一个格子上的哈密顿量,还有第一个格子的产生算符
    hamleft = create_hamiltonian_of_site(left.fock_basis, model.coef_u,
                                         model.get_coef_mu(model.sites[0]))
    cup1 = create_operator_of_site(left.fock_basis,
                                   OperFactory.create_spinup())
    cdn1 = create_operator_of_site(left.fock_basis,
                                   OperFactory.create_spindown())
    #把现在的结果暂存到dconf
    conf.left_tmp_reset(model.sites[0], left, hamleft)
    conf.left_tmp_add_oper(cup1)
    conf.left_tmp_add_oper(cdn1)
    #
    right = first_rightblock(model.sites[-1])
    #创建最后一个格子上的哈密顿量,还有最后一个格子的产生算符
    hamright = create_hamiltonian_of_site(right.fock_basis, model.coef_u,
                                          model.get_coef_mu(model.sites[-1]))
    cuplast = create_operator_of_site(right.fock_basis,
                                      OperFactory.create_spinup())
    cdnlast = create_operator_of_site(right.fock_basis,
                                      OperFactory.create_spindown())
    #把右侧的结果也暂存到dconf
    conf.right_tmp_reset(model.sites[-1], right, hamright)
    conf.right_tmp_add_oper(cuplast)
    conf.right_tmp_add_oper(cdnlast)
    #把block上面的算符存储到tmp里,以后需要的是ext上面的算符
    leftstor = conf.get_leftblock_storage(model.sites[0])
    rightstor = conf.get_rightblock_storage(model.sites[-1])
    for prefix, idx in meass:
        if idx == model.sites[0]:
            stor = leftstor
            basis = left
        elif idx == model.sites[-1]:
            stor = rightstor
            basis = right
        else:
            raise ValueError('这个算符不在第一个或最后一个格子')
        measop = create_operator_of_site(basis.fock_basis,
                                         OperFactory.create_by_name(prefix))
        stor.storage_meas(prefix, measop)
    return conf
Ejemplo n.º 2
0
def test1():
    '''测试leftblock'''
    #first_block中的phi有四个分量,内容和一个格子是一致的
    left = first_leftblock(1)
    cuop = create_operator_of_site(left.fock_basis,
                                   OperFactory.create_spinup())
    #nuop = create_operator_of_site(left.fock_basis, OperFactory.number_spinup())
    leftext = extend_leftblock(left)
    print(left)
    print(cuop)
    #print(nuop)
    #print('验证:', numpy.matmul(cuop.mat, cuop.mat.transpose()))
    cuopext = leftblock_extend_oper(leftext, cuop)
    #nuopext = leftblock_extend_oper(leftext, nuop)
    print(cuopext)
    #print('验证2:', nuopext)
    #print(numpy.matmul(cuopext.mat,cuopext.mat.transpose()))
    #
    print('site上的算符更新')
    #
    cuop2 = create_operator_of_site(leftext.stbss, OperFactory.create_spinup())
    #nuop2 = create_operator_of_site(leftext.stbss, OperFactory.number_spinup())
    print(cuop2)
    cuop2ext = leftsite_extend_oper(leftext, cuop2)
    #nuop2ext = leftsite_extend_oper(leftext, nuop2)
    print(cuop2ext)
    #print('验证3:', nuop2ext)
    #print(numpy.matmul(cuop2ext.mat, cuop2ext.mat.transpose()))
    #
    phival = random_phival([4, 16], leftext)
    newleft = update_to_leftblock(leftext, phival)
    print(newleft)
    #
    newcuop = update_leftblockextend_oper(newleft, cuopext, phival)
    #newnuop = update_leftblockextend_oper(newleft, nuopext, phival)
    print(newcuop)
    #print('验证4', newnuop)
    #print(numpy.matmul(newnuop.mat, newnuop.mat.transpose()))
    #
    newleftext = extend_leftblock(newleft)
    newcuopext = leftblock_extend_oper(newleftext, newcuop)
    phival = random_phival([8, 16], newleftext)
    newnewleft = update_to_leftblock(newleftext, phival)
    newnewcuop = update_leftblockextend_oper(newnewleft, newcuopext, phival)
    print(newnewcuop)
Ejemplo n.º 3
0
def test1():
    '''测试一维链上面的NRG,DMRG'''
    hc6 = HubbardChain(6, 0.0)
    #print(hc6)
    dconf = DMRGConfig(hc6, 1000)
    #
    left1 = first_leftblock(1)
    #创建第一个格子上的哈密顿量,还有第一个格子的产生算符
    hamleft = create_hamiltonian_of_site(left1.fock_basis, hc6.coef_u, 0)
    cup1 = create_operator_of_site(left1.fock_basis,
                                   OperFactory.create_spinup())
    cdn1 = create_operator_of_site(left1.fock_basis,
                                   OperFactory.create_spindown())
    #把现在的结果暂存到dconf
    dconf.left_tmp_reset(1, left1, hamleft)
    dconf.left_tmp_add_oper(cup1)
    dconf.left_tmp_add_oper(cdn1)
    print(dconf)
    #新的格子的bonds,只需要比自己小的
    allbonds = hc6.get_site_bonds(2)
    newbonds = [bond for bond in allbonds if bond < 2]
    print(newbonds)
    #如果之前的这些site中依旧和更大的site有bond
    #需要在left_tmp中保留他们的算符,在下一次中扩展
    site_need_tmp = []
    for site in range(1, left1.block_len + 2):
        allbonds = hc6.get_site_bonds(site)
        for bond in allbonds:
            if bond > left1.block_len + 1:
                site_need_tmp.append(site)
                break
    print(site_need_tmp)
    left2 = leftblock_to_next(dconf, 2, newbonds, [], site_need_tmp, [])
    print(dconf)
    #继续向下一个格子
    allbonds = hc6.get_site_bonds(3)
    newbonds = [bond for bond in allbonds if bond < 3]
    print(newbonds)
    site_need_tmp = []
    for site in range(1, left2.block_len + 2):
        allbonds = hc6.get_site_bonds(site)
        for bond in allbonds:
            if bond > left2.block_len + 1:
                site_need_tmp.append(site)
                break
    print(site_need_tmp)
    ##加上一个2用来检测结果
    #left3 = leftblock_to_next(left2, 2, dconf, newbonds, [], site_need_tmp + [2])
    ##检查算符
    #left_tmp = dconf.get_leftblock_storage(3)
    #cu1 = left_tmp.get_oper(1, 1)
    #cd1 = left_tmp.get_oper(1, -1)
    #cu2 = left_tmp.get_oper(2, 1)
    #cd2 = left_tmp.get_oper(2, -1)
    #for ridx in range(left3.dim):
    #    for lidx in range(left3.dim):
    #        print('右侧的基')
    #        print(left3.idx_to_state(ridx))
    #        #在fock_basis上面的分量
    #        sitebss_arr = left3.fock_dict[ridx]
    #        template = ''
    #        for idx2 in range(left3.fock_basis.dim):
    #            if (idx2 % 4) == 0:
    #                template += '\n'
    #            template += '%.4f |%s>\t' %\
    #                (sitebss_arr[idx2], left3.fock_basis.idx_to_state(idx2))
    #        print(template)
    #        print('左侧的基')
    #        #再fock_basis上面的分量
    #        sitebss_arr = left3.fock_dict[lidx]
    #        template = ''
    #        for idx2 in range(left3.fock_basis.dim):
    #            if (idx2 % 4) == 0:
    #                template += '\n'
    #            template += '%.4f |%s>\t' %\
    #                (sitebss_arr[idx2], left3.fock_basis.idx_to_state(idx2))
    #        print(template)
    #        print('算符的数值')
    #        print(cu1.mat[lidx, ridx])
    #        print(cd1.mat[lidx, ridx])
    #        print(cu2.mat[lidx, ridx])
    #        print(cd2.mat[lidx, ridx])
    #
    left3 = leftblock_to_next(dconf, 3, newbonds, [], site_need_tmp, [])
    #继续向下一个格子
    allbonds = hc6.get_site_bonds(4)
    newbonds = [bond for bond in allbonds if bond < 4]
    print(newbonds)
    #newbonds = newbonds + [1]#PBC的时候加一个4-1之间的链接
    site_need_tmp = []
    for site in range(1, left3.block_len + 2):
        allbonds = hc6.get_site_bonds(site)
        for bond in allbonds:
            if bond > left3.block_len + 1:
                site_need_tmp.append(site)
                break
    print(site_need_tmp)
    left4 = leftblock_to_next(dconf, 4, newbonds, [], site_need_tmp, [])
    print(left4)
    lst4 = dconf.get_leftblock_storage(4)
    ham4 = lst4.hamiltonian
    print(ham4)
    print(ham4.basis.dim)
    eigvs = numpy.linalg.eigvalsh(ham4.mat)
    print(numpy.sort(eigvs))
    #半满四个格子的时候的精确解是-4.47213595(OBC)可以调节max_keep来验证
    #半满四个格子的时候的精确解是-4.0(PBC)可以去掉之前的注释验证
    #注意这里的解是没有限制sector的,可以看ham4.basis第一个分量是不是半满
    print(ham4.basis.spin_nums[0])
Ejemplo n.º 4
0
def test1():
    '''测试superblock
    测试在5个格子时候的哈密顿量是否正确,验证自旋上的部分
    '''
    #
    left1 = first_leftblock(1)
    #现在只有第一个格子,创建第一个格子的哈密顿量和产生算符
    hamleft = create_hamiltonian_of_site(left1.fock_basis, -1., 0)
    print('U', hamleft)
    cup_in_1 = create_operator_of_site(left1.fock_basis,
                                       OperFactory.create_spinup())
    #将第一个格子扩展到第二个
    left1ext = extend_leftblock(left1)
    #在扩展过的格子上的C^+_1
    cup_in_1 = leftblock_extend_oper(left1ext, cup_in_1)
    #扩展以后有C^+_2
    cup_in_2 = create_operator_of_site(left1ext.stbss,
                                       OperFactory.create_spinup())
    cup_in_2 = leftsite_extend_oper(left1ext, cup_in_2)
    #扩展以后的U2
    ciu_in_2 = create_operator_of_site(left1ext.stbss, OperFactory.create_u())
    ciu_in_2 = leftsite_extend_oper(left1ext, ciu_in_2)
    #现在C^+_1和C^+_2都在|phi^1, s^2>这个left1ext基上,整合进哈密顿量
    #先把哈密顿量也放到|phi^1, s^2>这个基上
    hamleft = extend_leftblock_hamiltonian(hamleft, left1ext)
    hamleft.add_hopping_term(cup_in_1, cup_in_2, 1.0)
    hamleft.add_u_term(ciu_in_2, -1.0)
    print('U', hamleft)
    #然后升级left1ext到left2 |phi^2>
    phival = numpy.eye(16)
    left2 = update_to_leftblock(left1ext, phival)
    hamleft = update_leftblockextend_hamiltonian(left2, hamleft, phival)
    cup_in_1 = update_leftblockextend_oper(left2, cup_in_1, phival)
    cup_in_2 = update_leftblockextend_oper(left2, cup_in_2, phival)
    #将|phi^2>扩展到|phi^2, s^3>
    left2ext = extend_leftblock(left2)
    #把哈密顿量和第二个算符也扩展过去
    hamleft = extend_leftblock_hamiltonian(hamleft, left2ext)
    cup_in_2 = leftblock_extend_oper(left2ext, cup_in_2)
    #创建第三个格子的算符,然后放到|phi^2, s^3>
    cup_in_3 = create_operator_of_site(left2ext.stbss,
                                       OperFactory.create_spinup())
    cup_in_3 = leftsite_extend_oper(left2ext, cup_in_3)
    #把2-3之间的hopping放到哈密顿量里
    hamleft.add_hopping_term(cup_in_2, cup_in_3, 1.0)
    #把|phi^2, s^3>这个东西以后要用来生成supoerblock
    print(hamleft)
    print(cup_in_3)
    #
    #
    right = first_rightblock(5)
    #现在只有第5个格子
    hamright = create_hamiltonian_of_site(right.fock_basis, -1.0, 0)
    print('rU', hamright)
    cup_in_5 = create_operator_of_site(right.fock_basis,
                                       OperFactory.create_spinup())
    #将第5个格子扩展到第4个 |s^4, phi^1>
    rightext = extend_rightblock(right)
    #把第5个格子的算符扩展
    cup_in_5 = rightblock_extend_oper(rightext, cup_in_5)
    #创建第四个格子的算符并且扩展
    cup_in_4 = create_operator_of_site(rightext.stbss,
                                       OperFactory.create_spinup())
    cup_in_4 = rightsite_extend_oper(rightext, cup_in_4)
    #第四个格子上的U
    ciu_in_4 = create_operator_of_site(rightext.stbss, OperFactory.create_u())
    ciu_in_4 = rightsite_extend_oper(rightext, ciu_in_4)
    #把哈密顿量扩展到|s^4, phi^1>
    hamright = extend_rightblock_hamiltonian(hamright, rightext)
    #添加4-5的hopping
    hamright.add_hopping_term(cup_in_4, cup_in_5, 1.0)
    hamright.add_u_term(ciu_in_4, -1.0)
    print('rU', hamright)
    print(cup_in_4)
    #
    #创建superblock
    superblock = extend_merge_to_superblock(left2ext, rightext)
    print(superblock)
    #把左边的哈密顿量扩展到superblock上面
    hamleft = leftext_hamiltonian_to_superblock(superblock, hamleft)
    cup_in_3_e = leftext_oper_to_superblock(superblock, cup_in_3)
    print(hamleft)
    print(cup_in_3_e)
    #
    #for ridx in superblock.iter_idx():
    #    for lidx in superblock.iter_idx():
    #        if hamleft.mat[lidx, ridx] == 0:
    #            continue
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(ridx)
    #        rsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(lidx)
    #        lsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        print(rsta, lsta, hamleft.mat[lidx, ridx])
    #for ridx in superblock.iter_idx():
    #    for lidx in superblock.iter_idx():
    #        if cup_in_3.mat[lidx, ridx] == 0:
    #            continue
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(ridx)
    #        rsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(lidx)
    #        lsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        print(rsta, lsta, cup_in_3.mat[lidx, ridx])
    #
    #把右边的哈密顿量扩展到superblock上面
    hamright = rightext_hamiltonian_to_superblock(superblock, hamright)
    print(hamright)
    #for ridx in superblock.iter_idx():
    #    for lidx in superblock.iter_idx():
    #        if hamright.mat[lidx, ridx] == 0:
    #            continue
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(ridx)
    #        rsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(lidx)
    #        lsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        print(rsta, lsta, hamright.mat[lidx, ridx])
    #
    #把右边的算符扩展到superblock上面
    cup_in_4_e = rightext_oper_to_superblock(superblock, cup_in_4)
    print(cup_in_4_e)
    #for ridx in superblock.iter_idx():
    #    for lidx in superblock.iter_idx():
    #        if cup_in_4.mat[lidx, ridx] == 0:
    #            continue
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(ridx)
    #        rsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        idx1, idx2, idx3, idx4 = superblock.idx_to_idxtuple(lidx)
    #        lsta = '%s,%s,%s,%s' %\
    #            (left1ext.idx_to_state(idx1),\
    #                superblock.leftblockextend.stbss.idx_to_state(idx2),\
    #                    superblock.rightblockextend.stbss.idx_to_state(idx3),\
    #                        superblock.rightblockextend.rblk.idx_to_state(idx4))
    #        print(rsta, lsta, cup_in_4.mat[lidx, ridx])
    hamsuper = plus_two_hamiltonian(hamleft, hamright)
    res1 = hamsuper.add_hopping_term(cup_in_3_e, cup_in_4_e, 1.0)
    res2 = hamsuper.superblock_add_hopping_term(cup_in_3, cup_in_4, 1.0)
    print('superblock_add_hopping_term: ', numpy.allclose(res1, res2))
    print(hamsuper)
Ejemplo n.º 5
0
def test2():
    '''测试superblock
    测试在5个格子时候的哈密顿量是否正确,验证自旋下的部分
    '''
    #
    left1 = first_leftblock(1)
    #现在只有第一个格子,创建第一个格子的哈密顿量和产生算符
    hamleft = create_hamiltonian_of_site(left1.fock_basis, 0, 0)
    cdn_in_1 = create_operator_of_site(left1.fock_basis,
                                       OperFactory.create_spindown())
    #将第一个格子扩展到第二个
    left1ext = extend_leftblock(left1)
    #在扩展过的格子上的C^+_1
    cdn_in_1 = leftblock_extend_oper(left1ext, cdn_in_1)
    #扩展以后有C^+_2
    cdn_in_2 = create_operator_of_site(left1ext.stbss,
                                       OperFactory.create_spindown())
    cdn_in_2 = leftsite_extend_oper(left1ext, cdn_in_2)
    #现在C^+_1和C^+_2都在|phi^1, s^2>这个left1ext基上,整合进哈密顿量
    #先把哈密顿量也放到|phi^1, s^2>这个基上
    hamleft = extend_leftblock_hamiltonian(hamleft, left1ext)
    hamleft.add_hopping_term(cdn_in_1, cdn_in_2, 1.0)
    #然后升级left1ext到left2 |phi^2>
    phival = numpy.eye(16)
    left2 = update_to_leftblock(left1ext, phival)
    hamleft = update_leftblockextend_hamiltonian(left2, hamleft, phival)
    cdn_in_1 = update_leftblockextend_oper(left2, cdn_in_1, phival)
    cdn_in_2 = update_leftblockextend_oper(left2, cdn_in_2, phival)
    #将|phi^2>扩展到|phi^2, s^3>
    left2ext = extend_leftblock(left2)
    #把哈密顿量和第二个算符也扩展过去
    hamleft = extend_leftblock_hamiltonian(hamleft, left2ext)
    cdn_in_2 = leftblock_extend_oper(left2ext, cdn_in_2)
    #创建第三个格子的算符,然后放到|phi^2, s^3>
    cdn_in_3 = create_operator_of_site(left2ext.stbss,
                                       OperFactory.create_spindown())
    cdn_in_3._mat = numpy.random.randn(cdn_in_3.mat.shape[0],
                                       cdn_in_3.mat.shape[1])
    cdn_in_3 = leftsite_extend_oper(left2ext, cdn_in_3)
    #把2-3之间的hopping放到哈密顿量里
    hamleft.add_hopping_term(cdn_in_2, cdn_in_3, 1.0)
    #把|phi^2, s^3>这个东西以后要用来生成supoerblock
    print(hamleft)
    print(cdn_in_3)
    #
    #
    right = first_rightblock(5)
    #现在只有第5个格子
    hamright = create_hamiltonian_of_site(right.fock_basis, 0, 0)
    cdn_in_5 = create_operator_of_site(right.fock_basis,
                                       OperFactory.create_spindown())
    #将第5个格子扩展到第4个 |s^4, phi^1>
    rightext = extend_rightblock(right)
    #把第5个格子的算符扩展
    cdn_in_5 = rightblock_extend_oper(rightext, cdn_in_5)
    #创建第四个格子的算符并且扩展
    cdn_in_4 = create_operator_of_site(rightext.stbss,
                                       OperFactory.create_spindown())
    #Issue #16:用一个随机的矩阵来验证优化的正确性
    cdn_in_4._mat = numpy.random.randn(cdn_in_4.mat.shape[0],
                                       cdn_in_4.mat.shape[1])
    cdn_in_4 = rightsite_extend_oper(rightext, cdn_in_4)
    #把哈密顿量扩展到|s^4, phi^1>
    hamright = extend_rightblock_hamiltonian(hamright, rightext)
    #添加4-5的hopping
    hamright.add_hopping_term(cdn_in_4, cdn_in_5, 1.0)
    print(hamright)
    print(cdn_in_4)
    #
    #创建superblock
    superblock = extend_merge_to_superblock(left2ext, rightext)
    print(superblock)
    #把左边的哈密顿量扩展到superblock上面
    hamleft = leftext_hamiltonian_to_superblock(superblock, hamleft)
    cdn_in_3_e = leftext_oper_to_superblock(superblock, cdn_in_3)
    print(hamleft)
    print(cdn_in_3_e)
    #把右边的哈密顿量扩展到superblock上面
    hamright = rightext_hamiltonian_to_superblock(superblock, hamright)
    print(hamright)
    #把右边的算符扩展到superblock上面
    cdn_in_4_e = rightext_oper_to_superblock(superblock, cdn_in_4)
    print(cdn_in_4_e)
    #
    hamsuper = plus_two_hamiltonian(hamleft, hamright)
    res1 = hamsuper.add_hopping_term(cdn_in_3_e, cdn_in_4_e, 1.0)
    res2 = hamsuper.superblock_add_hopping_term(cdn_in_3, cdn_in_4, 1.0)
    print('superblock_add_hopping_term: ', numpy.allclose(res1, res2))
    print(hamsuper)