unitary_infidelity

Graph.unitary_infidelity(unitary_operator, target, *, name=None)

Calculate the infidelity between a target operation and the actual implemented unitary.

Both operators must be square and have shapes broadcastable to each other.

Parameters:
  • unitary_operator (np.ndarray or Tensor) – The actual unitary operator, \(U\), with shape (..., D, D). Its last two dimensions must be equal and the same as target, and its batch dimensions, if any, must be broadcastable with target.

  • target (np.ndarray or Tensor) – The target operation with respect to which the infidelity will be calculated, \(V\), with shape (..., D, D). Its last two dimensions must be equal and the same as unitary_operator, and its batch dimensions, if any, must be broadcastable with unitary_operator.

  • name (str or None, optional) – The name of the node.

Returns:

The infidelity between the two operators, with shape (...).

Return type:

Tensor

See also

Graph.density_matrix_infidelity

Infidelity between two density matrices.

Graph.infidelity_pwc

Total infidelity of a system with a piecewise-constant Hamiltonian.

Graph.infidelity_stf

Total infidelity of a system with a sampleable Hamiltonian.

Graph.state_infidelity

Infidelity between two quantum states.

Notes

The operational infidelity between the actual unitary and target operators is defined as

\[\mathcal{I} = 1 - \left| \frac{\mathrm{Tr} (V^\dagger U)}{\mathrm{Tr} (V^\dagger V)} \right|^2 .\]

Examples

Calculate the infidelity of a unitary with respect to a \(\sigma_x\) gate.

>>> theta = 0.5
>>> sigma_x = np.array([[0, 1], [1, 0]])
>>> unitary = np.array([[np.cos(theta), np.sin(theta)], [np.sin(theta), -np.cos(theta)]])
>>> graph.unitary_infidelity(unitary_operator=unitary, target=sigma_x, name="infidelity")
<Tensor: name="infidelity", operation_name="unitary_infidelity", shape=()>
>>> result = bo.execute_graph(graph=graph, output_node_names="infidelity")
>>> result["output"]["infidelity"]["value"]
0.7701511529340699

Calculate the time-dependent infidelity of the identity gate for a noiseless single qubit.

>>> sigma_x = np.array([[0, 1], [1, 0]])
>>> hamiltonian = sigma_x * graph.pwc_signal(
...     duration=1, values=np.pi * np.array([0.25, 1, 0.25])
... )
>>> unitaries = graph.time_evolution_operators_pwc(
...     hamiltonian=hamiltonian, sample_times=np.linspace(0, 1, 10)
... )
>>> graph.unitary_infidelity(
...     unitary_operator=unitaries, target=np.eye(2), name="infidelities"
... )
<Tensor: name="infidelities", operation_name="unitary_infidelity", shape=(10,)>
>>> result = bo.execute_graph(graph=graph, output_node_names="infidelities")
>>> result["output"]["infidelities"]["value"]
array([0.        , 0.00759612, 0.03015369, 0.0669873 , 0.32898993,
       0.67101007, 0.9330127 , 0.96984631, 0.99240388, 1.        ])