def MinWeightMatching(code, Syndrome, type, charge_type): dim = code.dimension # Fully connect check operators for check1 in Syndrome.nodes(): for check2 in Syndrome.nodes(): if check1 != check2: # weight = - code.distance(type, check1, check2) weight = -common.euclidean_dist(check1, check2) Syndrome.add_edge(*(check1, check2), weight=weight) # Generate Boundary Graph External_Graph = nx.Graph() for node in Syndrome.nodes(): charge = Syndrome.node[node]['charge'] external_node = AssociatedExternal(node, code.Dual[type], code.External[type]) External_Graph.add_node(external_node, charge=(-charge) % dim) # weight = -code.distance(type, node, external_node) weight = -common.euclidean_dist(node, external_node) Syndrome.add_edge(*(node, external_node), weight=weight) # Ensure even number of elements in Syndrome # so min weight matching can proceed successfully if len(Syndrome.nodes()) % 2 != 0: removed_external = External_Graph.nodes()[0] edge = Syndrome.edges(removed_external)[0] min_weight = Syndrome.get_edge_data(*edge)['weight'] for external_node in External_Graph.nodes(): edge = Syndrome.edges(external_node)[0] weight = Syndrome.get_edge_data(*edge)['weight'] if weight < min_weight: removed_external = external_node min_weight = weight External_Graph.remove_node(removed_external) Syndrome.remove_node(removed_external) # Connect External Nodes for ext1 in External_Graph: for ext2 in External_Graph: if ext1 != ext2: Syndrome.add_edge(*(ext1, ext2), weight=0) TempMatching = nx.max_weight_matching(Syndrome, maxcardinality=True) Matching = {} # each edge appears twice in TempMatching # Should only appear once in Matching for node, neighbor in TempMatching.items(): if neighbor not in Matching: if node in code.Dual[type].nodes( ) or neighbor in code.Dual[type].nodes(): Matching[node] = neighbor return Matching
def MinWeightMatching(code, Syndrome, type, charge_type): dim = code.dimension # Fully connect check operators for check1 in Syndrome.nodes(): for check2 in Syndrome.nodes(): if check1 != check2: # weight = - code.distance(type, check1, check2) weight = - common.euclidean_dist(check1, check2) Syndrome.add_edge(*(check1, check2), weight=weight) # Generate Boundary Graph External_Graph = nx.Graph() for node in Syndrome.nodes(): charge = Syndrome.node[node]['charge'] external_node = AssociatedExternal(node, code.Dual[type], code.External[type]) External_Graph.add_node(external_node, charge=(-charge) % dim) # weight = -code.distance(type, node, external_node) weight = - common.euclidean_dist(node, external_node) Syndrome.add_edge(*(node, external_node), weight=weight) # Ensure even number of elements in Syndrome # so min weight matching can proceed successfully if len(Syndrome.nodes()) % 2 != 0: removed_external = External_Graph.nodes()[0] edge = Syndrome.edges(removed_external)[0] min_weight = Syndrome.get_edge_data(*edge)['weight'] for external_node in External_Graph.nodes(): edge = Syndrome.edges(external_node)[0] weight = Syndrome.get_edge_data(*edge)['weight'] if weight < min_weight: removed_external = external_node min_weight = weight External_Graph.remove_node(removed_external) Syndrome.remove_node(removed_external) # Connect External Nodes for ext1 in External_Graph: for ext2 in External_Graph: if ext1 != ext2: Syndrome.add_edge(*(ext1, ext2), weight=0) TempMatching = nx.max_weight_matching(Syndrome, maxcardinality=True) Matching = {} # each edge appears twice in TempMatching # Should only appear once in Matching for node, neighbor in TempMatching.items(): if neighbor not in Matching: if node in code.Dual[type].nodes() or neighbor in code.Dual[type].nodes(): Matching[node] = neighbor return Matching
def GCC_Boundary_One_Color_Simplify(m, cc, uc, code, t, ct, scale, cntr): [t1, t2] = code.complementaryTypes(t) c = cc[t][0][1]['charge'] d = code.dimension if any(common.euclidean_dist(ext, m) < scale for ext in code.External[t]): for ext in code.External[t]: if common.euclidean_dist(ext, m) < scale: uc.add_node(ext, charge=d - c, type=t) cc[t].append((ext, {'charge': d - c, 'type': t})) code.Stabilizers[t][ext]['charge'][ct] = d - c cc[t], uc, code = GCC_One_Color_Simplify( cc[t], uc, code, t, ct, cntr) break elif any( common.euclidean_dist(ext, m) < scale for ext in code.External[t1]) and any( common.euclidean_dist(ext, m) < scale for ext in code.External[t2]): if any(ext1 in code.External[t1] for ext1 in code.Dual[t2].neighbors(m)) and any( ext2 in code.External[t2] for ext2 in code.Dual[t1].neighbors(m)): m_new = m else: for m_new in code.Stabilizers[t]: if any(ext1 in code.External[t1] for ext1 in code.Dual[t2].neighbors(m_new)) and any( ext2 in code.External[t2] for ext2 in code.Dual[t1].neighbors(m_new)): break s, e = cc[t][0], (m_new, {'charge': 0, 'type': t}) uc.add_node(m_new, charge=0, type=t) cc[t].append(e) cc[t], uc, code = GCC_One_Color_Transport(s, e, cc[t], uc, code, t, ct) for ext1 in code.External[t1]: if ext1 in code.Dual[t2].neighbors(m_new): break for ext2 in code.External[t2]: if ext2 in code.Dual[t1].neighbors(m_new): break uc.add_node(ext1, charge=c, type=t1) cc[t1].append((ext1, {'charge': c, 'type': t1})) uc.add_node(ext2, charge=c, type=t2) cc[t2].append((ext2, {'charge': c, 'type': t2})) cc, uc, code = GCC_Two_Color_Simplify(cc, uc, code, ct, cntr) return cc, uc, code
def DSP_Matching(Syndrome, External, dim, alt_ext): # Fully connect check operators for check1 in Syndrome.nodes(): for check2 in Syndrome.nodes(): if check1 != check2: weight = -common.euclidean_dist(check1, check2) + .1 Syndrome.add_edge(*(check1, check2), weight=weight) # Generate Boundary Graph External_Graph = nx.Graph() for m in Syndrome.nodes(): ext = DSP_AssociatedExternal(m, External) External_Graph.add_node(ext) weight = -common.euclidean_dist(m, ext) Syndrome.add_edge(*(m, ext), weight=weight) # Ensure even number of elements in Syndrome # so min weight matching can proceed successfully if len(Syndrome.nodes()) % 2 != 0: Syndrome.add_node(alt_ext) External_Graph.add_node(alt_ext) # Connect External Nodes edges = itertools.combinations(External_Graph, 2) Syndrome.add_edges_from(edges, weight=0) TempMatching = nx.max_weight_matching(Syndrome, maxcardinality=True) Matching = {} # each edge appears twice in TempMatching # Should only appear once in Matching for node, neighbor in TempMatching.items(): if neighbor not in Matching and node not in Matching: if node not in External or neighbor not in External: if node != alt_ext and neighbor != alt_ext: Matching[node] = neighbor return Matching
def GCC_Boundary_One_Color_Simplify(m, cc, uc, code, t, ct, scale, cntr): [t1,t2] = code.complementaryTypes(t) c = cc[t][0][1]['charge'] d = code.dimension if any(common.euclidean_dist(ext, m) < scale for ext in code.External[t]): for ext in code.External[t]: if common.euclidean_dist(ext, m) < scale: uc.add_node(ext, charge = d-c, type = t) cc[t].append((ext,{'charge':d-c,'type':t})) code.Stabilizers[t][ext]['charge'][ct] = d-c cc[t], uc, code = GCC_One_Color_Simplify(cc[t], uc, code, t, ct, cntr) break elif any(common.euclidean_dist(ext, m) < scale for ext in code.External[t1]) and any(common.euclidean_dist(ext, m) < scale for ext in code.External[t2]): if any(ext1 in code.External[t1] for ext1 in code.Dual[t2].neighbors(m)) and any(ext2 in code.External[t2] for ext2 in code.Dual[t1].neighbors(m)): m_new = m else: for m_new in code.Stabilizers[t]: if any(ext1 in code.External[t1] for ext1 in code.Dual[t2].neighbors(m_new)) and any(ext2 in code.External[t2] for ext2 in code.Dual[t1].neighbors(m_new)): break s, e = cc[t][0], (m_new,{'charge':0,'type':t}) uc.add_node(m_new, charge = 0, type = t) cc[t].append(e) cc[t], uc, code = GCC_One_Color_Transport(s, e, cc[t], uc, code, t, ct) for ext1 in code.External[t1]: if ext1 in code.Dual[t2].neighbors(m_new): break for ext2 in code.External[t2]: if ext2 in code.Dual[t1].neighbors(m_new): break uc.add_node(ext1, charge = c, type = t1) cc[t1].append((ext1,{'charge':c,'type':t1})) uc.add_node(ext2, charge = c, type = t2) cc[t2].append((ext2,{'charge':c,'type':t2})) cc, uc, code = GCC_Two_Color_Simplify(cc, uc, code, ct, cntr) return cc, uc, code
def DSP_Matching(Syndrome, External, dim, alt_ext): # Fully connect check operators for check1 in Syndrome.nodes(): for check2 in Syndrome.nodes(): if check1 != check2: weight = - common.euclidean_dist(check1, check2) +.1 Syndrome.add_edge(*(check1, check2), weight=weight) # Generate Boundary Graph External_Graph = nx.Graph() for m in Syndrome.nodes(): ext = DSP_AssociatedExternal(m, External) External_Graph.add_node(ext) weight = - common.euclidean_dist(m, ext) Syndrome.add_edge(*(m, ext), weight=weight) # Ensure even number of elements in Syndrome # so min weight matching can proceed successfully if len(Syndrome.nodes()) % 2 != 0: Syndrome.add_node(alt_ext) External_Graph.add_node(alt_ext) # Connect External Nodes edges = itertools.combinations(External_Graph,2) Syndrome.add_edges_from(edges, weight = 0) TempMatching = nx.max_weight_matching(Syndrome, maxcardinality=True) Matching = {} # each edge appears twice in TempMatching # Should only appear once in Matching for node, neighbor in TempMatching.items(): if neighbor not in Matching and node not in Matching: if node not in External or neighbor not in External: if node != alt_ext and neighbor != alt_ext: Matching[node] = neighbor return Matching
def GCC_Partition(UnclusteredGraph, scale): # Make edges on Unclustered graph # between all nodes separated by distance 'scale' for node1 in UnclusteredGraph.nodes(): for node2 in UnclusteredGraph.nodes(): if node1 != node2: dist = common.euclidean_dist(node1, node2) if dist <= scale: UnclusteredGraph.add_edge(*(node1, node2), weight=dist) Clusters = [] subgraphs = nx.connected_component_subgraphs(UnclusteredGraph) for i, sg in enumerate(subgraphs): Clusters.append(sg.nodes(data=True)) return Clusters
def __call__(self, code, charge_type): l,d = code.depth, code.dimension s = {} for type in code.types: s[type] = code.Syndrome(type, charge_type) uc = nx.union(s['green'], nx.union(s['red'], s['blue'])) for edge in code.Dual['red'].edges(): break scale = common.euclidean_dist(edge[0], edge[1])+.1 i = 1 while uc.nodes() != []: clusters = GCC_Partition(uc, i*scale) for cluster in clusters: code, uc = GCC_Annihilate(cluster, code, uc, charge_type, i*scale) i += 1 return code
def __call__(self, code, charge_type): l, d = code.depth, code.dimension s = {} for type in code.types: s[type] = code.Syndrome(type, charge_type) uc = nx.union(s['green'], nx.union(s['red'], s['blue'])) for edge in code.Dual['red'].edges(): break scale = common.euclidean_dist(edge[0], edge[1]) + .1 i = 1 while uc.nodes() != []: clusters = GCC_Partition(uc, i * scale) for cluster in clusters: code, uc = GCC_Annihilate(cluster, code, uc, charge_type, i * scale) i += 1 return code
def DSP_AssociatedExternal(int_node, external_nodes): return min(external_nodes, key=lambda x: common.euclidean_dist(int_node, x))
def GCC_Boundary_Two_Color_Simplify(ints, cc, uc, code, ct, scale, cntr): cc, uc, code = clean_clusters(cc, uc, code) d = code.dimension [m0, m1] = ints c0, c1 = m0[1]['charge'], m1[1]['charge'] t0, t1 = m0[1]['type'], m1[1]['type'] t2 = code.complementaryType([t0,t1]) if c0 == c1: if any((common.euclidean_dist(ext, m0[0]) < scale and common.euclidean_dist(ext, m1[0]) < scale) for ext in code.External[t2]): if any((ext in code.Dual[t1].neighbors(m0[0]) and ext in code.Dual[t0].neighbors(m1[0])) for ext in code.External[t2]): for ext in code.External[t2]: if ext in code.Dual[t1].neighbors(m0[0]) and ext in code.Dual[t0].neighbors(m1[0]): break else: ext = closest_to_point(code.External[t2],m0[0]) uc.add_node(ext, charge = c0, type = t2) cc[t2].append((ext,{'charge':c0,'type':t2})) code.Stabilizers[t2][ext]['charge'][ct] = c0 cc, uc, code = GCC_Two_Color_Simplify(cc, uc, code, ct, cntr) elif any(common.euclidean_dist(ext, m0[0]) < scale for ext in code.External[t0]) and any(common.euclidean_dist(ext, m1[0]) < scale for ext in code.External[t1]): cc, uc, code = GCC_Boundary_One_Color_Simplify(m0[0], cc, uc, code, t0, ct, scale, cntr) cc, uc, code = GCC_Boundary_One_Color_Simplify(m1[0], cc, uc, code, t1, ct, scale, cntr) elif any(common.euclidean_dist(ext, m0[0]) < scale for ext in code.External[t0]) and any(common.euclidean_dist(ext, m1[0]) < scale for ext in code.External[t1]): cc, uc, code = GCC_Boundary_One_Color_Simplify(m0[0], cc, uc, code, t0, ct, scale, cntr) cc, uc, code = GCC_Boundary_One_Color_Simplify(m1[0], cc, uc, code, t1, ct, scale, cntr) elif any(common.euclidean_dist(ext, cntr) < scale for ext in code.External[t0]) and any(common.euclidean_dist(ext, cntr) < scale for ext in code.External[t2]): ext = closest_to_point(code.External[t0],m0[0]) e = (ext, {'type':t0,'charge':(c0-c1)%d}) cc[t0].remove(m0) m0 = (m0[0],{'type':t0,'charge':(c0-c1)%d}) uc.node[m0[0]]['charge'] = (c0-c1)%d code.Stabilizers[t0][m0[0]]['charge'][ct]=(c0-c1)%d cc[t0].append(m0) cc[t0], uc, code = GCC_One_Color_Transport(m0, e, cc[t0], uc, code, t0, ct) m0 = (m0[0],{'type':t0,'charge':c1}) uc.add_node(m0[0], type = t0, charge = c1) code.Stabilizers[t0][m0[0]]['charge'][ct]=c1 cc[t0].append(m0) ints = [m0,m1] return GCC_Boundary_Two_Color_Simplify(ints, cc, uc, code, ct, scale, cntr) elif any(common.euclidean_dist(ext, cntr) < scale for ext in code.External[t1]) and any(common.euclidean_dist(ext, cntr) < scale for ext in code.External[t2]): ext = closest_to_point(code.External[t1],m1[0]) e = (ext, {'type':t1,'charge':(c1-c0)%d}) cc[t1].remove(m1) m1 = (m1[0],{'type':t1,'charge':(c1-c0)%d}) uc.node[m1[0]]['charge'] = (c1-c0)%d code.Stabilizers[t1][m1[0]]['charge'][ct]=(c1-c0)%d cc[t1].append(m1) cc[t1], uc, code = GCC_One_Color_Transport(m1, e, cc[t1], uc, code, t1, ct) m1 = (m1[0],{'type':t1,'charge':c0}) uc.add_node(m1[0], type = t1, charge = c0) code.Stabilizers[t1][m1[0]]['charge'][ct]=c0 cc[t1].append(m1) ints = [m0,m1] return GCC_Boundary_Two_Color_Simplify(ints, cc, uc, code, ct, scale, cntr) return cc, uc, code
def closest_to_point(nodes,pt): return min(nodes, key = lambda x:common.euclidean_dist(pt, x))
def GCC_Boundary_Two_Color_Simplify(ints, cc, uc, code, ct, scale, cntr): cc, uc, code = clean_clusters(cc, uc, code) d = code.dimension [m0, m1] = ints c0, c1 = m0[1]['charge'], m1[1]['charge'] t0, t1 = m0[1]['type'], m1[1]['type'] t2 = code.complementaryType([t0, t1]) if c0 == c1: if any((common.euclidean_dist(ext, m0[0]) < scale and common.euclidean_dist(ext, m1[0]) < scale) for ext in code.External[t2]): if any((ext in code.Dual[t1].neighbors(m0[0]) and ext in code.Dual[t0].neighbors(m1[0])) for ext in code.External[t2]): for ext in code.External[t2]: if ext in code.Dual[t1].neighbors( m0[0]) and ext in code.Dual[t0].neighbors(m1[0]): break else: ext = closest_to_point(code.External[t2], m0[0]) uc.add_node(ext, charge=c0, type=t2) cc[t2].append((ext, {'charge': c0, 'type': t2})) code.Stabilizers[t2][ext]['charge'][ct] = c0 cc, uc, code = GCC_Two_Color_Simplify(cc, uc, code, ct, cntr) elif any( common.euclidean_dist(ext, m0[0]) < scale for ext in code.External[t0]) and any( common.euclidean_dist(ext, m1[0]) < scale for ext in code.External[t1]): cc, uc, code = GCC_Boundary_One_Color_Simplify( m0[0], cc, uc, code, t0, ct, scale, cntr) cc, uc, code = GCC_Boundary_One_Color_Simplify( m1[0], cc, uc, code, t1, ct, scale, cntr) elif any( common.euclidean_dist(ext, m0[0]) < scale for ext in code.External[t0]) and any( common.euclidean_dist(ext, m1[0]) < scale for ext in code.External[t1]): cc, uc, code = GCC_Boundary_One_Color_Simplify(m0[0], cc, uc, code, t0, ct, scale, cntr) cc, uc, code = GCC_Boundary_One_Color_Simplify(m1[0], cc, uc, code, t1, ct, scale, cntr) elif any( common.euclidean_dist(ext, cntr) < scale for ext in code.External[t0]) and any( common.euclidean_dist(ext, cntr) < scale for ext in code.External[t2]): ext = closest_to_point(code.External[t0], m0[0]) e = (ext, {'type': t0, 'charge': (c0 - c1) % d}) cc[t0].remove(m0) m0 = (m0[0], {'type': t0, 'charge': (c0 - c1) % d}) uc.node[m0[0]]['charge'] = (c0 - c1) % d code.Stabilizers[t0][m0[0]]['charge'][ct] = (c0 - c1) % d cc[t0].append(m0) cc[t0], uc, code = GCC_One_Color_Transport(m0, e, cc[t0], uc, code, t0, ct) m0 = (m0[0], {'type': t0, 'charge': c1}) uc.add_node(m0[0], type=t0, charge=c1) code.Stabilizers[t0][m0[0]]['charge'][ct] = c1 cc[t0].append(m0) ints = [m0, m1] return GCC_Boundary_Two_Color_Simplify(ints, cc, uc, code, ct, scale, cntr) elif any( common.euclidean_dist(ext, cntr) < scale for ext in code.External[t1]) and any( common.euclidean_dist(ext, cntr) < scale for ext in code.External[t2]): ext = closest_to_point(code.External[t1], m1[0]) e = (ext, {'type': t1, 'charge': (c1 - c0) % d}) cc[t1].remove(m1) m1 = (m1[0], {'type': t1, 'charge': (c1 - c0) % d}) uc.node[m1[0]]['charge'] = (c1 - c0) % d code.Stabilizers[t1][m1[0]]['charge'][ct] = (c1 - c0) % d cc[t1].append(m1) cc[t1], uc, code = GCC_One_Color_Transport(m1, e, cc[t1], uc, code, t1, ct) m1 = (m1[0], {'type': t1, 'charge': c0}) uc.add_node(m1[0], type=t1, charge=c0) code.Stabilizers[t1][m1[0]]['charge'][ct] = c0 cc[t1].append(m1) ints = [m0, m1] return GCC_Boundary_Two_Color_Simplify(ints, cc, uc, code, ct, scale, cntr) return cc, uc, code
def closest_to_point(nodes, pt): return min(nodes, key=lambda x: common.euclidean_dist(pt, x))
def DSP_AssociatedExternal(int_node, external_nodes): return min(external_nodes, key = lambda x:common.euclidean_dist(int_node, x))