Source code for toqito.state_opt.state_distinguishability

"""State distinguishability."""
import cvxpy
import numpy as np
from .state_helper import __is_states_valid, __is_probs_valid


[docs] def state_distinguishability( states: list[np.ndarray], probs: list[float] = None, dist_method: str = "min-error" ) -> float: r""" Compute probability of state distinguishability [ELD03]_. The "quantum state distinguishability" problem involves a collection of :math:`n` quantum states .. math:: \rho = \{ \rho_0, \ldots, \rho_n \}, as well as a list of corresponding probabilities .. math:: p = \{ p_0, \ldots, p_n \}. Alice chooses :math:`i` with probability :math:`p_i` and creates the state :math:`\rho_i` Bob wants to guess which state he was given from the collection of states. One can specify the distinguishability method using the :code:`dist_method` argument. For :code:`dist_method = "min-error"`, this is the default method that yields the probability of distinguishing quantum states that minimize the probability of error. For :code:`dist_method = "unambiguous"`, Alice and Bob never provide an incorrect answer, although it is possible that their answer is inconclusive. When :code:`dist_method = "min-error"`, this function implements the following semidefinite program that provides the optimal probability with which Bob can conduct quantum state distinguishability. .. math:: \begin{align*} \text{maximize:} \quad & \sum_{i=0}^n p_i \langle M_i, \rho_i \rangle \\ \text{subject to:} \quad & M_0 + \ldots + M_n = \mathbb{I},\\ & M_0, \ldots, M_n \geq 0 \end{align*} When :code:`dist_method = "unambiguous"`, this function implements the following semidefinite program that provides the optimal probability with which Bob can conduct unambiguous quantum state distinguishability. .. math:: \begin{align*} \text{maximize:} \quad & \sum_{i=0}^n p_i \langle M_i, \rho_i \rangle \\ \text{subject to:} \quad & M_0 + \ldots + M_{n+1} = \mathbb{I},\\ & \langle M_i, \rho_j \rangle = 0, \quad 1 \leq i, j \leq n, \quad i \not= j, \\ & M_0, \ldots, M_n \geq 0. \end{align*} Examples ========== State distinguishability for two state density matrices. In this example, the states :math:`|0\rangle` and :math:`|1\rangle` are orthogonal and therefore perfectly distinguishable. >>> from toqito.states import basis >>> from toqito.state_opt import state_distinguishability >>> e_0, e_1 = basis(2, 0), basis(2, 1) >>> e_00 = e_0 * e_0.conj().T >>> e_11 = e_1 * e_1.conj().T >>> states = [e_00, e_11] >>> probs = [1 / 2, 1 / 2] >>> res = state_distinguishability(states, probs) 1.000 References ========== .. [ELD03] Eldar, Yonina C. "A semidefinite programming approach to optimal unambiguous discrimination of quantum states." IEEE Transactions on information theory 49.2 (2003): 446-456. https://arxiv.org/abs/quant-ph/0206093 :param states: A list of states provided as either matrices or vectors. :param probs: Respective list of probabilities each state is selected. :param dist_method: Method of distinguishing to use. :return: The optimal probability with which Bob can distinguish the state. """ obj_func = [] measurements = [] constraints = [] __is_states_valid(states) if probs is None: probs = [1 / len(states)] * len(states) __is_probs_valid(probs) dim_x, dim_y = states[0].shape # The variable `states` is provided as a list of vectors. Transform them # into density matrices. if dim_y == 1: for i, state_ket in enumerate(states): states[i] = state_ket * state_ket.conj().T # Unambiguous state discrimination has an additional constraint on the states and measurements. if dist_method == "unambiguous": # Note we have one additional measurement operator in the unambiguous case. for i in range(len(states) + 1): measurements.append(cvxpy.Variable((dim_x, dim_x), PSD=True)) # This is an extra condition required for the unambiguous case. for i, _ in enumerate(states): for j, _ in enumerate(states): if i != j: constraints.append(cvxpy.trace(states[j].conj().T @ measurements[i]) == 0) if dist_method == "min-error": for i, _ in enumerate(states): measurements.append(cvxpy.Variable((dim_x, dim_x), PSD=True)) # Objective function is the inner product between the states and measurements. for i, _ in enumerate(states): obj_func.append(probs[i] * cvxpy.trace(states[i].conj().T @ measurements[i])) constraints.append(sum(measurements) == np.identity(dim_x)) objective = cvxpy.Maximize(sum(obj_func)) problem = cvxpy.Problem(objective, constraints) sol_default = problem.solve() return sol_default