def selectRegion2(string, width, args): """ select a region within width from the given x-string (for x-PBC use only) Parameters ----------------- string : list of bonds bonds on the string operator width : int width of the spreading from string operator size : (int, int) linear size of the lattice system """ region = [] size = [args['nx'], args['ny']] xperiodic = args['xperiodic'] if xperiodic == False: sys.exit("selectRegion2 recognizes x-PBC only") for bond in string: x, y, dir = bond[0], bond[1], bond[2] # add the plaquette above/below this bond above = [(x, y, 'r')] below = [(x, y, 'r')] for d in range(width): above.append((x, y - d - 1, 'r')) above.append((x, y - d - 1, 'd')) above.append((x + 1, y - d - 1, 'd')) below.append((x, y + d + 1, 'r')) below.append((x, y + d, 'd')) below.append((x + 1, y + d, 'd')) if y == 0: # upper boundary; add plq. below only above = [] if y == size[1] - 1: # lower boundary; add plq. above only below = [] for newbond in above: region.append(lat.lat(newbond[0:2], newbond[2], size, xperiodic)) for newbond in below: region.append(lat.lat(newbond[0:2], newbond[2], size, xperiodic)) region = np.asarray(region, dtype=int) region = np.unique(region) return region
# use default p.args['nx'] sep = 10 # use default p.args['hz'] width = 2 os.makedirs(result_dir, exist_ok=True) benckmark = False # save parameters with open(result_dir + '/parameters.txt', 'w+') as file: pass # create string operator pair (x-PBC) MPO enclosing different area closed_str_list = crt.str_create3(args, sep) string = closed_str_list[0] bond_on_str, area, circum = crt.convertToStrOp(string, args) bond_list = [ lat.lat(bond_on_str[i][0:2], bond_on_str[i][2], (args['nx'], args['ny']), args['xperiodic']) for i in range(len(bond_on_str)) ] region = crt.selectRegion2(bond_on_str, width, args) # save parameters with open(result_dir + '/parameters.txt', 'a+') as file: file.write(json.dumps(args) + '\n') # use json.loads to do the reverse # Output information file.write("area: {}\ncircumference: {}\n".format(area, circum)) file.write("bond on str: \n{}\n".format(bond_on_str)) file.write("bond number: \n{}\n".format(bond_list)) if benchmark == False: file.write("bond within distance {}: \n{}\n\n".format(width, region)) # create Toric Code ground state |psi> psi = gnd_state.gnd_state_builder(args)
n += args['ny'] - 1 args['n'] = n # n in case of periodic X if args['xperiodic'] == True: args['real_n'] = n - (args['ny'] - 1) else: args['real_n'] = n # create Toric Code ground state psi = np.load( psi_dir + "mps_{}by{}_hz-{:.2f}.npy".format(nx, args['ny'], args['hz'])) # restore information of the string closed_str_list = crt.str_create3(args, sep) string = closed_str_list[0] bond_on_str, area, circum = crt.convertToStrOp(string, args) bond_list = [ lat.lat(bond_on_str[i][0:2], bond_on_str[i][2], (args['nx'], args['ny']), args['xperiodic']) for i in range(len(bond_on_str)) ] op = np.load(result_dir + 'quasi_op_{}by{}_sep-{}_hz-{:.2f}.npy'.format( args['nx'], args['ny'], sep, args['hz']), allow_pickle=True) op = list(op) exp_value = mps.matElem(psi, op, psi, verbose=True) with open(resultfile, 'a+') as file: file.write("{}\t{}\t{}\n".format(area, circum, exp_value))
def makeGateList(siteNum, args, region=range(10000)): """ Create time-evolution/swap gate list Parameters --------------- siteNum : int number of sites args : dictionary parameter dictionary region : iterable of integers (default range(p.args['n'])) the region from which gates are constructed """ gateList = [] xperiodic = args['xperiodic'] putsite = [False] * siteNum swapGates = [] # open boundary condition along x # make plaquette gates (together with field) if (args['g'] != 0): # i -> row; j -> column for j, i in product(range(args['ny'] - 1), range(args['nx'] - 1)): out_of_region = False u = lat.lat((i, j), 'r', (args['nx'], args['ny']), xperiodic=xperiodic) l = lat.lat((i, j), 'd', (args['nx'], args['ny']), xperiodic=xperiodic) r = lat.lat((i + 1, j), 'd', (args['nx'], args['ny']), xperiodic=xperiodic) d = lat.lat((i, j + 1), 'r', (args['nx'], args['ny']), xperiodic=xperiodic) sites = [u, l, r, d] # check if this gate is in the region for i in range(len(sites)): if sites[i] not in region: out_of_region = True break if out_of_region == True: continue # print(sites) # create swap gates # reaching boundary if (r % (args['nx'] - 1) == 0 and xperiodic == True): # in this case r = u + 1, l = u + nx - 1, d = u + 2 (nx - 1) sites.sort() # now sites = [u, u + 1, u + nx - 1, u + 2 (nx - 1)] # move sites[2] for site in np.arange(sites[2], sites[1] + 1, -1, dtype=int): swapGates.append( gate([site - 1, site], putsite, 'Swap', args)) # move sites[3] for site in np.arange(sites[3], sites[1] + 2, -1, dtype=int): swapGates.append( gate([site - 1, site], putsite, 'Swap', args)) gateSites = [ sites[0], sites[0] + 1, sites[0] + 2, sites[0] + 3 ] else: # OBC case / PBC case off boundary # move sites[0] for site in np.arange(sites[0], sites[1] - 1, 1, dtype=int): swapGates.append( gate([site, site + 1], putsite, 'Swap', args)) # move sites[3] for site in np.arange(sites[3], sites[2] + 1, -1, dtype=int): swapGates.append( gate([site - 1, site], putsite, 'Swap', args)) gateSites = [ sites[1] - 1, sites[1], sites[1] + 1, sites[1] + 2 ] for k in range(len(swapGates)): gateList.append(swapGates[k]) # evolution gate (plaquette with field) gateList.append(gate(gateSites, putsite, 'tEvolP', args)) """ VERY IMPORTANT: how to add magnetic field to the sites Example ----------- Suppose a 4-site operator acts on [11,15,16,20] It will become [14,15,16,17] after applying the swap gates We NOW add field to site 14,15,16,17 instead of 11,15,16,20 But we will set putsite[11,15,16,20] (not [14,15,16,17]) to True """ for site in sites: putsite[site] = True # put sites back to the original place for k in reversed(range(len(swapGates))): gateList.append(swapGates[k]) swapGates.clear() # vertex gates (ZZZZ) are not necessary since it commutes with # plaquette (XXXX), closed string (X...X) and field (Z) # make vertex gates if (args['U'] != 0): # i -> row; j -> column if xperiodic == True: irange = range(args['nx'] - 1) else: irange = range(args['nx']) for j, i in product(range(args['ny'] - 1), irange): out_of_region = False sites = lat.vertex((i, j), args) sites.sort() # create swap gates for site in np.arange(sites[0], sites[1] - 1, 1, dtype=int): swapGates.append(gate([site, site + 1], putsite, 'Swap', args)) for site in np.arange(sites[3] - 1, sites[2], -1, dtype=int): swapGates.append(gate([site, site + 1], putsite, 'Swap', args)) gateSites = [sites[1] - 1, sites[1], sites[1] + 1, sites[1] + 2] for k in range(len(swapGates)): gateList.append(swapGates[k]) # evolution gate (vertex) gateList.append(gate(gateSites, putsite, 'tEvolV', args)) # put sites back to the original place for k in reversed(range(len(swapGates))): gateList.append(swapGates[k]) swapGates.clear() # second order Trotter decomposition # b1.b2.b3....b3.b2.b1 # append "reversed gateList" to "gateList" gateNum = len(gateList) for i in reversed(range(gateNum)): gateList.append(gateList[i]) cleanGates(gateList) return gateList
def selectRegion(string, width, args): """ select a region within width from the given string Parameters ----------------- string : list of bonds bonds on the string operator width : int width of the spreading from string operator size : (int, int) linear size of the lattice system """ region = [] size = [args['nx'], args['ny']] xperiodic = args['xperiodic'] for bond in string: x, y, dir = bond[0], bond[1], bond[2] if dir == 'd': # add the plaquette to the left/right of this bond left = [(x - 1, y, 'r'), (x - 1, y, 'd'), (x, y, 'd'), (x - 1, y + 1, 'r')] right = [(x, y, 'd'), (x, y, 'r'), (x + 1, y, 'd'), (x, y + 1, 'r')] # check whether this is a boundary bond if xperiodic == False: if x == 0: # left boundary: add right plq. only left = [] elif x == size[0] - 1: # right boundary: add left plq. only right = [] elif xperiodic == True: if x == 0: # left boundary: add rightmost plq. left = [(x - 1, y, 'r'), (x - 1, y, 'd'), (x, y, 'd'), (x - 1, y + 1, 'r')] elif x == size[0] - 1: # right boundary: add leftmost plq. right = [(x, y, 'd'), (x, y, 'r'), (x + 1, y, 'd'), (x, y + 1, 'r')] for newbond in left: region.append( lat.lat(newbond[0:2], newbond[2], size, xperiodic)) for newbond in right: region.append( lat.lat(newbond[0:2], newbond[2], size, xperiodic)) if dir == 'r': # add the plaquette above/below this bond above = [(x, y - 1, 'r'), (x, y - 1, 'd'), (x + 1, y - 1, 'd'), (x, y, 'r')] below = [(x, y, 'r'), (x, y, 'd'), (x + 1, y, 'd'), (x, y + 1, 'r')] if y == 0: # upper boundary; add plq. below only above = [] if y == size[1] - 1: # lower boundary; add plq. above only below = [] for newbond in above: region.append( lat.lat(newbond[0:2], newbond[2], size, xperiodic)) for newbond in below: region.append( lat.lat(newbond[0:2], newbond[2], size, xperiodic)) region = np.asarray(region, dtype=int) region = np.unique(region) return region