def match_toric_2D(lattice_size, anyon_positions): """ Uses perfect matching to return a matching to fix the 2D TORIC code from the given positions of '-1' stabilizer outcomes in the code. Assumptions: ----------- Perfect measurement, meaning there must be an even number of anyons. Parameters: ---------- lattice_size -- size of the code. anyon_positions -- List of all '-1' stabilizer outcomes in the code. E.g. [[x0,y0],[x1,y1],..]. Returns: ------- The perfect matching, a list of paired anyon positions. """ nodes_list = anyon_positions n_nodes = len(nodes_list) if n_nodes == 0: return [] m = 2 * lattice_size graphArray = [] ##fully connect the nodes within the 2D layer ## node numbering starts at 0 for i in range(n_nodes - 1): (p0, p1) = nodes_list[i] for j in range(n_nodes - i - 1): (q0, q1) = nodes_list[j + i + 1] w0 = (p0 - q0) % m w1 = (p1 - q1) % m weight = min([w0, m - w0]) + min([w1, m - w1]) graphArray += [[i, j + i + 1, weight]] n_edges = len(graphArray) ## PERFORM MATCHING ## Use the blossom5 perfect matching algorithm to return a matching matching = pm.getMatching(n_nodes, graphArray) ## REFORMAT MATCHING matching_pairs = [[i, matching[i]] for i in range(n_nodes) if matching[i] > i] points = [] if len(matching_pairs) == 0 else [[nodes_list[i] for i in x] for x in matching_pairs] return points
def match_toric_2D(lattice_size,anyon_positions): """ Uses perfect matching to return a matching to fix the 2D TORIC code from the given positions of '-1' stabilizer outcomes in the code. Assumptions: ----------- Perfect measurement, meaning there must be an even number of anyons. Parameters: ---------- lattice_size -- size of the code. anyon_positions -- List of all '-1' stabilizer outcomes in the code. E.g. [[x0,y0],[x1,y1],..]. Returns: ------- The perfect matching, a list of paired anyon positions. """ nodes_list=anyon_positions n_nodes=len(nodes_list) if n_nodes==0: return [] m=2*lattice_size graphArray=[] ##fully connect the nodes within the 2D layer ## node numbering starts at 0 for i in range(n_nodes-1): (p0,p1)=nodes_list[i] for j in range(n_nodes-i-1): (q0,q1)=nodes_list[j+i+1] w0=(p0-q0)%m w1=(p1-q1)%m weight=min([w0,m-w0])+min([w1,m-w1]) graphArray+=[[i,j+i+1,weight]] n_edges=len(graphArray) ## PERFORM MATCHING ## Use the blossom5 perfect matching algorithm to return a matching matching=pm.getMatching(n_nodes,graphArray) ## REFORMAT MATCHING matching_pairs=[[i,matching[i]] for i in range(n_nodes) if matching[i]>i] points=[] if len(matching_pairs)==0 else [[nodes_list[i] for i in x] for x in matching_pairs] return points
def get_matching_blossom5(graph): """ Uses the BlossomV algorithm to get the matchings. A list of combinations of all the anyons and their respective weights are feeded to the blossom5 algorithm. To apply the matchings, we walk from each matching vertex to where their paths meet perpendicualarly, flipping the edges on the way over. """ edges = [] # Get all possible edges between the anyons and their weights def edge_func(edges, e0, e1, weight): edges.append([e0, e1, weight]) all_anyons, nxgraph = get_graph_edges(graph, edge_func, edges) output = pm.getMatching(len(all_anyons), edges) if all_anyons != [] else [] return [[all_anyons[i0], all_anyons[i1]] for i0, i1 in enumerate(output) if i0 > i1]
def match_toric_2D(lattice_size, anyon_positions): nodes_list = anyon_positions n_nodes = len(nodes_list) if n_nodes == 0: return [] m = 2 * lattice_size graphArray = [] ##fully connect the nodes within the 2D layer ## node numbering starts at 0 for i in range(n_nodes - 1): (p0, p1) = nodes_list[i] for j in range(n_nodes - i - 1): (q0, q1) = nodes_list[j + i + 1] w0 = (p0 - q0) % m w1 = (p1 - q1) % m weight = min([w0, m - w0]) + min([w1, m - w1]) graphArray += [[i, j + i + 1, weight]] n_edges = len(graphArray) ################ MATCHING ################### matching = pm.getMatching(n_nodes, graphArray) ############################################# matching_pairs = [[i, matching[i]] for i in range(n_nodes) if matching[i] > i] points = [] if len(matching_pairs) == 0 else [[nodes_list[i] for i in x] for x in matching_pairs] return points
def match_toric_2D(lattice_size,anyon_positions): nodes_list=anyon_positions n_nodes=len(nodes_list) if n_nodes==0: return [] m=2*lattice_size graphArray=[] ##fully connect the nodes within the 2D layer ## node numbering starts at 0 for i in range(n_nodes-1): (p0,p1)=nodes_list[i] for j in range(n_nodes-i-1): (q0,q1)=nodes_list[j+i+1] w0=(p0-q0)%m w1=(p1-q1)%m weight=min([w0,m-w0])+min([w1,m-w1]) graphArray+=[[i,j+i+1,weight]] n_edges=len(graphArray) ################ MATCHING ################### matching=pm.getMatching(n_nodes,graphArray) ############################################# matching_pairs=[[i,matching[i]] for i in range(n_nodes) if matching[i]>i] points=[] if len(matching_pairs)==0 else [[nodes_list[i] for i in x] for x in matching_pairs] return points
def match_planar_2D(lattice_size,stabilizer_type,anyon_positions): if anyon_positions==[]: matching=[] return matching N_nodes=len(anyon_positions) #N_edges=N_nodes*(N_nodes-1)/2 # graphStr=str(N_nodes*2)+' '+str(N_edges*2+N_nodes)+'\n' if N_nodes==0: return [] node_index = [] count = 0 graphArray = [] for i in range(N_nodes-1): (p0,p1)=anyon_positions[i] for j in range(N_nodes-i-1): indexj = j+i+1 (q0,q1)= anyon_positions[j+i+1] weight=abs(p0-q0)+abs(p1-q1) graphArray+=[[i,indexj,weight]] #newline=str(i)+' '+str(i+j+1)+' '+str(weight)+'\n' #graphStr+=newline # for every node, create a boundary node and joining edge boundary_node_positions=[] for i in range(N_nodes): (p0,p1)=anyon_positions[i] if stabilizer_type=="star": (b0,b1)=(p0,-1 if p1<lattice_size else 2*lattice_size+1) elif stabilizer_type=="plaquette": (b0,b1)=(-1 if p0<lattice_size else 2*lattice_size+1,p1) else: print "stabilizer_type must be either **star** or **plaquette**" return 0 boundary_node_positions+=[[b0,b1]] #add edge to graph weight=abs(p0-b0)+abs(p1-b1) graphArray+=[[i,i+N_nodes,weight]] #newline=str(i)+' '+str(i+N_nodes)+' '+str(weight)+'\n' #graphStr+=newline # fully connect boundary nodes with weight 0 N_boundary_nodes=len(boundary_node_positions) for i in range(N_boundary_nodes-1): for j in range(N_boundary_nodes-i-1): graphArray+=[[i+N_nodes,i+N_nodes+j+1,0]] #newline=str(i+N_nodes)+' '+str(i+N_nodes+j+1)+' '+str(0)+'\n' #graphStr+=newline ################ MATCHING ################### matching=pm.getMatching(2*N_nodes,graphArray) ############################################# matching_pairs=[[i,matching[i]] for i in range(2*N_nodes) if matching[i]>i] all_positions=anyon_positions+boundary_node_positions points=[] if len(matching_pairs) == 0 else [[all_positions[i] for i in x] for x in matching_pairs] return points
def match_toric_3D(lattice_size,anyon_positions,weights): #tp0 = time.time() nodes_list=[item for sublist in anyon_positions for item in sublist] n_nodes=len(nodes_list) if n_nodes==0: return [] m=2*lattice_size wT,wS=weights graphArray=[] ##fully connect the nodes within the 2D layer ## node numbering starts at 0 time_lookup={} for t in range(10): time_lookup[t]=t*wT weight_lookup = {} for i in range(m): weight_lookup[i]={} for j in range(m): diff = abs(i-j) weight_lookup[i][j] = min([diff,m-diff])*wS n_nodes_minus_1 = n_nodes-1 for i in range(n_nodes_minus_1): (pt,p0,p1)=nodes_list[i] i_plus_1 = i+1 for j in range(n_nodes_minus_1 - i): indexj = j+i_plus_1 (qt,q0,q1)=nodes_list[indexj] wt=(qt-pt) if wt>=8: break # the list of nodes is ordered by time so break as soon as difference between pt and qt is >=10 # w0=(q0-p0)%m # w1=(q1-p1)%m # weight=(min([w0,m-w0])+min([w1,m-w1]))*wS+wt*wT weight = weight_lookup[q0][p0]+weight_lookup[q1][p1]+time_lookup[wt] graphArray+=[[i,indexj,weight]] n_edges=len(graphArray) # tp1 = time.time() # print 'generate matching graph ',tp1-tp0 ################ MATCHING ################### matching=pm.getMatching(n_nodes,graphArray) ############################################# matching_pairs=[[i,matching[i]] for i in range(n_nodes) if matching[i]>i] points=[] if len(matching_pairs)==0 else [[nodes_list[i] for i in x] for x in matching_pairs] # tp2 = time.time() #print 'perfect matching ', tp2 - tp1 return points
def match_toric_3D(lattice_size, anyon_positions, weights=[1, 1]): """ Uses perfect matching to return a matching to fix the 3D TORIC code from the given positions of '-1' stabilizer outcomes in the code. Parameters: ---------- lattice_size -- size of the code. anyon_positions -- List of all '-1' stabilizer outcomes in the code, a space + time coordinate. E.g. [[x0,y0,t0],[x1,y1,t1],..]. weights -- A 2-component list, [space_weight,time_weight] containting multiplicative weightings for space and time dimensions. Default: [1,1] Returns: ------- The perfect matching, a list of paired anyon positions. """ # time direction cutoff cutoff = 15 #tp0 = time.time() nodes_list = [item for sublist in anyon_positions for item in sublist] n_nodes = len(nodes_list) if n_nodes == 0: return [] m = 2 * lattice_size wT, wS = weights graphArray = [] ##fully connect the nodes within the 2D layer ## node numbering starts at 0 time_lookup = {} for t in range(cutoff + 1): time_lookup[t] = t * wT weight_lookup = {} for i in range(m): weight_lookup[i] = {} for j in range(m): diff = abs(i - j) weight_lookup[i][j] = min([diff, m - diff]) * wS n_nodes_minus_1 = n_nodes - 1 for i in range(n_nodes_minus_1): (pt, p0, p1) = nodes_list[i] i_plus_1 = i + 1 for j in range(n_nodes_minus_1 - i): indexj = j + i_plus_1 (qt, q0, q1) = nodes_list[indexj] wt = (qt - pt) if wt >= cutoff: break # the list of nodes is ordered by time so break as soon as difference between pt and qt is >=10 weight = weight_lookup[q0][p0] + weight_lookup[q1][ p1] + time_lookup[wt] graphArray += [[i, indexj, weight]] n_edges = len(graphArray) ## PERFORM MINIMUM WEIGHT MATCHING ## Use Blossom5 algorithm to generating a matching matching = pm.getMatching(n_nodes, graphArray) ## REFORMAT MATCHING matching_pairs = [[i, matching[i]] for i in range(n_nodes) if matching[i] > i] points = [] if len(matching_pairs) == 0 else [[nodes_list[i] for i in x] for x in matching_pairs] return points
def match_toric_3D(lattice_size,anyon_positions,weights=[1,1]): """ Uses perfect matching to return a matching to fix the 3D TORIC code from the given positions of '-1' stabilizer outcomes in the code. Parameters: ---------- lattice_size -- size of the code. anyon_positions -- List of all '-1' stabilizer outcomes in the code, a space + time coordinate. E.g. [[x0,y0,t0],[x1,y1,t1],..]. weights -- A 2-component list, [space_weight,time_weight] containting multiplicative weightings for space and time dimensions. Default: [1,1] Returns: ------- The perfect matching, a list of paired anyon positions. """ # time direction cutoff cutoff = 15 #tp0 = time.time() nodes_list=[item for sublist in anyon_positions for item in sublist] n_nodes=len(nodes_list) if n_nodes==0: return [] m=2*lattice_size wT,wS=weights graphArray=[] ##fully connect the nodes within the 2D layer ## node numbering starts at 0 time_lookup={} for t in range(cutoff+1): time_lookup[t]=t*wT weight_lookup = {} for i in range(m): weight_lookup[i]={} for j in range(m): diff = abs(i-j) weight_lookup[i][j] = min([diff,m-diff])*wS n_nodes_minus_1 = n_nodes-1 for i in range(n_nodes_minus_1): (pt,p0,p1)=nodes_list[i] i_plus_1 = i+1 for j in range(n_nodes_minus_1 - i): indexj = j+i_plus_1 (qt,q0,q1)=nodes_list[indexj] wt=(qt-pt) if wt>=cutoff: break # the list of nodes is ordered by time so break as soon as difference between pt and qt is >=10 weight = weight_lookup[q0][p0]+weight_lookup[q1][p1]+time_lookup[wt] graphArray+=[[i,indexj,weight]] n_edges=len(graphArray) ## PERFORM MINIMUM WEIGHT MATCHING ## Use Blossom5 algorithm to generating a matching matching=pm.getMatching(n_nodes,graphArray) ## REFORMAT MATCHING matching_pairs=[[i,matching[i]] for i in range(n_nodes) if matching[i]>i] points=[] if len(matching_pairs)==0 else [[nodes_list[i] for i in x] for x in matching_pairs] return points