def basic_optimization(c, g):
    orig_tcount = c.tcount()
    orig_2qubitcount = c.twoqubitcount()

    c_opt = zx.basic_optimization(c)

    opt_tcount = c_opt.tcount()
    opt_2qubitcount = c_opt.twoqubitcount()
    if orig_tcount == opt_tcount and orig_2qubitcount == opt_2qubitcount:
        return False, (c, g)
    return True, (c_opt, c.to_graph())
Пример #2
0
def g_score(g):
    g_tmp = g.copy()

    # FIXME: VERY EXPENSIVE. only to enable circuit extraction.
    # A better strategy would be to probailistically full_reduce

    zx.full_reduce(g_tmp)
    c = zx.extract_circuit(g_tmp.copy()).to_basic_gates()
    c = zx.basic_optimization(c)

    return c_score(c)
    """
def rand_lc(c, g, reduce_prob=0.1):
    g_tmp = g.copy()
    apply_rand_lc(g_tmp)

    # Note the work around to not always full_reduce the graph itself!
    g_fr = g_tmp.copy()
    zx.full_reduce(g_fr)
    c_new = zx.extract_circuit(g_fr.copy()).to_basic_gates()
    c_new = zx.basic_optimization(c_new)
    if random.uniform(0, 1) < reduce_prob:
        g_tmp = g_fr.copy()
    return True, (c_new, g_tmp)
    def evolve(self, g, n_mutants, n_generations):
        self.n_mutants = n_mutants
        self.n_gens = n_generations

        self.g_orig = g.copy()
        to_graph_like(self.g_orig)
        self.c_orig = zx.extract_circuit(self.g_orig.copy()).to_basic_gates()
        self.c_orig = zx.basic_optimization(self.c_orig)

        # self.c_orig = c
        # self.g_orig = c.to_graph()
        # to_graph_like(self.g_orig)
        # self.mutants = [Mutant(c, self.g_orig) for _ in range(self.n_mutants)]
        self.mutants = [Mutant(self.c_orig, self.g_orig) for _ in range(self.n_mutants)]

        self.update_scores()
        best_mutant = min(self.mutants, key=lambda m: m.score) # FIXME: Check if this assignment is by reference or value
        best_score = best_mutant.score

        gen_scores = [best_score]
        best_scores = [best_score]
        for i in tqdm(range(self.n_gens), desc="Generations", disable=self.quiet):
            n_unique_mutants = len(list(set([id(m) for m in self.mutants])))
            assert(n_unique_mutants == self.n_mutants)

            self.mutate()
            # self.update_scores()
            best_in_gen = min(self.mutants, key=lambda m: m.score)
            gen_scores.append(best_in_gen.score) # So that if we never improve, we see each generation. Because our actions might all rely on extracting, we may never improve on the original
            if best_in_gen.score < best_score:
                best_mutant = deepcopy(best_in_gen)
                best_score = best_in_gen.score

            best_scores.append(best_score)
            if all([m.dead for m in self.mutants]):
                print("[_optimize] stopping early -- all mutants are dead")
                break

            self.select()

        return best_scores, gen_scores, best_mutant.c_curr
Пример #5
0
    c = zx.generate.CNOT_HAD_PHASE_circuit(qubits=N_QUBITS,
                                           depth=DEPTH,
                                           clifford=False)
    print("----- initial -----")
    print(c.stats())

    # zx.draw(c)
    plt.show()
    plt.close('all')

    g = c.to_graph()

    g_fr = g.copy()
    zx.full_reduce(g_fr)
    c_fr = zx.extract_circuit(g_fr.copy()).to_basic_gates()
    c_fr = zx.basic_optimization(c_fr)
    # note: we don't reset g_fr here because for any future annealing, we'd really optimize after the graph produced by full_reduce, rather than something resulting from extraction
    print("\n----- full_reduce + basic_optimization -----")
    print(c_fr.stats())

    g_just_tr = g.copy()
    zx.teleport_reduce(g_just_tr)
    c_just_tr = zx.Circuit.from_graph(g_just_tr.copy()).to_basic_gates()
    print("\n----- teleport_reduce -----")
    print(c_just_tr.stats())

    g_tr = g.copy()
    zx.teleport_reduce(g_tr)
    c_tr = zx.Circuit.from_graph(g_tr.copy()).to_basic_gates()
    # c_opt = zx.full_optimize(c_opt)
    c_tr = zx.basic_optimization(c_tr)
    N_ITERS = 5000
    INTERVAL = 250
    improvement_after = { x: list() for x in range(0, N_ITERS, INTERVAL) }

    REDUCE_METHOD = "TR"

    for c in tqdm(cs, desc="Circuits..."):
        g = c.to_graph()

        g_tmp = g.copy()

        if REDUCE_METHOD == "TR":
            zx.teleport_reduce(g_tmp)
            c_tr = zx.Circuit.from_graph(g_tmp.copy()).to_basic_gates()
            c_tr = zx.basic_optimization(c_tr)
            g_simp = c_tr.to_graph()
        elif REDUCE_METHOD == "FR":
            zx.full_reduce(g_tmp)
            g_simp = g_tmp.copy()
        else:
            raise RuntimeError(f"Invalid REDUCE_METHOD: {REDUCE_METHOD}")

        to_graph_like(g_simp)

        _, scores = pivot_anneal(g_simp, iters=N_ITERS)
        final_score = scores[-1]
        for x in range(0, N_ITERS, INTERVAL):
            if final_score < scores[x]:
                improvement_after[x].append(1)
            else:
Пример #7
0
    """

    # Compare GA vs SA

    N_QUBITS = 9
    DEPTH = 100

    c = zx.generate.CNOT_HAD_PHASE_circuit(qubits=N_QUBITS,
                                           depth=DEPTH,
                                           clifford=False)
    g = c.to_graph()

    g_tr = g.copy()
    zx.teleport_reduce(g_tr)
    c_tr = zx.Circuit.from_graph(g_tr.copy())
    c_tr = zx.basic_optimization(c_tr).to_basic_gates()
    g_tr = c_tr.to_graph()
    to_graph_like(g_tr)

    # fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(5, 3))
    fig, axes = plt.subplots(nrows=1, ncols=2)

    ## GA part

    N_MUTANTS = 100
    N_GENS = 100
    actions = [ga.rand_pivot, ga.rand_lc, ga.do_nothing]
    # actions = [rand_lc, rand_pivot]
    ga_opt = ga.GeneticOptimizer(actions,
                                 n_generations=N_GENS,
                                 n_mutants=N_MUTANTS,

if __name__ == "__main__":
    # imports
    import matplotlib.pyplot as plt

    N_QUBITS = 5
    DEPTH = 100

    c = zx.generate.CNOT_HAD_PHASE_circuit(qubits=N_QUBITS, depth=DEPTH, clifford=False)
    g = c.to_graph()

    g_tr = g.copy()
    zx.teleport_reduce(g_tr)
    c_tr = zx.Circuit.from_graph(g_tr.copy())
    c_tr = zx.basic_optimization(c_tr).to_basic_gates()
    g_tr = c_tr.to_graph()
    to_graph_like(g_tr)

    # Testing for simplification operators
    """
    actions = [
        # BASIC
        color_change, remove_id, fuse, strong_comp, copy_X,

        # INTERMEDIATE
        spider_simp, pivot_gadget_simp, pivot_boundary_simp, lcomp_simp, bialg_simp, spider_simp,
        id_simp, gadget_simp, # supplementary_simp,
        cx_cancellation, optimize_1q, optimize_1q_decomp,
        # remove_redundancies, pauli_simp, clifford_simp, # kak_decomposition