def test_is_povm_true(): """Test if valid measurement returns True.""" dim, num_inputs, num_outputs = 2, 2, 2 measurements = random_povm(dim, num_inputs, num_outputs) np.testing.assert_equal( is_povm([measurements[:, :, 0, 0], measurements[:, :, 0, 1]]), True)
def test_random_povm_unitary_not_real(): """Generate random POVMs and check that they sum to the identity.""" dim, num_inputs, num_outputs = 2, 2, 2 povms = random_povm(dim, num_inputs, num_outputs) np.testing.assert_equal( np.allclose(povms[:, :, 0, 0] + povms[:, :, 0, 1], np.identity(dim)), True)
def genPOVMs(self): ''' Initialise each player with random POVMs ''' opDict = {} for playerId in range(self.nbJoueurs): povms = random_povm( self.dimension, 2, self.dimension) # dim = 2, nbInput = 2, nbOutput = 2 for type in ["0", "1"]: # Generate a unitary to use to make a random projective measurement U = random_unitary(self.dimension) for answer in ["0", "1"]: # TODO: Generalise to higher dimension if (self.dimension > 2): print( "Mauvaise implémentation de la dimension, cf seesaw - ligne 63" ) exit(0) proj = np.transpose([U[int(answer)]]) opDict[str(playerId) + answer + type] = pure_to_mixed(proj) return opDict
def test_random_povm_unitary_not_real(self): """Generate random POVMs and check that they sum to the identity.""" dim, num_inputs, num_outputs = 2, 2, 2 povms = random_povm(dim, num_inputs, num_outputs) self.assertEqual(povms.shape, (dim, dim, num_inputs, num_outputs)) np.testing.assert_allclose(povms[:, :, 0, 0] + povms[:, :, 0, 1], np.identity(dim), atol=1e-7)
def test_random_povm_uneven_dimensions(self): """Generate random POVMs of uneven dimensions""" dim, num_inputs, num_outputs = 2, 3, 4 povms = random_povm(dim, num_inputs, num_outputs) self.assertEqual(povms.shape, (dim, dim, num_inputs, num_outputs)) for i in range(num_inputs): povm_sum = np.sum(povms[:, :, i, :], axis=-1) np.testing.assert_allclose(povm_sum, np.identity(dim), atol=1e-7)
def quantum_value_lower_bound( self, iters: int = 5, tol: float = 10e-6, ): r""" Compute a lower bound on the quantum value of a nonlocal game [LD07]_. Calculates a lower bound on the maximum value that the specified nonlocal game can take on in quantum mechanical settings where Alice and Bob each have access to `d`-dimensional quantum system. This function works by starting with a randomly-generated POVM for Bob, and then optimizing Alice's POVM and the shared entangled state. Then Alice's POVM and the entangled state are fixed, and Bob's POVM is optimized. And so on, back and forth between Alice and Bob until convergence is reached. Note that the algorithm is not guaranteed to obtain the optimal local bound and can get stuck in local minimum values. The alleviate this, the `iter` parameter allows one to run the algorithm some pre-specified number of times and keep the highest value obtained. The algorithm is based on the alternating projections algorithm as it can be applied to Bell inequalities as shown in [LD07]_. The alternating projection algorithm has also been referred to as the "see-saw" algorithm as it goes back and forth between the following two semidefinite programs: .. math:: \begin{equation} \begin{aligned} \textbf{SDP-1:} \quad & \\ \text{maximize:} \quad & \sum_{(x,y \in \Sigma)} \pi(x,y) \sum_{(a,b) \in \Gamma} V(a,b|x,y) \langle B_b^y, A_a^x \rangle \\ \text{subject to:} \quad & \sum_{a \in \Gamma_{\mathsf{A}}}= \tau, \qquad \qquad \forall x \in \Sigma_{\mathsf{A}}, \\ \quad & A_a^x \in \text{Pos}(\mathcal{A}), \qquad \forall x \in \Sigma_{\mathsf{A}}, \ \forall a \in \Gamma_{\mathsf{A}}, \\ & \tau \in \text{D}(\mathcal{A}). \end{aligned} \end{equation} .. math:: \begin{equation} \begin{aligned} \textbf{SDP-2:} \quad & \\ \text{maximize:} \quad & \sum_{(x,y \in \Sigma)} \pi(x,y) \sum_{(a,b) \in \Gamma} V(a,b|x,y) \langle B_b^y, A_a^x \rangle \\ \text{subject to:} \quad & \sum_{b \in \Gamma_{\mathsf{B}}}= \mathbb{I}, \qquad \qquad \forall y \in \Sigma_{\mathsf{B}}, \\ \quad & B_b^y \in \text{Pos}(\mathcal{B}), \qquad \forall y \in \Sigma_{\mathsf{B}}, \ \forall b \in \Gamma_{\mathsf{B}}. \end{aligned} \end{equation} Examples ========== The CHSH game The CHSH game is a two-player nonlocal game with the following probability distribution and question and answer sets. .. math:: \begin{equation} \begin{aligned} \pi(x,y) = \frac{1}{4}, \qquad (x,y) \in \Sigma_A \times \Sigma_B, \qquad \text{and} \qquad (a, b) \in \Gamma_A \times \Gamma_B, \end{aligned} \end{equation} where .. math:: \begin{equation} \Sigma_A = \{0, 1\}, \quad \Sigma_B = \{0, 1\}, \quad \Gamma_A = \{0,1\}, \quad \text{and} \quad \Gamma_B = \{0, 1\}. \end{equation} Alice and Bob win the CHSH game if and only if the following equation is satisfied. ..math:: \begin{equation} a \oplus b = x \land y. \end{equation} Recall that :math:`\oplus` refers to the XOR operation. The optimal quantum value of CHSH is :math:`\cos(\pi/8)^2 \approx 0.8536` where the optimal classical value is :math:`3/4`. >>> import numpy as np >>> from toqito.nonlocal_games.nonlocal_game import NonlocalGame >>> >>> dim = 2 >>> num_alice_inputs, num_alice_outputs = 2, 2 >>> num_bob_inputs, num_bob_outputs = 2, 2 >>> prob_mat = np.array([[1 / 4, 1 / 4], [1 / 4, 1 / 4]]) >>> pred_mat = np.zeros( >>> (num_alice_outputs, num_bob_outputs, num_alice_inputs, num_bob_inputs) >>> ) >>> >>> for a_alice in range(num_alice_outputs): >>> for b_bob in range(num_bob_outputs): >>> for x_alice in range(num_alice_inputs): >>> for y_bob in range(num_bob_inputs): >>> if np.mod(a_alice + b_bob + x_alice * y_bob, dim) == 0: >>> pred_mat[a_alice, b_bob, x_alice, y_bob] = 1 >>> >>> chsh = NonlocalGame(prob_mat, pred_mat) >>> chsh.quantum_value_lower_bound() 0.8535533840915605 References ========== .. [LD07] Liang, Yeong-Cherng, and Andrew C. Doherty. "Bounds on quantum correlations in Bell-inequality experiments." Physical Review A 75.4 (2007): 042103. https://arxiv.org/abs/quant-ph/0608128 :param iters: The number of times to run the alternating projection algorithm. :param tol: The tolerance before quitting out of the alternating projection semidefinite program. :return: The lower bound on the quantum value of a nonlocal game. """ # Get number of inputs and outputs. _, num_outputs_bob, _, num_inputs_bob = self.pred_mat.shape best_lower_bound = float("-inf") for _ in range(iters): # Generate a set of random POVMs for Bob. These measurements serve # as a rough starting point for the alternating projection # algorithm. bob_tmp = random_povm(num_outputs_bob, num_inputs_bob, num_outputs_bob) bob_povms = defaultdict(int) for y_ques in range(num_inputs_bob): for b_ans in range(num_outputs_bob): bob_povms[y_ques, b_ans] = bob_tmp[:, :, y_ques, b_ans] # Run the alternating projection algorithm between the two SDPs. it_diff = 1 prev_win = -1 best = float("-inf") while it_diff > tol: # Optimize over Alice's measurement operators while fixing # Bob's. If this is the first iteration, then the previously # randomly generated operators in the outer loop are Bob's. # Otherwise, Bob's operators come from running the next SDP. alice_povms, lower_bound = self.__optimize_alice(bob_povms) bob_povms, lower_bound = self.__optimize_bob(alice_povms) it_diff = lower_bound - prev_win prev_win = lower_bound # As the SDPs keep alternating, check if the winning probability # becomes any higher. If so, replace with new best. if best < lower_bound: best = lower_bound if best_lower_bound < best: best_lower_bound = best return best_lower_bound