Functionalities to compute the overlap between states through a swap test.

swap_test_overlap[source]

swap_test_overlap(state0:Union[QuantumCircuit, CircuitStateFn], state1:Union[QuantumCircuit, CircuitStateFn, Iterable[Union[QuantumCircuit, CircuitStateFn]], NoneType]=None, param_dict:Optional[Dict[ParameterExpression, List[float]]]=None, backend:Union[Backend, QuantumInstance, NoneType]=None)

Returns overlap between states using swap test.

The swap test is one of the most common ways of computing the overlap between quantum states. It relies on the construction of a circuit of $2n+1$ qubits, where $n$ is the number of qubits of the states that are to be compared. The additional qubit is used as control qubit for a set of control-swap gates performed between the qubits of the states.

We have taken the convention of having the additional qubit as the first one. This way, the operator applied to the tensored states looks as follows for two 3-qubit states.

_swap_test_operator(3).primitive.draw('mpl')

The first state $|\psi\rangle$ would, for instance, take qubits $q_1, q_2, q_3$ and the second state $|\phi\rangle$ would take $q_4, q_5, q_6$. The ancilla qubit, $q0$ is then measured and the probability of measuring zero $P_0$ is proportional to the overlap between the states, such that $$\text{Tr}\left[\rho_\psi\rho_\phi\right] = 2P_0 - 1.$$

The behaviour is analogous to the other overlap computation functions with the exception that swap_test_overlap does accept QuantumCircuit inputs, provided that it heavily relies on quantum circuit construction.

See some function call examples below and refer to the basic usage for a joint explanation of the overlap computation functions.

qc0 = QuantumCircuit(2)
qc0.x(0)
qc0.draw('mpl')
theta0 = Parameter('θ')
qc1 = QuantumCircuit(2)
qc1.x(0)
qc1.rx(theta0, 1)
qc1.draw('mpl')
state0 = CircuitStateFn(qc0)
purity = swap_test_overlap(state0)
purity
array([1.])
theta_values = [0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi]
param_dict = {theta0: theta_values}
state0 = CircuitStateFn(qc0)
state1 = CircuitStateFn(qc1).bind_parameters(param_dict)
overlaps = swap_test_overlap(state0, state1)
overlaps
array([ 1.        ,  0.47851562, -0.0078125 ,  0.44140625,  1.        ])
param_state = CircuitStateFn(qc1)
overlaps = swap_test_overlap(param_state, param_dict=param_dict)
overlaps
array([[ 1.        ,  0.49609375,  0.0078125 ,  0.50195312,  1.        ],
       [ 0.49609375,  1.        ,  0.48242188,  0.03320312,  0.51171875],
       [ 0.0078125 ,  0.48242188,  1.        ,  0.50585938, -0.00976562],
       [ 0.50195312,  0.03320312,  0.50585938,  1.        ,  0.51171875],
       [ 1.        ,  0.51171875, -0.00976562,  0.51171875,  1.        ]])
overlaps.diagonal()
array([1., 1., 1., 1., 1.])