Ejemplo n.º 1
0
def rightext_oper_to_superblock(sbext: SuperBlockExtend, oper: BaseOperator):
    '''把rightblockextend基上面的算符扩展到superblock上\n
    Issue#2: 优化算法以提升速度
    '''
    #原本的算符在|s^n+1, phi^N-(n+1)>上
    #现在要弄到 |phi^n-1, s^n, s^n+1, phi^N-(n+1)>上
    # O' = I X O,这时的算符会经过phi^n-1和s^n中所有的产生算符
    #才能到|s^n+1, phi^N-(n+1)>上
    eyedim = sbext.leftblockextend.dim
    opermat = oper.mat.todok()\
        if scipy.sparse.isspmatrix_coo(oper.mat) else oper.mat
    speye = None
    if oper.isferm:
        eyevals = []
        for idx in sbext.leftblockextend.iter_idx():
            _pnum = sbext.leftblockextend.spin_nums[idx]
            _partinum = numpy.sum(_pnum)
            eyevals.append(1. if _partinum % 2 == 0 else -1.)
            speye = scipy.sparse.dia_matrix((eyevals, 0),
                                            shape=(eyedim, eyedim))
    else:
        speye = scipy.sparse.eye(eyedim)
    speye = speye.tocsr()
    #
    block_arr = numpy.array([[None]*sbext.rightblockextend.dim]\
        *sbext.rightblockextend.dim)
    idxllist, idxrlist = opermat.nonzero()
    for lidx, ridx in zip(idxllist, idxrlist):
        block_arr[lidx, ridx] = speye.multiply(opermat[lidx, ridx])
    for idx in range(sbext.rightblockextend.dim):
        if block_arr[idx, idx] is None:
            block_arr[idx, idx] = scipy.sparse.dok_matrix((eyedim, eyedim))
    mat = scipy.sparse.bmat(block_arr)
    return BaseOperator(oper.siteidx, sbext, oper.isferm, mat, spin=oper.spin)
Ejemplo n.º 2
0
def create_operator_of_site(basis: SiteBasis, tup: OPERTUP):
    '''从一个site创建,spin = 1代表向上,spin=-1代表向下
    '''
    if len(basis.sites) > 1:
        raise NotImplementedError('多个格子的不去实现')
    stidx = basis.sites[0]
    mat = scipy.sparse.csr_matrix(tup.mat)
    return BaseOperator(stidx, basis, tup.isferm, mat, spin=tup.spin)
Ejemplo n.º 3
0
def update_rightblockextend_oper(newrbk: RightBlock, oper: BaseOperator,
                                 spphival):
    '''利用21.19左右的式子'''
    #if not isinstance(phival, numpy.ndarray):
    #    raise ValueError('phival不是ndarray')
    if not scipy.sparse.issparse(spphival):
        raise ValueError('spphival不是稀疏矩阵')
    mat = oper.mat * spphival.transpose()
    mat = spphival * mat
    return BaseOperator(oper.siteidx, newrbk, oper.isferm, mat, spin=oper.spin)
Ejemplo n.º 4
0
def leftext_oper_to_superblock(sbext: SuperBlockExtend, oper: BaseOperator):
    '''将leftblockextend上面的算符扩展到superblockextend'''
    #原本的算符在|phi^n-1, s^n>上面
    #现在增加到|phi^n-1, s^n, s^n+1, phi^N-(n+1)>
    #没有影响正常的算符顺序,不会有反对易的符号所以扩展的方式和哈密顿量是差不多的
    #
    highbit = sbext.rightblockextend.dim
    lowbitlen = sbext.leftblockextend.dim
    if lowbitlen != oper.basis.dim:
        raise ValueError('算符的基不一致')
    #
    mat = scipy.sparse.block_diag([oper.mat] * highbit)
    return BaseOperator(oper.siteidx, sbext, oper.isferm, mat, spin=oper.spin)
Ejemplo n.º 5
0
def rightsite_extend_oper(rightext: RightBlockExtend, oper: BaseOperator):
    '''将RightBlockExtend中的site扩展到RightBlockExtend中'''
    opdim = oper.basis.dim
    if rightext.stbss.dim != opdim:
        raise ValueError('oper.basis.dim和RightBlockExtend.stbss.dim对不上')
    #这个时候是没有交换的符号的问题的,因为site在前面
    #这个时候rlbk在高位,只有他们相等时才有数值
    mat = scipy.sparse.block_diag([oper.mat] * rightext.rblk.dim)
    #
    return BaseOperator(oper.siteidx,
                        rightext,
                        oper.isferm,
                        mat,
                        spin=oper.spin)
Ejemplo n.º 6
0
def leftsite_extend_oper(leftext: LeftBlockExtend, oper: BaseOperator):
    '''将LeftBlockExtend.stbss上面的算符扩展到LeftBlockExtend上
    这里利用的是21.15左右的公式,加上了反对易
    Issue#3: 优化速度
    '''
    opdim = oper.basis.dim
    if leftext.stbss.dim != opdim:
        raise ValueError('oper.basis.dim和LeftBlockExtend.stbss.dim对应不上')
    opermat = oper.mat.todok()\
        if scipy.sparse.isspmatrix_coo(oper.mat) else oper.mat
    #需要处理反对易的符号
    #|A_1,A_2,..A_n> = C_1C_2..C_n|0>
    #C_n|A_1,A_2..> = C_nC_1C_2..|0> = (-1)^a C_1C_2..C_n|0>
    #其中a的数量是phi^n-1中的粒子数,因为phi^n-1是和粒子数的共同本征态
    eyedim = leftext.lblk.dim
    #
    speye = None
    if oper.isferm:
        #如果是反对易的,统计block中的算符数目
        eyeval = []
        #eye(eyedim)
        #numpy.zeros([eyedim, eyedim])
        for idx in leftext.lblk.iter_idx():
            _pnum = leftext.lblk.spin_nums[idx]
            _partinum = numpy.sum(_pnum)
            eyeval.append(1.0 if _partinum % 2 == 0 else -1.0)
            #speye[idx, idx] = 1.0 if _partinum % 2 == 0 else -1.0
        speye = scipy.sparse.dia_matrix((eyeval, 0), shape=(eyedim, eyedim))
        #speye = speye.tocsr()
    else:
        speye = scipy.sparse.eye(eyedim)
    #
    block_arr = []
    for lidx in leftext.stbss.iter_idx():
        row = []
        block_arr.append(row)
        for ridx in leftext.stbss.iter_idx():
            if opermat[lidx, ridx] == 0:
                if lidx == ridx:
                    row.append(scipy.sparse.csr_matrix((eyedim, eyedim)))
                else:
                    row.append(None)
            else:
                row.append(speye.multiply(opermat[lidx, ridx]))
    mat = scipy.sparse.bmat(block_arr)
    return BaseOperator(oper.siteidx,
                        leftext,
                        oper.isferm,
                        mat,
                        spin=oper.spin)
Ejemplo n.º 7
0
def leftblock_extend_oper(leftext: LeftBlockExtend, oper: BaseOperator):
    '''oper需要是在leftext.lbkl上面的算符
    这个函数把oper扩展到leftext上面
    这里利用的是21.15左右的公式
    '''
    #
    opdim = oper.basis.dim
    if leftext.lblk.dim != opdim:
        raise ValueError('LeftBlockExtend.lblk.dim和oper的dim对应不上')
    #在leftblock中的算符是已经把符号处理好的
    #直接扩展到新的基上就行了
    #只有idx2相等的时候才能有数值
    mat = scipy.sparse.block_diag([oper.mat] * 4)
    return BaseOperator(oper.siteidx,
                        leftext,
                        oper.isferm,
                        mat,
                        spin=oper.spin)
Ejemplo n.º 8
0
def rightblock_extend_oper(rightext: RightBlockExtend, oper: BaseOperator):
    '''把rightblock.rblk下的算符扩展到
    rightblockextend上面
    Issue#3:优化速度
    '''
    opdim = oper.basis.dim
    if rightext.rblk.dim != opdim:
        raise ValueError('oper.basis.dim和RightBlockExtend.rblk.dim对应不上')
    opermat = oper.mat.todok()\
        if scipy.sparse.isspmatrix_coo(oper.mat) else oper.mat
    #需要处理反对易的符号
    #|A_1,A_2,..A_n> = C_1C_2..C_n|0>
    #在Cm|phi^n_beta> = |phi^n_beta'>的情况下
    #Cm|s^n-1,phi^n_beta> = -C^n-1Cm|0, phi^n_beta>
    #所以在扩展rightblock中的算符的时候,要看n-1上面有几个粒子
    eyedim = rightext.stbss.dim
    speye = None
    if oper.isferm:
        #如果是反对易的,统计block中的算符数目
        eyevals = []
        for idx in rightext.stbss.iter_idx():
            _pnum = rightext.stbss.partinum[idx]
            _partinum = numpy.sum(_pnum)
            eyevals.append(1.0 if _partinum % 2 == 0 else -1.0)
        speye = scipy.sparse.dia_matrix((eyevals, 0), shape=(eyedim, eyedim))
    else:
        speye = scipy.sparse.eye(eyedim)
    speye = speye.tocsr()
    #
    block_arr = numpy.array([[None] * rightext.rblk.dim] * rightext.rblk.dim)
    idxllist, idxrlist = opermat.nonzero()
    for lidx, ridx in zip(idxllist, idxrlist):
        block_arr[lidx, ridx] = speye.multiply(opermat[lidx, ridx])
    for idx in range(rightext.rblk.dim):
        if block_arr[idx, idx] is None:
            block_arr[idx, idx] = scipy.sparse.dok_matrix((eyedim, eyedim))
    mat = scipy.sparse.bmat(block_arr)
    return BaseOperator(oper.siteidx,
                        rightext,
                        oper.isferm,
                        mat,
                        spin=oper.spin)