예제 #1
0
파일: HOTRG.py 프로젝트: CaoRX/CTL
    def directedIterateTrial(self, d):
        funcs.assertInSet(d, ['u', 'd', 'l', 'r'], 'direction')
        # make projector, and return the truncation error
        # for l: use M, M', calculate MM', return U_L
        if (d == 'l') or (d == 'r'):
            # horizontal project
            squareTensor = self.horizontalProjectFTN[d].contract(
                makeSquareTensorDict(self.a))
            # l, r
            # labels = [d, funcs.oppositeDirection(d)]
            # print('a = {}'.format(self.a))
            # print('squareTensor = {}'.format(squareTensor))
            squareMat = squareTensor.toMatrix(
                rows=[d], cols=[funcs.oppositeDirection(d)])
            # print(squareTensor)
            prjMat, error = linalgFuncs.solveEnv(squareMat, self.chiH)
            # prjTensor = Tensor(data = prjMat, shape = (chiH ** 2, prjMat.shape[1]), labels = ['i', 'o'])
        else:
            squareTensor = self.verticalProjectFTN[d].contract(
                makeSquareTensorDict(self.a))
            # print('a = {}'.format(self.a))
            # print('squareTensor = {}'.format(squareTensor))
            squareMat = squareTensor.toMatrix(
                rows=[d], cols=[funcs.oppositeDirection(d)])
            prjMat, error = linalgFuncs.solveEnv(squareMat, self.chiV)
            # prjTensor = Tensor(data = prjMat, shape = (chiV ** 2, prjMat.shape[1]), labels = ['i', 'o'])

        # envTrace = xplib.xp.trace(squareMat)
        # envTraceApprox = xplib.xp.trace(prjMat.T @ squareMat @ prjMat)
        # error = (envTrace - envTraceApprox) / envTrace
        # deltaTensor = (prjMat.T @ squareMat @ prjMat) - squareMat
        # error = xplib.xp.linalg.norm(deltaTensor) / xplib.xp.linalg.norm(squareMat)
        return {'error': error, 'projectTensor': prjMat}
예제 #2
0
def squareVerticalContractFTN(d):
    funcs.assertInSet(d, ['u', 'd'], 'vertical direction')
    opd = funcs.oppositeSingleDirection(d)
    FTN = FiniteTensorNetwork(tensorNames=['ul', 'ur', 'dr', 'dl'])

    FTN.addLink('ul', opd, 'dl', opd)
    FTN.addLink('ul', 'r', 'ur', 'l')
    FTN.addLink('ur', opd, 'dr', opd)
    FTN.addLink('dl', 'r', 'dr', 'l')

    FTN.addLink('ul', 'l', 'dl', 'l')
    FTN.addLink('ur', 'r', 'dr', 'r')

    FTN.addPostOutProduct([d + 'l-' + d, d + 'r-' + d], d)
    FTN.addPostOutProduct([opd + 'l-' + d, opd + 'r-' + d], opd)
    return FTN
예제 #3
0
파일: HOTRG.py 프로젝트: CaoRX/CTL
 def directedIterate(self,
                     d,
                     prjTensor,
                     inputTensor1=None,
                     inputTensor2=None):
     # print(inputTensor1, inputTensor2)
     # print(prjTensor.shape)
     funcs.assertInSet(d, ['u', 'd', 'l', 'r'], 'direction')
     # use the real projector for iteration
     if (inputTensor1 is None):
         inputTensor1 = self.a
     if (inputTensor2 is None):
         inputTensor2 = self.a
     chiH = inputTensor1.shapeOfLabel('l')
     chiV = inputTensor1.shapeOfLabel('u')
     if (d == 'l') or (d == 'r'):
         # given U_L:
         # the prjTensor
         lTensor = Tensor(data=prjTensor,
                          shape=(chiH, chiH, prjTensor.shape[1]),
                          labels=['u', 'd', 'o'])
         rTensor = Tensor(data=funcs.transposeConjugate(prjTensor),
                          shape=(prjTensor.shape[1], chiH, chiH),
                          labels=['o', 'u', 'd'])
         if (d == 'r'):
             lTensor, rTensor = rTensor, lTensor
         return self.horizontalIterateFTN.contract({
             'u': inputTensor1,
             'd': inputTensor2,
             'l': lTensor,
             'r': rTensor
         })
     else:
         uTensor = Tensor(data=prjTensor,
                          shape=(chiV, chiV, prjTensor.shape[1]),
                          labels=['l', 'r', 'o'])
         dTensor = Tensor(data=funcs.transposeConjugate(prjTensor),
                          shape=(prjTensor.shape[1], chiV, chiV),
                          labels=['o', 'l', 'r'])
         if (d == 'd'):
             uTensor, dTensor = dTensor, uTensor
         return self.verticalIterateFTN.contract({
             'u': uTensor,
             'd': dTensor,
             'l': inputTensor1,
             'r': inputTensor2
         })
예제 #4
0
def squareHorizontalContractFTN(d):
    # TODO: add docstrings for following functions
    funcs.assertInSet(d, ['l', 'r'], 'horizontal direction')
    opd = funcs.oppositeSingleDirection(d)
    FTN = FiniteTensorNetwork(tensorNames=['ul', 'ur', 'dr', 'dl'])

    FTN.addLink('ul', 'd', 'dl', 'u')
    FTN.addLink('ul', opd, 'ur', opd)
    FTN.addLink('ur', 'd', 'dr', 'u')
    FTN.addLink('dl', opd, 'dr', opd)

    FTN.addLink('ul', 'u', 'ur', 'u')
    FTN.addLink('dl', 'd', 'dr', 'd')

    FTN.addPostOutProduct(['u' + d + '-' + d, 'd' + d + '-' + d], d)
    FTN.addPostOutProduct(['u' + opd + '-' + d, 'd' + opd + '-' + d], opd)
    return FTN
예제 #5
0
파일: Ising.py 프로젝트: CaoRX/CTL
def squareTensorMeasure(idx, obs=None):
    """
    Local measurement on a square of four Ising spins.

    Parameters
    ----------
    idx : (4, ) tuple of {0, 1}
        The local spins on the square.
    obs : str, {'M', 'E'}, optional
        The observable to be measured. If None, then return 1.0.

    Returns
    -------
    float
        If obs is 'M': return the local magnetization(since each site is shared by two squares if we divide the system into such squares, only 0.5 counted for one spin).
        If obs is 'E': return the local energy(if neighbor spin is equal, then -1, else +1)
        If obs is None: considering partition function, return 1.0
    """
    if (obs is None):
        return 1.0
    funcs.assertInSet(obs, ['M', 'E'], 'Ising obervables')
    if (obs == 'M'):
        res = 0.0
        for x in idx:
            if (x == 0):
                res -= 0.5
            else:
                res += 0.5

        return res

    if (obs == 'E'):
        res = 0.0
        for i in range(4):
            if (idx[i] == idx[(i + 1) % 4]):
                res -= 1.0
            else:
                res += 1.0
        return res
    return 1.0