Exemplo n.º 1
0
def test2():
    '''测试right相关的'''
    right = first_rightblock(10)
    cudown = create_operator_of_site(right.fock_basis,
                                     OperFactory.create_spindown())
    print(cudown)
    #扩展right
    rightext = extend_rightblock(right)
    cuup2 = create_operator_of_site(rightext.stbss,
                                    OperFactory.create_spinup())
    #扩展rightext上面的两个算符
    cudownext = rightblock_extend_oper(rightext, cudown)
    print(cudownext)
    cuup2ext = rightsite_extend_oper(rightext, cuup2)
    print(cuup2ext)
    #将扩展完的两个算符收缩到新的right上
    phival = random_phival([16, 16], rightext)
    newright = update_to_rightblock(rightext, phival)
    print(newright)
    #print(newright.fock_dict)
    newcudown = update_rightblockextend_oper(newright, cudownext, phival)
    newcuup2 = update_rightblockextend_oper(newright, cuup2ext, phival)
    print(newcudown)
    print(newcuup2)
    #再给right扩展一个
    newrightext = extend_rightblock(newright)
    print(newrightext)  #, newrightext._fock_basis)
    #扩展newright上面的算符
    newcudownext = rightblock_extend_oper(newrightext, newcudown)
    phival = random_phival([8, 64], newrightext)
    newnewright = update_to_rightblock(newrightext, phival)
    newnewcudown = update_rightblockextend_oper(newnewright, newcudownext,
                                                phival)
    print(newnewcudown)
Exemplo n.º 2
0
def prepare_rightblockextend(conf: DMRGConfig, phi_idx: int,
                             newbonds: List[int], extoper_storage: List[int],
                             measure_storage: List[Tuple[str, int]]):
    '''把最右边的一个格子的扩展计算出来,这个扩展要包括新增的hopping\n
    以后要用来构成superblock
    '''
    #这个过程不会更新conf中的right_tmp
    rightstorage = conf.get_rightblock_storage(phi_idx)
    right = rightstorage.block
    rightham = rightstorage.hamiltonian
    #扩展right
    rightext = extend_rightblock(right)
    #给conf中的rightext进行初始化
    conf.rightext_reset(phi_idx, rightext)
    #扩展哈密顿量
    rightham = extend_rightblock_hamiltonian(rightham, rightext)
    #把扩展以后的哈密顿量存下来
    conf.storage_rightext_ham(phi_idx, rightham)
    #把需要扩展的算符扩展
    maintain_opers = {}
    #首先考虑这次新加进来的两个
    newup = create_operator_of_site(rightext.stbss,
                                    OperFactory.create_spinup())
    newup = rightsite_extend_oper(rightext, newup)
    newdown = create_operator_of_site(rightext.stbss,
                                      OperFactory.create_spindown())
    newdown = rightsite_extend_oper(rightext, newdown)
    #先把他放到maintain_opers当中
    maintain_opers[rightext.stbss.sites[0]] = (newup, newdown)
    #然后把现在暂存的这些都扩展并保存到maintain_oper
    #中,这些可能会去要计算bond,还有可能会保存到rightext
    while len(rightstorage.oper_storage_list) > 0:
        stidx = rightstorage.oper_storage_list[0]
        #弹出这两个算符
        stup, stdown = rightstorage.pop_oper(stidx)
        #扩展这两个算符,然后放到maintain_opers
        stup = rightblock_extend_oper(rightext, stup)
        stdown = rightblock_extend_oper(rightext, stdown)
        maintain_opers[stidx] = (stup, stdown)
    #把需要保存到ext中的算符都保存下来
    for stidx in extoper_storage:
        conf.storage_rightext_oper(phi_idx, maintain_opers[stidx][0])
        conf.storage_rightext_oper(phi_idx, maintain_opers[stidx][1])
    #把新的bond添加进去
    #rightext中保存的是rightham的实例,在这时修改也是可以的
    for bstidx in newbonds:
        coef_t = conf.model.get_t_coef(bstidx, newup.siteidx)
        #自旋向上部分
        tar_up = maintain_opers[bstidx][0]
        rightham.add_hopping_term(tar_up, newup, coef_t)
        #自旋向下部分
        tar_down = maintain_opers[bstidx][1]
        rightham.add_hopping_term(tar_down, newdown, coef_t)
    #把新的U添加进去
    newu = create_operator_of_site(rightext.stbss, OperFactory.create_u())
    newu = rightsite_extend_oper(rightext, newu)
    rightham.add_u_term(newu, conf.model.coef_u)
    #把新的Mu项添加进去
    coef_mu = conf.model.get_coef_mu(phi_idx - 1)
    if coef_mu != 0:
        newnu = create_operator_of_site(rightext.stbss,
                                        OperFactory.create_numup())
        newnu = rightsite_extend_oper(rightext, newnu)
        rightham.add_mu_term(newnu, coef_mu)
        newnd = create_operator_of_site(rightext.stbss,
                                        OperFactory.create_numdown())
        newnd = rightsite_extend_oper(rightext, newnd)
        rightham.add_mu_term(newnd, coef_mu)
    #把扩展后的算符存储到rightext[N]上面,用来给以后的观测使用
    #之前的过程并没有调整right_tmp,直接用就可以了
    rightext_stor = conf.get_rightext_storage(phi_idx)
    for prefix, idx in measure_storage:
        if idx == phi_idx - 1:  #如果是新加的格子,就新建这个算符
            meaop = create_operator_of_site(rightext.stbss,
                                            OperFactory.create_by_name(prefix))
            meaop = rightsite_extend_oper(rightext, meaop)
        else:
            meaop = rightstorage.get_meas(prefix, idx)
            meaop = rightblock_extend_oper(rightext, meaop)
        rightext_stor.storage_meas(prefix, meaop)
    return rightext
Exemplo n.º 3
0
def rightblockextend_to_next(conf: DMRGConfig, phi_idx: int,
                             extrabonds: List[int], newbonds: List[int],
                             extoper_storage: List[int],
                             measure_storage: List[Tuple[str, int]],
                             spin_sector, maxkeep: int):
    '''这时候的phi_idx是新的rightext的idx,leftext的idx就是他减去2\n
    spin_sector是在superblock上面的粒子数的要求\n
    extrabond在get_superblock_ham中要使用,而newbonds是值扩展
    '''
    #首先要将superblock得到,这个时候左边和右边之间的
    #extrabond也要考虑上
    leftstorage = conf.get_leftext_storage(phi_idx - 2)
    rightstorage = conf.get_rightext_storage(phi_idx + 1)
    #scrtor_idxs中保存的是满足粒子数要求的所有superblock上的基的idx
    #mat是这个sector上的矩阵
    sector_idxs, mat, superext = get_superblock_ham(conf.model, leftstorage,
                                                    rightstorage, spin_sector,
                                                    extrabonds)
    #将基态解出来
    eigvals, eigvecs = scipy.sparse.linalg.eigsh(mat, k=1, which='SA')
    #numpy.linalg.eigh(mat)
    ground = eigvecs[:, 0]
    ground_erg = eigvals[0]
    #把基态的信息保留下来
    conf.ground_vec = ground
    conf.ground_secidx = sector_idxs
    conf.ground_superext = superext
    #print('g', ground_erg)
    #从基态构造密度矩阵
    #这里需要sector_idx来判断有哪些位置上是有数值的
    #这个方法主要是将基态的C(alpha,s^j,s^j+1,beta)这个写成
    #M(a,b),lidxs就是将a变成(alpha,s^j)的列表,
    #ridxs是b到(s^j+1,beta)的,这在以后计算phival的时候有作用
    #因为phival的列是在(s^j+1,beta)的
    lidxs, ridxs, mat = get_density_root(  #pylint: disable=unused-variable
        leftstorage, rightstorage, sector_idxs, ground)
    #right上面的密度矩阵的获得
    denmat = numpy.matmul(mat.transpose(), mat)
    #这个方法主要目的是把density matrix划分成小块
    spsec_mat_dict = get_density_in_sector(rightstorage, ridxs, denmat)
    #获得phival
    phival = get_phival_from_density_sector(rightstorage, spsec_mat_dict,
                                            maxkeep)
    #在获得了phival以后,就可以通过这个phival更新基
    #rightblock^phi_idx里面的内容全部都在rightblockextend^phi_idx+1里面
    #不需要添加,只需要升级就行了,在DMRG sweep的过程中,rightblock上面的
    #算符或者哈密顿量都是用不到的,不进行保存
    rightext = rightstorage.block
    newrightblk = update_to_rightblock(rightext, phival)
    newham = update_rightblockextend_hamiltonian(newrightblk,
                                                 rightstorage.hamiltonian,
                                                 phival)
    #设置一下现在的idx,不保存哈密顿量,以后用不到
    conf.right_tmp_reset(phi_idx, newrightblk, None)
    #用来保存newrightblk上面的算符
    maintain_dict = {}
    #把需要放到新的rightext上面的算符,先升级到新的right上面
    for extidx in rightstorage.oper_storage_list:  #extoper_storage:
        #上一次迭代的时候,包含小于phi_val的bond的site都被存在
        #conf里面了
        extup = rightstorage.get_oper(extidx, 1)
        newup = update_rightblockextend_oper(newrightblk, extup, phival)
        extdn = rightstorage.get_oper(extidx, -1)
        newdn = update_rightblockextend_oper(newrightblk, extdn, phival)
        maintain_dict[extidx] = (newup, newdn)
    #把新的rightblock扩展一个格子
    newrightext = extend_rightblock(newrightblk)
    #把哈密顿量也扩展一个格子
    newhamext = extend_rightblock_hamiltonian(newham, newrightext)
    #以后的观测需要的算符,从leftext[phi_idx-1]中拿到,再升级扩展
    #以后放到leftext[phi_idx]中
    ext_meaops = {}
    for prefix, stidx in measure_storage:
        if stidx == phi_idx - 1:  #如果是新加的格子上的算符,不需要升级
            #新建一个观测用的算符
            meaop = create_operator_of_site(newrightext.stbss,
                                            OperFactory.create_by_name(prefix))
            #扩展到leftext[phi_idx]上
            meaop = rightsite_extend_oper(newrightext, meaop)
        else:
            #得到meaop
            meaop = rightstorage.get_meas(prefix, stidx)
            #升级meaop到leftblock[phi_idx]
            meaop = update_rightblockextend_oper(newrightblk, meaop, phival)
            #扩展
            meaop = rightblock_extend_oper(newrightext, meaop)
        ext_meaops['%s,%d' % (prefix, stidx)] = meaop
    #更新缓存的ext,现在存进去就行了,后面在add_hopping_term
    #也是加在这个newhamext上面的
    conf.rightext_reset(phi_idx, newrightext)
    conf.storage_rightext_ham(phi_idx, newhamext)
    #获得新加的格子上面的两个算符
    newsiteup = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_spinup())
    newsitedn = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_spindown())
    #扩展到新的基上
    newsiteup = rightsite_extend_oper(newrightext, newsiteup)
    newsitedn = rightsite_extend_oper(newrightext, newsitedn)
    #maintain_dict[phi_idx-1] = (newsiteup, newsitedn)
    #把maintain_dict中的其他算符也扩展到新的基上
    for idx in maintain_dict:
        extup, extdn = maintain_dict[idx]
        extup = rightblock_extend_oper(newrightext, extup)
        extdn = rightblock_extend_oper(newrightext, extdn)
        maintain_dict[idx] = (extup, extdn)
    maintain_dict[phi_idx - 1] = (newsiteup, newsitedn)
    #加入新的hopping项
    for bnd in newbonds:
        coef_t = conf.model.get_t_coef(bnd, newsiteup.siteidx)
        newhamext.add_hopping_term(maintain_dict[bnd][0], newsiteup, coef_t)
        newhamext.add_hopping_term(maintain_dict[bnd][1], newsitedn, coef_t)
    #把新的格子的U项添加进去
    newiu = create_operator_of_site(newrightext.stbss, OperFactory.create_u())
    newiu = rightsite_extend_oper(newrightext, newiu)
    newhamext.add_u_term(newiu, conf.model.coef_u)
    #把新的格子的Mu项添加进去
    coef_mu = conf.model.get_coef_mu(phi_idx - 1)
    if coef_mu != 0:
        newnu = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_numup())
        newnu = rightsite_extend_oper(newrightext, newnu)
        newhamext.add_mu_term(newnu, coef_mu)
        newnd = create_operator_of_site(newrightext.stbss,
                                        OperFactory.create_numdown())
        newnd = rightsite_extend_oper(newrightext, newnd)
        newhamext.add_mu_term(newnd, coef_mu)
    #保存需要保存的新的ext上面的算符
    for extidx in extoper_storage:
        conf.storage_rightext_oper(phi_idx, maintain_dict[extidx][0])
        conf.storage_rightext_oper(phi_idx, maintain_dict[extidx][1])
    #把需要保存的观测用的算符保存到leftext[phi_idx]当中
    rightstor_phiidx = conf.get_rightext_storage(phi_idx)
    for prefix, stidx in measure_storage:
        meaop = ext_meaops['%s,%d' % (prefix, stidx)]
        rightstor_phiidx.storage_meas(prefix, meaop)
    return ground_erg
Exemplo 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)
Exemplo 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)