# The Swap Test Algorithm

The swap test is a quantum function that checks the overlap between two quantum states: the inputs of the function are two quantum registers of the same size, $$|\psi_1\rangle, \,|\psi_2\rangle$$, and it returns as an output a single "test" qubit whose state encodes the overlap between the two inputs: $$|q\rangle_{\rm test} = \alpha|0\rangle + \sqrt{1-\alpha^2}|1\rangle$$, with

$\alpha^2 = \frac{1}{2}\left(1+|\langle \psi_1 |\psi_2 \rangle |^2\right).$

Thus, the probability of measuring the test qubit at state $$|0\rangle$$ is $$1$$ if the states are identical (up to a global phase) and 0.5 if the states are orthogonal to each other.

The quantum model starts with an H gate on the test qubit, followed by swapping between the two states controlled on the test qubit (a controlled-SWAP gate for each of the qubits in the two states), and a final H gate on the test qubit:

Prepare two random states:

import numpy as np

np.random.seed(12)

NUM_QUBITS = 3
amps1 = 1 - 2 * np.random.rand(
2**NUM_QUBITS
)  # vector of 2^3 numbers in the range [-1,1]
amps2 = 1 - 2 * np.random.rand(2**NUM_QUBITS)
amps1 = amps1 / np.linalg.norm(amps1)  # normalize the vector
amps2 = amps2 / np.linalg.norm(amps2)


Create a model and synthesize:

from classiq import (
Output,
QArray,
QBit,
create_model,
execute,
prepare_amplitudes,
qfunc,
set_execution_preferences,
swap_test,
synthesize,
)
from classiq.execution import ExecutionPreferences

@qfunc
def main(test: Output[QBit]):

state1 = QArray("state1")
state2 = QArray("state2")
prepare_amplitudes(amps1.tolist(), 0.0, state1)
prepare_amplitudes(amps2.tolist(), 0.0, state2)
swap_test(state1, state2, test)

qmod = create_model(main)
qmod = set_execution_preferences(
qmod, execution_preferences=ExecutionPreferences(num_shots=100_000)
)
qprog = synthesize(qmod)


## swap test - qmod implementations

The swap test is defined as a library function in the qmod language (definition can be found on our public github ). Users can easily add their own functions

from classiq import show

show(qprog)

Opening: https://platform.classiq.io/circuit/56682c53-15bf-4d1f-81e2-1121ce978b16?version=0.41.0.dev39%2B79c8fd0855

from classiq import write_qmod

write_qmod(qmod, "swap_test", decimal_precision=15)


Verify the results:

res = execute(qprog).result()


## Comparing the measured overlap with the exact overlap

Using the expected probability of measuring the state $$|0\rangle$$ as defined above:

$\alpha^2 = \frac{1}{2}\left(1+|\langle \psi_1 |\psi_2 \rangle |^2\right).$

we extract the overlap $$|\langle \psi_1 |\psi_2 \rangle |^2=\sqrt{2 P\left(q_{\text{test}}=|0\rangle\right)-1}$$
The exact overlap is computed with the dot product of the two state-vectors. Note that for the sake of this demonstration we execute this circuit $$100,000$$ times to improve the precision of the probability estimate. This is usually not required in actual programs.

overlap_from_swap_test = np.sqrt(
2 * res[0].value.counts["0"] / sum(res[0].value.counts.values()) - 1
)
exact_overlap = np.abs(amps1 @ amps2)

print("States overlap from Swap-Test result:", overlap_from_swap_test)
print("States overlap from classical calculation:", exact_overlap)

States overlap from Swap-Test result: 0.4673970474874655
States overlap from classical calculation: 0.46972037234759095

RTOL = 0.05
assert np.isclose(
overlap_from_swap_test, exact_overlap, RTOL
), f"""
The quantum result is too far than classical one, by a relative tolerance of {RTOL}. Please verify your parameters"""