def grow_clusters(self, method="list", start_bucket=0): if self.print_steps: pr.print_graph(self.graph) self.uf_plot.waitforkeypress() if self.plot else input("Press any key to continue...") bucket_i = 0 support = 0 bucket = self.graph.buckets[support] while bucket: bucket = sorted(bucket, key=lambda x: x.size) if self.print_steps: pr.printlog( "\n############################ GROW ############################" + f"\nGrowing bucket {bucket_i} of {self.graph.maxbucket}: {bucket}" + f"\nRemaining buckets: {self.graph.buckets[bucket_i + 1 : self.graph.maxbucket + 1]}, {self.graph.wastebasket}\n" ) self.uf_plot.waitforkeypress() self.list_grow_bucket(bucket, support) if self.print_steps: pr.print_graph(self.graph, printmerged=0) if self.plot: self.uf_plot.ax.set_xlabel("") if not self.plot_growth and not self.print_steps: txt = "" if self.print_steps else f"Growing bucket #{bucket_i}/{self.graph.maxbucket}" self.uf_plot.draw_plot(txt) self.graph.buckets[support] = [] bucket_i += 1 support = 1 - support bucket = self.graph.buckets[support] if self.plot: if self.print_steps: pr.print_graph(self.graph) if self.plot_growth: pr.printlog("Clusters grown.") self.uf_plot.waitforkeypress()
def grow_clusters(self, method="tree", start_bucket=0): if self.print_steps: pr.print_graph(self.graph) self.uf_plot.waitforkeypress() if self.plot else input( "Press any key to continue...") for bucket_i, bucket in enumerate(self.graph.buckets[start_bucket:], start_bucket): if bucket_i > self.graph.maxbucket: # Break from upper buckets if top bucket has been reached. if self.uf_plot is not None or self.print_steps: pr.printlog("Max bucket number reached.") self.uf_plot.waitforkeypress() if self.plot else input() break if not bucket: # no need to check empty bucket continue if self.print_steps: pr.printlog( "\n############################ GROW ############################" + f"\nGrowing bucket {bucket_i} of {self.graph.maxbucket}: {bucket}" + f"\nRemaining buckets: {self.graph.buckets[bucket_i + 1 : self.graph.maxbucket + 1]}, {self.graph.wastebasket}\n" ) self.uf_plot.waitforkeypress() self.list_grow_bucket(bucket, bucket_i) if self.print_steps: pr.print_graph(self.graph, printmerged=0) if self.plot: self.uf_plot.ax.set_xlabel("") if not self.plot_growth and not self.print_steps: txt = "" if self.print_steps else f"Growing bucket #{bucket_i}/{self.graph.maxbucket}" self.uf_plot.draw_plot(txt) if self.plot: if self.print_steps: pr.print_graph(self.graph) if self.plot_growth: pr.printlog("Clusters grown.") self.uf_plot.waitforkeypress()
def list_grow_bucket(self, bucket, bucket_i): fusion, place = [], [] # Initiate Fusion list while bucket: # Loop over all clusters in the current bucket\ cluster = find_cluster_root(bucket.pop()) if cluster.bucket == bucket_i and cluster.support == bucket_i % 2: # Check that cluster is not already in a higher bucket place.append(cluster) # Set boudary cluster.boundary = [[], cluster.boundary[0]] # Grow cluster support for bucket placement cluster.support = 1 - cluster.support # for vertex, new_edge, new_vertex in cluster.boundary[1]: while cluster.boundary[1]: vertex, new_edge, new_vertex = cluster.boundary[1].pop() # Grow boundaries by half-edge if new_edge.support != 2: new_edge.support += 1 if new_edge.support == 2: # Apped to fusion list of edge fully grown fusion.append((vertex, new_edge, new_vertex)) else: # Half grown edges are added immediately to new boundary cluster.boundary[0].append( (vertex, new_edge, new_vertex)) if self.plot: self.uf_plot.add_edge(new_edge, vertex) if self.plot_growth: self.uf_plot.draw_plot(str(cluster) + " grown.") if self.print_steps: mstr = {} for base_vertex, edge, grow_vertex in fusion: base_cluster = find_cluster_root(base_vertex.cluster) grow_cluster = find_cluster_root(grow_vertex.cluster) if grow_cluster is None: # Fully grown edge. New vertex is on the old boundary. Find new boundary on vertex base_cluster.add_vertex(grow_vertex) self.cluster_new_vertex(base_cluster, grow_vertex, self.plot_growth) elif grow_cluster is base_cluster: # Edge grown on itself. This cluster is already connected. Cut half-edge edge.support -= 1 if self.plot: self.uf_plot.add_edge(edge, base_vertex) else: # Clusters merge by weighted union if grow_cluster.size < base_cluster.size: # apply weighted union base_cluster, grow_cluster = grow_cluster, base_cluster if self.print_steps: # Keep track of which clusters are merged into one if base_cluster.cID not in mstr: mstr[base_cluster.cID] = pr.print_graph( self.graph, [base_cluster], return_string=True) if grow_cluster.cID not in mstr: mstr[grow_cluster.cID] = pr.print_graph( self.graph, [grow_cluster], return_string=True) mstr[grow_cluster.cID] += "\n" + mstr[base_cluster.cID] mstr.pop(base_cluster.cID) union_clusters(grow_cluster, base_cluster, self.size) grow_cluster.boundary[0].extend(base_cluster.boundary[0]) if self.print_steps: pr.printlog("") for cID, string in mstr.items(): pr.printlog( f"B:\n{string}\nA:\n{pr.print_graph(self.graph, [self.graph.C[cID]], return_string=True)}\n" ) # Put clusters in new buckets. Some will be added double, but will be skipped by the new_boundary check for cluster in place: cluster = find_cluster_root(cluster) cluster_place_bucket(self.graph, cluster) if self.plot and not self.plot_growth: self.uf_plot.draw_plot("Clusters merged")
def list_grow_bucket(self, bucket, bucket_i): fusion, place = [], [] # Initiate Fusion list while bucket: # Loop over all clusters in the current bucket\ cluster = find_cluster_root(bucket.pop()) if cluster.bucket == bucket_i and cluster.support == bucket_i % 2: # Check that cluster is not already in a higher bucket place.append(cluster) # Set boudary cluster.boundary = [[], cluster.boundary[0]] # Grow cluster support for bucket placement cluster.support = 1 - cluster.support # for vertex, new_edge, new_vertex in cluster.boundary[1]: while cluster.boundary[1]: vertex, new_edge, new_vertex = cluster.boundary[1].pop() # Grow boundaries by half-edge if new_edge.support != 2: new_edge.support += 1 if new_edge.support == 2: # Apped to fusion list of edge fully grown fusion.append((vertex, new_edge, new_vertex)) else: # Half grown edges are added immediately to new boundary cluster.boundary[0].append((vertex, new_edge, new_vertex)) if self.plot: self.uf_plot.add_edge(new_edge, vertex) if self.plot_growth: self.uf_plot.draw_plot(str(cluster) + " grown.") if self.print_steps: mstr = {} merging = [] for baseV, edge, growV in fusion: baseC = find_cluster_root(baseV.cluster) growC = find_cluster_root(growV.cluster) # Fully grown edge. New vertex is on the old boundary. Find new boundary on vertex if growC is None: baseC.add_vertex(growV) self.cluster_new_vertex(baseC, growV, self.plot_growth) # Edge grown on itself. This cluster is already connected. Cut half-edge elif growC is baseC: edge.support -= 1 if self.plot: self.uf_plot.add_edge(edge, baseV) # Append to merging list, list of edges between clusters else: merging.append((baseC, baseV, edge, growV, growC)) if baseC.tempparent is not growC: baseC.tempparent = growC baseC.cons += 1 growC.cons += 1 # Initiate subbucket for merging cluster edges, ordered by cluster connection degeneracy merge_length = 10 con_buckets = [[] for _ in range(merge_length)] for baseC, baseV, edge, growV, growC in merging: count = baseC.cons + growC.cons - 2 if count >= merge_length: count = merge_length - 1 con_buckets[count].append((baseV, edge, growV)) # Connect subbuckets, starting from lowest subbucket for con_bucket in con_buckets: for baseV, edge, growV in con_bucket: baseC = find_cluster_root(baseV.cluster) growC = find_cluster_root(growV.cluster) # Edge grown on itself. This cluster is already connected. Cut half-edge if growC is baseC: edge.support -= 1 if self.plot: self.uf_plot.add_edge(edge, baseV) # Merge clusters by union else: # apply weighted union if growC.size < baseC.size: baseC, growC = growC, baseC # Keep track of which clusters are merged into one if self.print_steps: if baseC.cID not in mstr: mstr[baseC.cID] = pr.print_graph(self.graph, [baseC], return_string=True) if growC.cID not in mstr: mstr[growC.cID] = pr.print_graph(self.graph, [growC], return_string=True) mstr[growC.cID] += "\n" + mstr[baseC.cID] mstr.pop(baseC.cID) union_clusters(growC, baseC) growC.boundary[0].extend(baseC.boundary[0]) growC.cons = 0 growC.tempparent = growC if self.print_steps: pr.printlog("") for cID, string in mstr.items(): pr.printlog(f"B:\n{string}\nA:\n{pr.print_graph(self.graph, [self.graph.C[cID]], return_string=True)}\n") # Put clusters in new buckets. Some will be added double, but will be skipped by the new_boundary check for cluster in place: cluster = find_cluster_root(cluster) cluster_place_bucket(self.graph, cluster) if self.plot and not self.plot_growth: self.uf_plot.draw_plot("Clusters merged")
def plot_final(tp, graph_t, graph_l): """ param: flips qubits that have flipped in value (y,x) param: arrays data array of the (corrected) qubit states plots the applied stabilizer measurements over the lattices also, in the qubits that have flipped in value a smaller white circle is plotted optionally, the axis is clear and the final state of the lattice is plotted """ plt.sca(tp.ax) uc, vc, wc = [0.2, 0, 0.8], [0.2, 0.8, 0], [0.2, 0.8, 0.8] for y in range(tp.size): for x in range(tp.size): for td in range(2): u_error = graph_t.E[(0, y, x, td)].matching v_error = graph_l.E[(0, y, x, td)].matching qubit = tp.qubits[(y, x, td)] if u_error and not v_error: qubit.set_edgecolor(uc) tp.ax.draw_artist(qubit) elif v_error and not u_error: qubit.set_edgecolor(vc) tp.ax.draw_artist(qubit) elif u_error and v_error: qubit.set_edgecolor(wc) tp.ax.draw_artist(qubit) uerr = Line2D([0], [0], lw=0, marker="o", color=uc, mfc="w", mew=2, ms=10, label="Tree") verr = Line2D([0], [0], lw=0, marker="o", color=vc, mfc="w", mew=2, ms=10, label="List") werr = Line2D([0], [0], lw=0, marker="o", color=wc, mfc="w", mew=2, ms=10, label="Both") legend1 = plt.legend( handles=[uerr, verr, werr], bbox_to_anchor=(1.25, 0.95), loc="upper right", ncol=1, ) tp.ax.add_artist(legend1) tp.canvas.blit(tp.ax.bbox) pr.printlog("Corrections plotted.") tp.waitforkeypress("Corrections plotted")
def grow_clusters( graph_t, uft, uf_plot_t, graph_l, ufl, uf_plot_l, plot_growth=0, print_steps=0, ): """ Grows the clusters, and merges them until there are no uneven clusters left. Starting from the lowest bucket, clusters are popped from the list and grown with {grow_cluster}. Due to the nature of how clusters are appended to the buckets, a cluster needs to be checked for 1) root level 2) bucket level and 3) parity before it can be grown. """ for bucket_i, (bucket_t, bucket_l) in enumerate(zip(graph_t.buckets, graph_l.buckets)): if bucket_i > max([graph_t.maxbucket, graph_l.maxbucket]): break if bucket_t == [] and bucket_l == []: continue if print_steps and bucket_t != []: pr.printlog( "\n############################ GROW TREE ############################" + f"\nGrowing bucket {bucket_i} of {graph_t.maxbucket}: {bucket_t}" + f"\nRemaining buckets: {graph_t.buckets[bucket_i + 1 : graph_t.maxbucket + 1]}, {graph_t.wastebasket}\n" ) uf_plot_t.waitforkeypress() uft.tree_grow_bucket_full(bucket_t, bucket_i) uf_plot_t.ax.set_xlabel("") if print_steps: pr.print_graph(graph_t, printmerged=0) if print_steps and bucket_l != []: pr.printlog( "\n############################ GROW LIST ############################" + f"\nGrowing bucket {bucket_i} of {graph_l.maxbucket}: {bucket_l}" + f"\nRemaining buckets: {graph_l.buckets[bucket_i + 1 : graph_l.maxbucket + 1]}, {graph_l.wastebasket}\n" ) uf_plot_l.waitforkeypress() ufl.list_grow_bucket(bucket_l, bucket_i) if print_steps: pr.print_graph(graph_l, printmerged=0) uf_plot_l.ax.set_xlabel("") if not plot_growth and not print_steps: txt = "" if print_steps else f"Growing bucket #{bucket_i}/{max([graph_t.maxbucket, graph_l.maxbucket])}" uf_plot_t.draw_plot(txt) uf_plot_l.draw_plot() pr.printlog("Clusters grown.") uf_plot_t.waitforkeypress()
limit=limit) cur.execute(query) sims = cur.fetchall() cur.close() con.close() graph_t = go.init_toric_graph(L) graph_l = go.init_toric_graph(L) for comp_id, created_on, seed in sims: time = created_on.strftime("%Y-%m-%d_%H-%M-%S") winner = "list" if ftree_tlist else "tree" name = f"L{L}_p{p}_{comp_id}_{time}_{seed}_{winner}" fileh = logging.FileHandler(f"./logs/{name}.log") formatter = logging.Formatter("%(message)s") fileh.setFormatter(formatter) log = logging.getLogger() # root logger for hdlr in log.handlers[:]: # remove all old handlers log.removeHandler(hdlr) log.addHandler(fileh) pr.printlog( "\n______________________________________________________________________" ) pr.printlog( f"Sim computed by {comp_id} created on {created_on} with L = {L}, p = {p}" ) pr.printlog(f"Winner: {winner}") plot_both(graph_t, graph_l, seed, p, saveanim=None)