def run(n_qubits: int, circuit_length: int, tolerance: float, noise_strength: float, n_trials: int) \
        -> Tuple[float, float]:
    total = 0
    total_gates_cut = 0
    noise = standard_noise_channels(noise_strength, n_qubits)

    for _ in range(n_trials):
        circuit, key = generate_random_circuit(n_qubits, circuit_length)
        pruned = prune_circuit(circuit, tolerance)
        gates_cut = len(circuit) - len(pruned)
        total_gates_cut += gates_cut

        unitary = np.eye(2**n_qubits)
        for s in circuit[::-1]:
            unitary = key[s] @ unitary

        pruned_unitary = np.eye(2**n_qubits)
        for s in pruned[::-1]:
            pruned_unitary = key[s] @ pruned_unitary

        f_pro = J_fidelity.ProcessFidelityFinder(n_qubits)
        original_f = f_pro.f_pro_experimental(circuit, unitary, noise, key)
        pruned_f = f_pro.f_pro_experimental(pruned, unitary, noise, key)
        difference = pruned_f - original_f
        total += difference
    return total / n_trials, total_gates_cut / n_trials
Пример #2
0
def plot_fidelities(circuits: Iterable[Iterable[Any]], U: np.ndarray,
                    noise_strength: float):
    max_acc = len(circuits)

    lengths = [len(c) for c in circuits]

    noise_channels = standard_noise_channels(noise_strength)

    pro_fid = J_fidelity.ProcessFidelityFinder(1)
    J_noiseless = [pro_fid.f_pro_experimental(c, U) for c in circuits]

    def model(n, a, b):
        return 1 - (a * 0.5**n) + b * noise_strength * n

    start = time.time()
    J_fidelities = [
        pro_fid.f_pro_experimental(c, U, noise_channels) for c in circuits
    ]
    end = time.time()
    print("The best accuracy for J was: " +
          str(max(range(max_acc), key=lambda x: J_fidelities[x])))
    print("It took " + str(end - start) + " seconds")
    params1 = curve_fit(model, lengths, J_fidelities)[0]
    print("gradient for J is " + str(params1[1]))
    print()

    start = time.time()
    S_fidelities = [
        S_fidelity.experimental(c, U, 1000, noise_channels) for c in circuits
    ]
    end = time.time()
    print("The best accuracy for S was: " +
          str(max(range(max_acc), key=lambda x: S_fidelities[x])))
    print("It took " + str(end - start) + " seconds")
    params2 = curve_fit(model, lengths, S_fidelities)[0]
    print("gradient for S is " + str(params2[1]))
    print()

    # This will take several minutes and is really really inaccurate with any amount of noise
    # start = time.time()
    # J_simulated = [J_fidelity.f_pro_simulated(c, U, noise_strength, noise_strength, noise_strength) for c in circuits]
    # end = time.time()
    # print("The best accuracy for simulation was: " + str(max(range(max_acc), key=lambda x: J_simulated[x])))
    # print("It took " + str(end-start) + " seconds")

    plt.figure()
    lineJ2, = plt.plot(J_noiseless)
    lineJ, = plt.plot(J_fidelities)
    lineS, = plt.plot(S_fidelities)

    plt.xlabel('Accuracy')
    plt.ylabel('Fidelity')
    plt.legend((lineJ2, lineJ, lineS),
               ('J_fidelity (noiseless)', 'J_fidelity', 'S_fidelity'))
    plt.savefig('../graphs/fid.png')
    return
def is_it_worth_it(unitary: np.ndarray, noise_strength: float) -> bool:
    n_qubits = int(math.log(unitary.shape[0], 2))
    noise = standard_noise_channels(noise_strength, n_qubits)
    circuit = ["A"]
    key = {"A": unitary}
    f_pro = J_fidelity.ProcessFidelityFinder(n_qubits)
    do_it = f_pro.f_pro_experimental(circuit, unitary, noise, key)
    dont_do_it = f_pro.f_pro([unitary], np.eye(unitary.shape[0]))
    if do_it > dont_do_it:
        return True
    return False
def run_v2(n_qubits: int, circuit_length: int, noise_strength: float,
           n_trials: int) -> Tuple[float, float]:
    noise = standard_noise_channels(noise_strength, n_qubits)

    def do_once():
        circuit, key = generate_random_circuit(n_qubits, circuit_length)
        pruned = prune_circuit_v2(circuit, key, noise_strength)
        gates_cut = len(circuit) - len(pruned)

        unitary = np.eye(2**n_qubits)
        for s in circuit[::-1]:
            unitary = key[s] @ unitary

        f_pro = J_fidelity.ProcessFidelityFinder(n_qubits)
        original_f = f_pro.f_pro_experimental(circuit, unitary, noise, key)
        pruned_f = f_pro.f_pro_experimental(pruned, unitary, noise, key)
        difference = pruned_f - original_f
        return difference, gates_cut

    res = [do_once() for _ in range(n_trials)]
    total = sum([r[0] for r in res])
    total_gates_cut = sum([r[1] for r in res])

    return total / n_trials, total_gates_cut / n_trials
    return {**get_Rz_key(angle, 4), **cnot_key}


circuit1 = ["cnot01", "cnot12", "cnot23", "Rz3", "cnot23", "cnot12",
            "cnot01"]  # Original phase gadget
circuit2 = ["cnot01", "cnot32", "cnot12", "Rz2", "cnot12", "cnot32",
            "cnot01"]  # Balanced tree
circuit3 = ["cnot01-32", "cnot12", "Rz2", "cnot12",
            "cnot01-32"]  # Parallel CNOTs in balanced tree

theta = math.pi / 4

circuit_key = get_key(theta)

noise_strength = 0.001
noise_channels = standard_noise_channels(noise_strength, n_qubits=4)

print(
    effect_of_noise(circuit1,
                    noise_channels,
                    n_qubits=4,
                    circuit_key=circuit_key))
print(
    effect_of_noise(circuit2,
                    noise_channels,
                    n_qubits=4,
                    circuit_key=circuit_key))
print(
    effect_of_noise(circuit3,
                    noise_channels,
                    n_qubits=4,