Note
Click here to download the full example code
Quantum Capacity
import matplotlib.pyplot as plt
import numpy as np
import random
import trueq as tq
First, we demonstrate using QCAP in the simplest setting: we create a small circuit and compute its QCAP bound.
# make a circuit to assess
circuit = tq.Circuit(
[
{1: tq.Gate.x, (0, 2): tq.Gate.cz},
{0: tq.Gate.h, 1: tq.Gate.h},
{(1, 2): tq.Gate.cnot, (0, 4): tq.Gate.cz},
]
)
# generate a circuit collection to measure the QCAP
circuits = tq.make_qcap(circuit, [0, 4, 16, 32])
# run the circuits on your hardware or simulator
sim = tq.Simulator().add_overrotation(0.03)
sim.run(circuits)
# generate the QCAP bound
tq.qcap_bound(circuit, circuits)
Next, we perform a small study demonstrating the effectiveness of the QCAP bound on the family of random circuits which use the following hard cycles:
hard_cycles = [
tq.Cycle({(0, 1): tq.Gate.cz, (2, 3): tq.Gate.cz}),
tq.Cycle({(0, 2): tq.Gate.cz, (1, 3): tq.Gate.cz}),
tq.Cycle({(0, 3): tq.Gate.cz, (1, 2): tq.Gate.cz}),
]
First, we use the QCAP assessment to measure the process infidelity of each of these hard cycles.
qcap_circuits = tq.make_qcap(hard_cycles, [4, 16])
sim.run(qcap_circuits)
qcap_fit = qcap_circuits.fit()
Then, we generate a random circuit using these hard cycles interleaved with single qubit cycles for a number of circuit depths. In each instance, we randomly compile the random circuit 20 times; QCAP bounds the performance of circuits whose noise profile has been tailored by RC.
def make_random_circuit(depth):
circuit = tq.Circuit()
for _ in range(depth):
circuit += {q: tq.Gate.random(2) for q in range(4)}
circuit += random.choice(hard_cycles)
circuit += {q: tq.Gate.random(2) for q in range(4)}
circuit.measure_all()
circuit.key = tq.Key(depth=depth)
return circuit
random_circuits = tq.CircuitCollection()
depths = list(range(5, 30, 5))
for depth in depths:
bare_circuit = make_random_circuit(depth)
random_circuits += bare_circuit
random_circuits += tq.randomly_compile(bare_circuit, 20)
sim.run(random_circuits, 1000)
Finally, we collect and plot the data.
qcaps = np.empty((len(depths), 2))
rc_tvds = np.empty((len(depths), 2))
for idx, depth in enumerate(depths):
bare_circuit = random_circuits.subset(protocol=["RC"], depth=depth)[0]
rc_circuits = random_circuits.subset(protocol="RC", depth=depth)
# compute the QCAP bound for this circuit
qcaps[idx, :] = tq.qcap_bound(bare_circuit, qcap_fit).e_IU[1:]
# compute the TVD from the RC results to the ideal bitstring distribution
ideal_probs = tq.Simulator().sample(bare_circuit, float("inf"))
rc_tvds[idx, :] = rc_circuits.sum_results().tvd(ideal_probs)
plt.errorbar(depths, qcaps[:, 0], yerr=2.96 * qcaps[:, 1], label="QCAP Bound")
plt.errorbar(depths, rc_tvds[:, 0], yerr=2.96 * rc_tvds[:, 1], label="RC TVD")
plt.ylim([0, 0.3])
plt.legend()
plt.xlabel("Circuit Depth")

Text(0.5, 23.52222222222222, 'Circuit Depth')
Total running time of the script: ( 0 minutes 18.116 seconds)