- 1, # # where :math:`n` is the number of qubits, :math:`P(x_i)` is the # probability of bitstring :math:`x_i` computed for the ideal quantum # circuit, and the average is over the observed bitstrings. # # The idea behind using this fidelity is that it will be close to 1 for # samples obtained from random quantum circuits, such as the one we defined # above, and close to zero for a uniform probability distribution, which # can be effectively sampled from classically. Sampling a bitstring from a # random quantum circuit would follow the distribution # # .. math:: # # Pr(p) = (N - 1)(1- p)^{N-2}, # # where :math:`N = 2^n` is the number of possible bitstrings [#Boixo2018]_. # This distribution is approximated well by the Porter-Thomas distribution, # given by :math:`Pr(p) = Ne^{-Np}`, a characteristic property of chaotic quantum # systems. From this we can then calculate the expectation value # :math:`\left

` as follows: # # .. math:: # # \left

= \int_0^1 p^2 N (N-1)(1-p)^{N-2}dp = \frac{2}{N+1}, # # which leads to the theoretical fidelity # # .. math:: # # F_{XEB} = 2^{n}\left

- 1 = \frac{2N}{N+1} - 1.
#
# We implement this fidelity as the function below, where ``samples`` is a
# list of sampled bitstrings, and ``probs`` is a list with corresponding
# sampling probabilities for the same noiseless circuit.
#
def fidelity_xeb(samples, probs):
sampled_probs = []
for bitstring in samples:
# convert each bitstring into an integer
bitstring_idx = int(bitstring, 2)
# retrieve the corresponding probability for the bitstring
sampled_probs.append(probs[bitstring_idx])
return 2 ** len(samples[0]) * np.mean(sampled_probs) - 1
######################################################################
# We set a random seed and use it to calculate the probability for all the
# possible bitstrings. It is then possible to sample from exactly the same
# circuit by using the same seed. Before calculating the cross-entropy
# benchmarking fidelity, the Pauli-Z samples need to be converted into
# their correponding bitstrings, since we need the samples to be in the
# computational basis.
#
seed = np.random.randint(0, 42424242)
probs = circuit(seed=seed, return_probs=True)
# transpose the samples to get the shape (shots, wires)
circuit_samples = circuit(seed=seed).T
# take the eigenvalues and transform -1 to 1 and 1 to 0
bitstring_samples = []
for sam in circuit_samples:
bitstring_sample = -(sam - 1) // 2
bitstring_samples.append("".join(str(bs) for bs in bitstring_sample))
f_circuit = fidelity_xeb(bitstring_samples, probs)
######################################################################
# Similarly, we can sample random bitstrings from a uniform probability
# distribution by generating all basis states, along with their
# corresponding bitstrings, and sample directly from them using NumPy.
#
basis_states = dev.generate_basis_states(wires)
random_integers = np.random.randint(0, len(basis_states), size=shots)
bitstring_samples = []
for i in random_integers:
bitstring_samples.append("".join(str(bs) for bs in basis_states[i]))
f_uniform = fidelity_xeb(bitstring_samples, probs)
######################################################################
# Finally, let's compare the two different values. Sampling from the
# circuit's probability distribution should give a fidelity close to 1,
# while sampling from a uniform distribution should give a fidelity
# close to 0.
#
# .. note::
#
# The cross-entropy benchmarking fidelity may output
# values that are negative or that are larger than 1, for any finite
# number of samples. This is due to the random nature of the sampling.
# For an infinite amount of samples, or circuit runs, the observed
# values will tend towards the theoretical ones, and will then always
# lie in the 0-to-1 interval.
#
print("Circuit's distribution:", f"{f_circuit:.7f}".rjust(12))
print("Uniform distribution:", f"{f_uniform:.7f}".rjust(14))
######################################################################
# .. rst-class:: sphx-glr-script-out
#
# Out:
#
# .. code-block:: none
#
# Circuit's distribution: 1.0398803
# Uniform distribution: 0.0013487
#
######################################################################
# To show that the fidelity from the circuit sampling actually tends
# towards the theoretical value calculated above we can run several
# different random circuits, calculate their respective cross-entropy
# benchmarking fidelities and then calculate the mean fidelity of all the
# runs. The more evaluations we do, the closer to the theoretical value we
# should get.
#
# In the experiment, they typically calculate each of their
# presented fidelities over ten circuit instances, which only differ
# in the choices of single-qubit gates. In this demo, we use even more
# instances to demonstrate a value closer to the theoretically obtained
# one.
#
# .. note::
#
# The following mean fidelity calculations can be interesting to play
# around with. You can change the qubit grid at the top of this demo
# using, e.g., 8 or 4 qubits; change the number of shots used; as well
# as the number of circuit evaluations below. Running the following code
# snippet, the mean fidelity should still tend towards the theoretical
# value (which will be lower for fewer qubits).
#
N = 2 ** wires
theoretical_value = 2 * N / (N + 1) - 1
print("Theoretical:", f"{theoretical_value:.7f}".rjust(24))
f_circuit = []
num_of_evaluations = 100
for i in range(num_of_evaluations):
seed = np.random.randint(0, 42424242)
probs = circuit(seed=seed, return_probs=True)
samples = circuit(seed=seed).T
bitstring_samples = []
for sam in samples:
new_sam = -(sam - 1) // 2
bitstring_samples.append("".join(str(bs) for bs in new_sam))
f_circuit.append(fidelity_xeb(bitstring_samples, probs))
print(f"\r{i + 1:4d} / {num_of_evaluations:4d}{' ':17}{np.mean(f_circuit):.7f}", end="")
print("\rObserved:", f"{np.mean(f_circuit):.7f}".rjust(27))
##############################################################################
# .. rst-class:: sphx-glr-script-out
#
# Out:
#
# .. code-block:: none
#
# Theoretical: 0.9995118
# Observed: 0.9999512
#
######################################################################
# Classical hardness
# ------------------
#
# Why are we calculating this specific fidelity, and what does it actually
# mean if we get a cross-entropy benchmarking fidelity close to 1? This is
# an important question, containing one of the main arguments behind why
# this experiment is used to demonstrate "quantum supremacy".
#
# Much is due to the Porter-Thompson probability distribution that the
# random quantum circuits follow, which is hard to simulate classically.
# On the other hand, a quantum device, running a circuit as the one
# constructed above, should be able to sample from such a distribution
# without much overhead. Thus, by showing that a quantum device can produce
# a high enough fidelity value for a large enough circuit, "quantum
# supremacy" can be claimed. This is exactly what Google's experiment
# has done.
#
# There's still one issue that hasn't been touched on yet: the addition of
# noise in quantum hardware. Simply put, this noise will lower the
# cross-entropy benchmarking fidelity---the larger the
# circuit, the more noise there will be, and thus the lower the fidelity, with the
# fidelity approaching 0 as the noise increases.
# By calculating the specific single-qubit, two-qubit, and readout errors
# of the Sycamore chip, and using them to simulate a noisy circuit, the Google
# AI quantum team was able to compare the run-times with the output from
# their actual hardware device. This way, they managed to show that a
# significant speedup could be gained from using a quantum computer, and
# thus proclaimed "quantum supremacy" (see Fig. 4 in [#Arute2019]_).
#
# .. note::
#
# For more reading on this, the original paper [#Arute2019]_ is highly
# recommended (along with the suplementary information [#Arute2019sup]_ if you want
# to dive deeper into the math and physics of the experiment). The blog
# post in [#Sohaib2019]_, along with the accompanying GitHub repo, also provides
# a nice introduction to the cross-entropy benchmarking fidelity, and
# includes calculations highlighting the effects of added noise models.
#
######################################################################
# References
# ----------
#
# .. [#Arute2019]
#
# Arute, F., Arya, K., Babbush, R. et al. "Quantum supremacy using a programmable
# superconducting processor"
# `Nature 574, 505-510 (2019)