Esempio n. 1
0
    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()
Esempio n. 2
0
    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()
Esempio n. 3
0
    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)