Beispiel #1
0
    def impsgrowth(self, sites, bonds, osvs, qn=0, ttype=None):
        '''
        Infinite MPS growth.

        Parameters
        ----------
        sites,bonds : list of Label/str
            The site/bond labels/identifiers of the new mps.
        osvs : 1d ndarray
            The old singular values.
        qn : QuantumNumber, optional
            The injected quantum number of the new mps.
        ttype : NOne/'D'/'S', optional
            Tensor type. 'D' for dense, 'S' for sparse and None for automatic.

        Returns
        -------
        MPS
            The imps after growth.
        '''
        if self.nsite > 0:
            assert self.cut == self.nsite // 2 and self.nsite % 2 == 0 and len(
                sites) + 1 == len(bonds)
            ob, nb = self.nsite // 2 + 1, (len(bonds) + 1) // 2
            ns = nb - ob
            cms = self[ob - ns - 1:ob + ns - 1].impsprediction(
                sites[ob - 1:2 * nb - ob - 1],
                bonds[ob - 1:2 * nb - ob],
                osvs,
                qn=qn,
                ttype=ttype)
            lms = MPS([copy(self[pos]) for pos in range(0, self.cut)])
            rms = MPS([copy(self[pos]) for pos in range(self.cut, self.nsite)])
            lms.relabel(sites[:ob - 1], bonds[:ob])
            rms.relabel(sites[-ob + 1:], bonds[-ob:])
            rms.qninject(qn)
            result = MPS(it.chain(lms, cms, rms),
                         Lambda=cms.Lambda,
                         cut=nb - 1,
                         ttype=ttype)
        else:
            bonds = copy(bonds)
            iqns, oqns = (QNS.mono(qn.zero()),
                          QNS.mono(qn)) if isinstance(qn, QN) else (1, 1)
            bonds[+0] = bonds[+0].replace(qns=iqns) if isinstance(
                bonds[+0], Label) else Label(bonds[+0], qns=iqns, flow=None)
            bonds[-1] = bonds[-1].replace(qns=oqns) if isinstance(
                bonds[-1], Label) else Label(bonds[-1], qns=oqns, flow=None)
            result = MPS.random(sites,
                                bonds=bonds,
                                cut=len(sites) // 2,
                                nmax=10,
                                ttype=ttype or 'D')
        return result
Beispiel #2
0
    def impsgrowth(self,sites,bonds,osvs,qn=0,ttype=None):
        '''
        Infinite MPS growth.

        Parameters
        ----------
        sites,bonds : list of Label/str
            The site/bond labels/identifiers of the new mps.
        osvs : 1d ndarray
            The old singular values.
        qn : QuantumNumber, optional
            The injected quantum number of the new mps.
        ttype : NOne/'D'/'S', optional
            Tensor type. 'D' for dense, 'S' for sparse and None for automatic.

        Returns
        -------
        MPS
            The imps after growth.
        '''
        if self.nsite>0:
            assert self.cut==self.nsite//2 and self.nsite%2==0 and len(sites)+1==len(bonds)
            ob,nb=self.nsite//2+1,(len(bonds)+1)//2
            ns=nb-ob
            cms=self[ob-ns-1:ob+ns-1].impsprediction(sites[ob-1:2*nb-ob-1],bonds[ob-1:2*nb-ob],osvs,qn=qn,ttype=ttype)
            lms=MPS([copy(self[pos]) for pos in range(0,self.cut)])
            rms=MPS([copy(self[pos]) for pos in range(self.cut,self.nsite)])
            lms.relabel(sites[:ob-1],bonds[:ob])
            rms.relabel(sites[-ob+1:],bonds[-ob:])
            rms.qninject(qn)
            result=MPS(it.chain(lms,cms,rms),Lambda=cms.Lambda,cut=nb-1,ttype=ttype)
        else:
            bonds=copy(bonds)
            iqns,oqns=(QNS.mono(qn.zero()),QNS.mono(qn)) if isinstance(qn,QN) else (1,1)
            bonds[+0]=bonds[+0].replace(qns=iqns) if isinstance(bonds[+0],Label) else Label(bonds[+0],qns=iqns,flow=None)
            bonds[-1]=bonds[-1].replace(qns=oqns) if isinstance(bonds[-1],Label) else Label(bonds[-1],qns=oqns,flow=None)
            result=MPS.random(sites,bonds=bonds,cut=len(sites)//2,nmax=10,ttype=ttype or 'D')
        return result
Beispiel #3
0
    def tompo(self, ttype='D', **karg):
        '''
        Convert to the tensor-formatted mpo.

        Parameters
        ----------
        ttype : 'D'/'S', optional
            Tensor type. 'D' for dense and 'S' for sparse.
        karg : dict with keys containing 'nsweep','method' and 'options'
            Please see MPO.compress for details.

        Returns
        -------
        MPO
            The corresponding tensor-formatted MPO.
        '''
        Ms = []
        type = self[0][0, 0].site.qns.type if isinstance(
            self[0][0, 0].site.qns, QuantumNumbers) else None
        for pos, m in enumerate(self):
            dim = self.sites[pos].dim
            L = Label(self.bonds[pos], qns=m.shape[0], flow=0)
            U = self.sites[pos].replace(prime=True, qns=dim, flow=0)
            D = self.sites[pos].replace(qns=dim, flow=0)
            R = Label(self.bonds[pos + 1], qns=m.shape[1], flow=0)
            Ms.append(
                DTensor(np.zeros((m.shape[0], dim, dim, m.shape[1]),
                                 dtype=self.dtype),
                        labels=[L, U, D, R]))
            for i, j in it.product(range(m.shape[0]), range(m.shape[1])):
                Ms[-1].data[i, :, :, j] = m[i, j].matrix
        result = MPO(Ms)
        result.compress(**karg)
        if type is not None:
            for pos in range(len(result)):
                lqns, sqns = QuantumNumbers.mono(
                    type.zero()) if pos == 0 else result[pos - 1].labels[
                        MPO.R].qns, self.sites[pos].qns
                result[pos].qngenerate(flow=-1,
                                       axes=[MPO.L, MPO.U, MPO.D],
                                       qnses=[lqns, sqns, sqns],
                                       flows=[1, 1, -1])
        if ttype == 'S':
            assert issubclass(type, QuantumNumber)
            for i, m in enumerate(result):
                m.qnsort()
                result[i] = m.tostensor()
        return result
Beispiel #4
0
    def tompo(self,degfres,ttype='D'):
        '''
        Convert an optstr to the full-formatted mpo.

        Parameters
        ----------
        degfres : DegFreTree
            The tree of the site degrees of freedom.
        ttype : 'D'/'S', optional
            Tensor type. 'D' for dense and 'S' for sparse.

        Returns
        -------
        MPO
            The corresponding MPO.
        '''
        index=self[0].site.identifier
        type,layer=degfres.dtype,degfres.layers[degfres.level(index)-1]
        table,sites,bonds=degfres.table(layer),degfres.labels('S',layer),degfres.labels('O',layer)
        poses,matrices=set(table[opt.site.identifier] for opt in self),[opt.matrix for opt in self]
        ms,count=[],0
        for pos in range(len(sites)):
            ndegfre=sites[pos].dim
            if issubclass(type,QuantumNumbers):
                L=Label(bonds[pos],qns=QuantumNumbers.mono(type.zero()) if pos==0 else ms[-1].labels[MPO.R].qns,flow=None)
                U=sites[pos].P
                D=copy(sites[pos])
                R=Label(bonds[pos+1],qns=1,flow=None)
            else:
                L=Label(bonds[pos],qns=1,flow=0)
                U=sites[pos].P.replace(flow=0)
                D=sites[pos].replace(flow=0)
                R=Label(bonds[pos+1],qns=1,flow=0)
            if pos in poses:
                ms.append(DTensor(np.asarray(matrices[count],dtype=self.dtype).reshape((1,ndegfre,ndegfre,1)),labels=[L,U,D,R]))
                count+=1
            else:
                ms.append(DTensor(np.identity(ndegfre,dtype=self.dtype).reshape((1,ndegfre,ndegfre,1)),labels=[L,U,D,R]))
            if issubclass(type,QuantumNumbers): ms[-1].qngenerate(flow=-1,axes=[MPO.L,MPO.U,MPO.D],qnses=[L.qns,U.qns,D.qns],flows=[1,1,-1])
        if ttype=='S':
            assert issubclass(type,QuantumNumbers)
            for m in ms: m.qnsort()
            ms=[m.tostensor() for m in ms]
        return MPO(ms)
Beispiel #5
0
    def tompo(self,ttype='D',**karg):
        '''
        Convert to the tensor-formatted mpo.

        Parameters
        ----------
        ttype : 'D'/'S', optional
            Tensor type. 'D' for dense and 'S' for sparse.
        karg : dict with keys containing 'nsweep','method' and 'options'
            Please see MPO.compress for details.

        Returns
        -------
        MPO
            The corresponding tensor-formatted MPO.
        '''
        Ms=[]
        type=self[0][0,0].site.qns.type if isinstance(self[0][0,0].site.qns,QuantumNumbers) else None
        for pos,m in enumerate(self):
            dim=self.sites[pos].dim
            L=Label(self.bonds[pos],qns=m.shape[0],flow=0)
            U=self.sites[pos].replace(prime=True,qns=dim,flow=0)
            D=self.sites[pos].replace(qns=dim,flow=0)
            R=Label(self.bonds[pos+1],qns=m.shape[1],flow=0)
            Ms.append(DTensor(np.zeros((m.shape[0],dim,dim,m.shape[1]),dtype=self.dtype),labels=[L,U,D,R]))
            for i,j in it.product(range(m.shape[0]),range(m.shape[1])):
                Ms[-1].data[i,:,:,j]=m[i,j].matrix
        result=MPO(Ms)
        result.compress(**karg)
        if type is not None:
            for pos in range(len(result)):
                lqns,sqns=QuantumNumbers.mono(type.zero()) if pos==0 else result[pos-1].labels[MPO.R].qns,self.sites[pos].qns
                result[pos].qngenerate(flow=-1,axes=[MPO.L,MPO.U,MPO.D],qnses=[lqns,sqns,sqns],flows=[1,1,-1])
        if ttype=='S':
            assert issubclass(type,QuantumNumber)
            for i,m in enumerate(result):
                m.qnsort()
                result[i]=m.tostensor()
        return result
Beispiel #6
0
    def to_mpo(self,**karg):
        '''
        Convert to the tensor-formatted mpo.

        Parameters
        ----------
        karg : dict with keys containing 'nsweep','method' and 'options'
            Please see MPO.compress for details.

        Returns
        -------
        MPO
            The corresponding tensor-formatted MPO.
        '''
        Ms=[]
        type=self[0][0,0].site.qns.type if isinstance(self[0][0,0].site.qns,QuantumNumbers) else None
        for pos,m in enumerate(self):
            dim=self.sites[pos].dim
            if type is None:
                L=self.bonds[pos].replace(qns=m.shape[0],flow=0)
                U=self.sites[pos].replace(prime=True,flow=0)
                D=self.sites[pos].replace(flow=0)
                R=self.bonds[pos+1].replace(qns=m.shape[1],flow=0)
            else:
                L=copy(self.bonds[pos])
                U=self.sites[pos].P
                D=self.sites[pos]
                R=copy(self.bonds[pos+1])
            Ms.append(DTensor(np.zeros((m.shape[0],dim,dim,m.shape[1]),dtype=dtype),labels=[L,U,D,R]))
            for i,j in it.product(xrange(m.shape[0]),xrange(m.shape[1])):
                Ms[-1][i,:,:,j]=m[i,j].matrix
        result=MPO(Ms)
        result.compress(**karg)
        if type is not None:
            for pos in xrange(len(result)):
                lqns,sqns=QuantumNumbers.mono(type.zero()) if pos==0 else result[pos-1].labels[MPO.R].qns,self.sites[pos].qns
                result[pos].qngenerate(flow=-1,axes=[MPO.L,MPO.U,MPO.D],qnses=[lqns,sqns,sqns],flows=[1,1,-1])
        return result
Beispiel #7
0
    def to_mpo(self,degfres):
        '''
        Convert an optstr to the full-formatted mpo.

        Parameters
        ----------
        degfres : DegFreTree
            The tree of the site degrees of freedom.

        Returns
        -------
        MPO
            The corresponding MPO.
        '''
        index=self[0].site.identifier
        type,layer=degfres[index].type if degfres.mode=='QN' else None,degfres.layers[degfres.level(index)-1]
        table,sites,bonds=degfres.table(layer),degfres.labels('S',layer),degfres.labels('O',layer)
        poses,matrices=set(table[opt.site.identifier] for opt in self),[opt.matrix for opt in self]
        ms,count=[],0
        for pos in xrange(len(sites)):
            ndegfre=sites[pos].dim
            if degfres.mode=='QN':
                L=bonds[pos].replace(qns=QuantumNumbers.mono(type.zero()) if pos==0 else ms[-1].labels[MPO.R].qns)
                U=sites[pos].P
                D=copy(sites[pos])
                R=bonds[pos+1].replace(qns=1)
            else:
                L=bonds[pos].replace(qns=1,flow=0)
                U=sites[pos].P.replace(flow=0)
                D=sites[pos].replace(flow=0)
                R=bonds[pos+1].replace(qns=1,flow=0)
            if pos in poses:
                ms.append(DTensor(np.asarray(matrices[count],dtype=self.dtype).reshape((1,ndegfre,ndegfre,1)),labels=[L,U,D,R]))
                count+=1
            else:
                ms.append(DTensor(np.identity(ndegfre,dtype=self.dtype).reshape((1,ndegfre,ndegfre,1)),labels=[L,U,D,R]))
            if degfres.mode=='QN': ms[-1].qngenerate(flow=-1,axes=[MPO.L,MPO.U,MPO.D],qnses=[L.qns,U.qns,D.qns],flows=[1,1,-1])
        return MPO(ms)
Beispiel #8
0
    def random(sites, bonds=None, cut=None, nmax=None, dtype=np.float64):
        '''
        Generate a random mps.

        Parameters
        ----------
        sites : list of Label/int/QuantumNumbers
            The labels/number-of-degrees-of-freedom/quantum-numbers of the physical legs.
        bonds : optional
            * list of Label
                The labels of the virtual legs.
            * 2-list of QuantumNumber
                The quantum number of the first and last virtual legs.
        cut : int, optional
            The index of the connecting link.
        nmax : int, optional
            The maximum number of singular values to be kept.
        dtype : np.float64, np.complex128, optional
            The data type of the random mps.

        Returns
        -------
        MPS
            The random mixed-canonical mps.
        '''
        np.random.seed()
        sites = [
            site if isinstance(site, Label) else Label(
                '__MPS_RANDOM_S_%s__' % i, qns=site)
            for i, site in enumerate(sites)
        ]
        if bonds is not None and all(
                isinstance(bond, Label) for bond in bonds):
            assert len(bonds) == len(sites) + 1
        else:
            if bonds is not None:
                assert len(bonds) == 2 and isinstance(
                    bonds[0], QN) and isinstance(bonds[1], QN)
            iqns, oqns = (QNS.mono(bonds[0]),
                          QNS.mono(bonds[1])) if bonds is not None else (1, 1)
            bonds = [
                Label(
                    '__MPS_RANDOM_B_%s__' % i,
                    qns=iqns if i == 0 else oqns if i == len(sites) else None)
                for i in xrange(len(sites) + 1)
            ]
        mode, shape = 'QN' if next(iter(sites)).qnon else 'NB', tuple(
            [site.dim for site in sites])
        if mode == 'QN':
            result = 0
            if dtype in (np.float32, np.float64):
                coeffs = np.random.random(nmax)
            else:
                coeffs = np.random.random(nmax) + 1j * np.random.random(nmax)
            for k, indices in enumerate(
                    QNS.decomposition([site.qns for site in sites],
                                      bonds[-1].qns[0] - bonds[0].qns[0],
                                      method='monte carlo',
                                      nmax=nmax)):
                ms = [
                    np.array(
                        [1.0 if i == index else 0.0 for i in xrange(site.dim)],
                        dtype=dtype) for site, index in zip(sites, indices)
                ]
                result += MPS.productstate(ms, sites, copy(bonds)) * coeffs[k]
        else:
            ms = []
            for i in xrange(len(sites)):
                if dtype in (np.float32, np.float64):
                    ms.append(np.random.random((nmax, shape[i], nmax)))
                else:
                    ms.append(
                        np.random.random((nmax, shape[i], nmax)) +
                        1j * np.random.random((nmax, shape[i], nmax)))
            result = MPS(mode=mode, ms=ms, sites=sites, bonds=bonds)
        if cut is None:
            result.canonicalize(cut=len(sites) / 2, nmax=nmax)
            result._merge_ABL_()
        else:
            result.canonicalize(cut=cut, nmax=nmax)
        return result
Beispiel #9
0
    def random(sites,
               bonds=None,
               cut=None,
               nmax=None,
               ttype='D',
               dtype=np.float64):
        '''
        Generate a random mps.

        Parameters
        ----------
        sites : list of Label/int/QuantumNumbers
            The labels/number-of-degrees-of-freedom/quantum-numbers of the physical legs.
        bonds : optional
            * list of Label/str
                The labels/identifiers of the virtual legs.
            * 2-list of QuantumNumber
                The quantum number of the first and last virtual legs.
        cut : int, optional
            The index of the connecting link.
        nmax : int, optional
            The maximum number of singular values to be kept.
        ttype : 'D'/'S', optional
            Tensor type. 'D' for dense and 'S' for sparse.
        dtype : np.float64, np.complex128, optional
            The data type of the random mps.

        Returns
        -------
        MPS
            The random mixed-canonical mps.
        '''
        np.random.seed()
        sites = [
            site if isinstance(site, Label) else Label(
                '__MPS_RANDOM_S_%s__' % i, qns=site)
            for i, site in enumerate(sites)
        ]
        if bonds is None or not isinstance(bonds[+0], Label) or not isinstance(
                bonds[-1], Label):
            if bonds is not None:
                iqns = bonds[+0].qns if isinstance(
                    bonds[+0], Label) else bonds[+0] if isinstance(
                        bonds[+0], QNS) else QNS.mono(bonds[+0]) if isinstance(
                            bonds[+0], QN) else 1
                oqns = bonds[-1].qns if isinstance(
                    bonds[-1], Label) else bonds[-1] if isinstance(
                        bonds[-1], QNS) else QNS.mono(bonds[-1]) if isinstance(
                            bonds[-1], QN) else 1
            else:
                iqns, oqns = 1, 1
            bonds = [
                Label('__MPS_RANDOM_B_%s__' % i, None, None)
                for i in range(len(sites) + 1)
            ]
            bonds[+0] = bonds[+0].replace(qns=iqns)
            bonds[-1] = bonds[-1].replace(qns=oqns)
        else:
            assert len(bonds) == len(sites) + 1
            bonds = [
                bond if isinstance(bond, Label) else Label(bond, None, None)
                for bond in bonds
            ]
        qnon, shape = next(iter(sites)).qnon, tuple(
            [site.dim for site in sites])
        if ttype == 'S': assert qnon
        if qnon:
            result = 0
            if dtype in (np.float32, np.float64):
                coeffs = np.random.random(nmax)
            else:
                coeffs = np.random.random(nmax) + 1j * np.random.random(nmax)
            for k, indices in enumerate(
                    QNS.decomposition([site.qns for site in sites],
                                      bonds[-1].qns[0] - bonds[+0].qns[0],
                                      method='monte carlo',
                                      nmax=nmax)):
                ms = [
                    np.array(
                        [1.0 if i == index else 0.0 for i in range(site.dim)],
                        dtype=dtype) for site, index in zip(sites, indices)
                ]
                result += MPS.productstate(ms, sites, copy(bonds)) * coeffs[k]
            if ttype == 'S':
                for m in result:
                    m.qnsort()
                result = result.tosparse()
        else:
            ms = []
            for i in range(len(sites)):
                if dtype in (np.float32, np.float64):
                    ms.append(np.random.random((nmax, shape[i], nmax)))
                else:
                    ms.append(
                        np.random.random((nmax, shape[i], nmax)) +
                        1j * np.random.random((nmax, shape[i], nmax)))
            result = MPS.compose(ms=ms, sites=sites, bonds=bonds)
        if cut is None:
            result.canonicalize(cut=len(sites) / 2, nmax=nmax)
            result._merge_ABL_()
        else:
            result.canonicalize(cut=cut, nmax=nmax)
        return result
Beispiel #10
0
    def random(sites,bonds=None,cut=None,nmax=None,ttype='D',dtype=np.float64):
        '''
        Generate a random mps.

        Parameters
        ----------
        sites : list of Label/int/QuantumNumbers
            The labels/number-of-degrees-of-freedom/quantum-numbers of the physical legs.
        bonds : optional
            * list of Label/str
                The labels/identifiers of the virtual legs.
            * 2-list of QuantumNumber
                The quantum number of the first and last virtual legs.
        cut : int, optional
            The index of the connecting link.
        nmax : int, optional
            The maximum number of singular values to be kept.
        ttype : 'D'/'S', optional
            Tensor type. 'D' for dense and 'S' for sparse.
        dtype : np.float64, np.complex128, optional
            The data type of the random mps.

        Returns
        -------
        MPS
            The random mixed-canonical mps.
        '''
        np.random.seed()
        sites=[site if isinstance(site,Label) else Label('__MPS_RANDOM_S_%s__'%i,qns=site) for i,site in enumerate(sites)]
        if bonds is None or not isinstance(bonds[+0],Label) or not isinstance(bonds[-1],Label):
            if bonds is not None:
                iqns=bonds[+0].qns if isinstance(bonds[+0],Label) else bonds[+0] if isinstance(bonds[+0],QNS) else QNS.mono(bonds[+0]) if isinstance(bonds[+0],QN) else 1
                oqns=bonds[-1].qns if isinstance(bonds[-1],Label) else bonds[-1] if isinstance(bonds[-1],QNS) else QNS.mono(bonds[-1]) if isinstance(bonds[-1],QN) else 1
            else:
                iqns,oqns=1,1
            bonds=[Label('__MPS_RANDOM_B_%s__'%i,None,None) for i in range(len(sites)+1)]
            bonds[+0]=bonds[+0].replace(qns=iqns)
            bonds[-1]=bonds[-1].replace(qns=oqns)
        else:
            assert len(bonds)==len(sites)+1
            bonds=[bond if isinstance(bond,Label) else Label(bond,None,None) for bond in bonds]
        qnon,shape=next(iter(sites)).qnon,tuple([site.dim for site in sites])
        if ttype=='S': assert qnon
        if qnon:
            result=0
            if dtype in (np.float32,np.float64):
                coeffs=np.random.random(nmax)
            else:
                coeffs=np.random.random(nmax)+1j*np.random.random(nmax)
            for k,indices in enumerate(QNS.decomposition([site.qns for site in sites],bonds[-1].qns[0]-bonds[+0].qns[0],method='monte carlo',nmax=nmax)):
                ms=[np.array([1.0 if i==index else 0.0 for i in range(site.dim)],dtype=dtype) for site,index in zip(sites,indices)]
                result+=MPS.productstate(ms,sites,copy(bonds))*coeffs[k]
            if ttype=='S':
                for m in result: m.qnsort()
                result=result.tosparse()
        else:
            ms=[]
            for i in range(len(sites)):
                if dtype in (np.float32,np.float64):
                    ms.append(np.random.random((nmax,shape[i],nmax)))
                else:
                    ms.append(np.random.random((nmax,shape[i],nmax))+1j*np.random.random((nmax,shape[i],nmax)))
            result=MPS.compose(ms=ms,sites=sites,bonds=bonds)
        if cut is None:
            result.canonicalize(cut=len(sites)/2,nmax=nmax)
            result._merge_ABL_()
        else:
            result.canonicalize(cut=cut,nmax=nmax)
        return result
Beispiel #11
0
    def tompo(self, degfres, ttype='D'):
        '''
        Convert an optstr to the full-formatted mpo.

        Parameters
        ----------
        degfres : DegFreTree
            The tree of the site degrees of freedom.
        ttype : 'D'/'S', optional
            Tensor type. 'D' for dense and 'S' for sparse.

        Returns
        -------
        MPO
            The corresponding MPO.
        '''
        index = self[0].site.identifier
        type, layer = degfres.dtype, degfres.layers[degfres.level(index) - 1]
        table, sites, bonds = degfres.table(layer), degfres.labels(
            'S', layer), degfres.labels('O', layer)
        poses, matrices = set(table[opt.site.identifier]
                              for opt in self), [opt.matrix for opt in self]
        ms, count = [], 0
        for pos in range(len(sites)):
            ndegfre = sites[pos].dim
            if issubclass(type, QuantumNumbers):
                L = Label(bonds[pos],
                          qns=QuantumNumbers.mono(type.zero())
                          if pos == 0 else ms[-1].labels[MPO.R].qns,
                          flow=None)
                U = sites[pos].P
                D = copy(sites[pos])
                R = Label(bonds[pos + 1], qns=1, flow=None)
            else:
                L = Label(bonds[pos], qns=1, flow=0)
                U = sites[pos].P.replace(flow=0)
                D = sites[pos].replace(flow=0)
                R = Label(bonds[pos + 1], qns=1, flow=0)
            if pos in poses:
                ms.append(
                    DTensor(np.asarray(matrices[count],
                                       dtype=self.dtype).reshape(
                                           (1, ndegfre, ndegfre, 1)),
                            labels=[L, U, D, R]))
                count += 1
            else:
                ms.append(
                    DTensor(np.identity(ndegfre, dtype=self.dtype).reshape(
                        (1, ndegfre, ndegfre, 1)),
                            labels=[L, U, D, R]))
            if issubclass(type, QuantumNumbers):
                ms[-1].qngenerate(flow=-1,
                                  axes=[MPO.L, MPO.U, MPO.D],
                                  qnses=[L.qns, U.qns, D.qns],
                                  flows=[1, 1, -1])
        if ttype == 'S':
            assert issubclass(type, QuantumNumbers)
            for m in ms:
                m.qnsort()
            ms = [m.tostensor() for m in ms]
        return MPO(ms)