Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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 
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
    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
Exemple #10
0
    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
Exemple #11
0
def DSP_AssociatedExternal(int_node, external_nodes):
    return min(external_nodes,
               key=lambda x: common.euclidean_dist(int_node, x))
Exemple #12
0
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
Exemple #13
0
def closest_to_point(nodes,pt):
	return min(nodes, key = lambda x:common.euclidean_dist(pt, x))
Exemple #14
0
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
Exemple #15
0
def closest_to_point(nodes, pt):
    return min(nodes, key=lambda x: common.euclidean_dist(pt, x))
Exemple #16
0
def DSP_AssociatedExternal(int_node, external_nodes):
    return min(external_nodes, key = lambda x:common.euclidean_dist(int_node, x))