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