From cbf9100fc21e4eb772ee5b2e6d9e1ec96a926a40 Mon Sep 17 00:00:00 2001 From: Alex Pozas Date: Thu, 18 Apr 2019 16:13:59 +0200 Subject: [PATCH] Initial commit --- Compatibility_with_bipartite_models.ipynb | 652 ++++++++++++++++++++++ README.md | 9 + scalar_extension_tools.py | 166 ++++++ tripartite_line.png | Bin 0 -> 35620 bytes 4 files changed, 827 insertions(+) create mode 100644 Compatibility_with_bipartite_models.ipynb create mode 100644 README.md create mode 100644 scalar_extension_tools.py create mode 100644 tripartite_line.png diff --git a/Compatibility_with_bipartite_models.ipynb b/Compatibility_with_bipartite_models.ipynb new file mode 100644 index 0000000..d9fb7e1 --- /dev/null +++ b/Compatibility_with_bipartite_models.ipynb @@ -0,0 +1,652 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Computational appendix of [arXiv:](www.arxiv.org/abs/).\n", + "---\n", + "In this appendix we describe with explicit formulas the *scalar extension* method presented in [arXiv:](www.arxiv.org/abs/) to impose relaxations of (non-convex) factorization constraints in semidefinite programs, and show how this method can be used to study correlations in complex causal networks.\n", + "\n", + "authors: Alejandro Pozas-Kerstjens\n", + "\n", + "requires: [ncpol2sdpa](https://ncpol2sdpa.readthedocs.io/en/stable/), numpy, [picos](https://picos-api.gitlab.io/picos/) <= 1.1.3.post8, scipy, time\n", + "\n", + "last update: Apr, 2019\n", + "\n", + "Description of the method\n", + "---\n", + "Scalar extension is a method designed to deliver a hierarchy which, by means of semidefinite programming, allows to detect distributions that are not realizable in complex quantum networks. Essentially, the method consists in extending the generating set of monomials $\\mathcal{S}$ for a given moment matrix with additional monomials of the form $S_i\\langle S_j\\rangle,\\,S_i\\langle S_j\\rangle\\langle S_k\\rangle\\dots$ (throughout this notebook, the bracket and trace notation of expectation values will be used interchangeably). This is, we complement the generating set of monomials with another set, whose elements are products of operators multiplied by (possibly unknown) expectation values of other products of operators.\n", + "\n", + "This is particularly useful to test correlations in networks where some variables are independent of each other. An example of such is the tripartite-line scenario, depicted below\n", + "\n", + "\n", + "\n", + "A probability distribution $p(abc|xyz)$ is said to have a quantum realization in this scenario if there exists sets of projectors $\\{\\Pi_a^x\\}$, $\\{\\Pi_b^y\\}$ and $\\{\\Pi_c^z\\}$ (acting on $\\mathcal{H}_A$, $\\mathcal{H}_B=\\mathcal{H}_{B_1}\\otimes\\mathcal{H}_{B_2}$ and $\\mathcal{H}_C$, respectively), and a quantum state of the form $\\rho=\\rho_{AB_1}\\otimes\\rho_{B_2C}$ such that $p(abc|xyz)=\\text{Tr}(\\Pi_a^x\\otimes\\Pi_b^y\\otimes\\Pi_c^z\\rho)$. Moreover, from the NPA hierarchy it is known that if such a quantum realization exists, then for any set $\\mathcal{S}$ of products of projectors the matrix given by $\\Gamma_{ij}=\\text{Tr}(S_i^\\dagger S_j \\rho)$ is positive-semidefinite.\n", + "\n", + "However, a moment matrix generated from a distribution compatible with the tripartite-line scenario satisfies additional properties that matrices compatible with quantum realizations in other causal structures would not. Namely, if $S_i$ and $S_j$ only contain projectors of $A$ and $C$, the element in $\\Gamma_{ij}$ can be written as the product of two other elements in the matrix. This is, if $S_i^\\dagger S_j= S^A S^C$, where $S^A$ (resp. $S^C$) is a sequence of only projectors of $A$ (resp. $C$), then the moment matrix satisfies $\\Gamma_{ij}=\\Gamma_{a_1,a_2}\\Gamma_{c_1,c_2}$, where $S_{a_1}^\\dagger S_{a_2}=S^A$ and $S_{c_1}^\\dagger S_{c_2}=S^C$.\n", + "\n", + "Therefore, in order to know whether a distribution has a quantum realization in the tripartite-line scenario, we must be able to check whether moment matrices with unknown entries but that satisfy factorization constraints as that explained above can be made positive-semidefinite, this is, we must be able to solve problems of the form\n", + "\n", + "$$\\begin{aligned}\n", + "& \\text{find}\n", + "& & \\text{vars} \\\\\n", + "& \\text{such that}\n", + "& & \\Gamma \\geq 0.\n", + "\\end{aligned}$$\n", + "\n", + "Failing to find a positive-semidefinite completion of one of these moment matrices will be a proof that the distribution does not have a quantum realization in the scenario. Nevertheless, factorization constraints are non-linear and furthermore non-convex, so they cannot be imposed in semidefinite programs. Scalar extension overcomes this issue by imposing linear constraints in larger moment matrices, that implement relaxations of the factorizations.\n", + "\n", + "Let us demonstrate the logic behind the method through an example, where we build a moment matrix step by step: assume we are given a binary probability distribution $p(abc|xyz)$ where $a,b,c,x,y,z\\in\\{0,1\\}$ and we want to test whether it has a quantum realization in the tripartite-line scenario. We will build a $4\\times 4$ moment matrix that, in principle, could allow us to answer the question in the negative: if such a matrix cannot be made positive-semidefinite, then the distribution does not have a quantum realization. For simplicity, we will assume that the entries in the matrix are real.\n", + "\n", + "Let us begin with an arbitrary, $4\\times 4$ symmetric matrix\n", + "$$\n", + "\\Gamma = \\begin{pmatrix}\n", + "v_1 & v_2 & v_3 & v_4 \\\\\n", + " & v_5 & v_6 & v_7 \\\\\n", + " & & v_8 & v_9 \\\\\n", + " & & & v_{10}\n", + "\\end{pmatrix}\n", + "$$\n", + "\n", + "The first step proceeds as in the standard NPA hierarchy: we assume that a quantum realization exists and with it the set of projectors $\\{\\Pi_a^x\\}\\cup\\{\\Pi_b^y\\}\\cup\\{\\Pi_c^z\\}$. With it, we define a set of generating moments. In our case, let us choose\n", + "\n", + "$$\\mathcal{S}=\\{\\mathbb{1},\\Pi_{a=0}^{x=0},\\Pi_{a=0}^{x=0}\\Pi_{a=0}^{x=1},\\Pi_{c=0}^{z=0}\\Pi_{c=0}^{z=1}\\},$$\n", + "\n", + "and try to fill $\\Gamma$ with it according to $\\Gamma_{ij}=\\text{Tr}(S_i^\\dagger S_j \\rho)$. This allows us to reduce the number of variables in the problem. Since projectors are Hermitian and idempotent (so $\\Pi^\\dagger\\Pi=\\Pi^2=\\Pi\\,\\forall\\Pi$) we have that $v_2=\\text{Tr}(\\Pi_{a=0}^{x=0}\\rho)=\\text{Tr}({\\Pi_{a=0}^{x=0}}^\\dagger\\Pi_{a=0}^{x=0}\\rho)=v_5$. Proceeding analogously we also obtain $v_3=v_6$. We can also identify some of the elements of the matrix with elements of the probability distribution. Indeed, we have that $v_1=\\text{Tr}(\\rho)=1$ (which is true for any quantum state $\\rho$) and $v_2=\\text{Tr}(\\Pi_{a=0}^{x=0}\\rho)=p_a(0|0)$, where $p_A(a|x)$ is the marginalization of $p(abc|xyz)$ over the outcomes of parties $B$ and $C$. After all these substitutions, $\\Gamma$ has the form\n", + "$$\n", + "\\Gamma = \\begin{pmatrix}\n", + "1 & p_A(0|0) & v_3 & v_4 \\\\\n", + " & p_A(0|0) & v_3 & v_7 \\\\\n", + " & & v_8 & v_9 \\\\\n", + " & & & v_{10}\n", + "\\end{pmatrix}\n", + "$$\n", + "If the probability distribution was compatible with the tripartite-line scenario, expectation values of operator strings containing only projectors of $A$ and $C$ would factorize. This generates two additional constraints, namely\n", + "\n", + "$$\n", + "\\begin{align}\n", + "v_7 &= \\text{Tr}(\\Pi_{a=0}^{x=0}\\Pi_{c=0}^{z=0}\\Pi_{c=0}^{z=1}\\rho)=\\text{Tr}(\\Pi_{a=0}^{x=0}\\rho_{AB_1})\\text{Tr}(\\Pi_{c=0}^{z=0}\\Pi_{c=0}^{z=1}\\rho_{B_2C})=p_A(0|0)v_4,\\\\\n", + "v_9 &= \\text{Tr}({\\Pi_{a=0}^{x=1}}^\\dagger{\\Pi_{a=0}^{x=0}}^\\dagger\\Pi_{c=0}^{z=0}\\Pi_{c=0}^{z=1}\\rho)=\\text{Tr}({\\Pi_{a=0}^{x=1}}^\\dagger{\\Pi_{a=0}^{x=0}}^\\dagger\\rho_{AB_1})\\text{Tr}(\\Pi_{c=0}^{z=0}\\Pi_{c=0}^{z=1}\\rho_{B_2C})=v_3 v_4.\n", + "\\end{align}\n", + "$$\n", + "\n", + "The first constraint can be readily imposed since it is a linear relation between $v_7$ and $v_4$ (recall that $p_A(0|0)$ is a known real number). Note that this is a nonlinear constraint, but it turns out that it can be imposed as a linear relation between unknown variables given a specific probability distribution. Therefore, this constraint can only be be imposed when aiming to certify if a correlation is compatible or not, and never for optimizing Bell inequalities over the set of compatible correlations.\n", + "\n", + "The second constraint involves products of two unknown variables, and therefore it can never be imposed in semidefinite programming. In order to impose a relaxation of such constraint, we perform the *scalar extension*. In particular, let us extend the moment matrix with just one new column (and the corresponding row), so the new moment matrix is\n", + "\n", + "$$\n", + "\\tilde{\\Gamma} = \\begin{pmatrix}\n", + "1 & p_A(0|0) & v_3 & v_4 & v_{11}\\\\\n", + " & p_A(0|0) & v_3 & p_A(0|0)v_4 & v_{12} \\\\\n", + " & & v_8 & v_9 & v_{13} \\\\\n", + " & & & v_{10} & v_{14} \\\\\n", + " & & & & v_{15}\n", + "\\end{pmatrix}.\n", + "$$\n", + "\n", + "We choose to associate such a new column with the operator $S_5=\\Pi_{a=0}^{x=1}\\left\\langle \\Pi_{c=0}^{z=1}\\Pi_{c=0}^{z=0}\\right\\rangle$, which is the projector $\\Pi_{a=0}^{x=1}$ multiplied by the scalar factor $\\left\\langle \\Pi_{c=0}^{z=1}\\Pi_{c=0}^{z=0}\\right\\rangle$, which cannot be computed from the probability distribution, and therefore will remain as a variable to be determined in our problem. Using as extended set of generating moments $\\tilde{\\mathcal{S}}=\\mathcal{S}\\cup\\{S_5\\}$, some new relations can be imposed in $\\tilde{\\Gamma}$, namely $v_{11}=p_a(0|1)v_4$ and $v_{14}=v_{15}$, obtaining\n", + "\n", + "$$\n", + "\\tilde{\\Gamma} = \\begin{pmatrix}\n", + "1 & p_A(0|0) & v_3 & v_4 & p_A(0|1)v_4\\\\\n", + " & p_A(0|0) & v_3 & p_A(0|0)v_4 & v_{12} \\\\\n", + " & & v_8 & v_9 & v_{13} \\\\\n", + " & & & v_{10} & v_{14} \\\\\n", + " & & & & v_{14}\n", + "\\end{pmatrix}.\n", + "$$\n", + "\n", + "Now, at last, the factorization condition translates to the linear constraint $v_9=v_{12}$. Therefore, in order to know whether the probability distribution $p(abc|xyz)$ has a quantum realization in the tripartite-line scenario, one can solve the problem\n", + "\n", + "\n", + "$$\\begin{aligned}\n", + "& \\text{find}\n", + "& & v_3, v_4, v_8, v_9, v_{10}, v_{13}, v_{14} \\\\\n", + "& \\text{such that}\n", + "& & \\begin{pmatrix}\n", + "1 & p_A(0|0) & v_3 & v_4 & p_A(0|1)v_4\\\\\n", + " & p_A(0|0) & v_3 & p_A(0|0)v_4 & v_9 \\\\\n", + " & & v_8 & v_9 & v_{13} \\\\\n", + " & & & v_{10} & v_{14} \\\\\n", + " & & & & v_{14}\n", + "\\end{pmatrix} \\geq 0.\n", + "\\end{aligned}$$\n", + "\n", + "This problem can be cast as a semidefinite program which, upon failing of finding a variable assignment that satisfied the constraints, would identify $p(abc|xyz)$ as not realizable. However, on the other hand success on finding such a variable assignment is not a proof of the distribution having a quantum realization, as in the standard NPA hierarchy.\n", + "\n", + "Application: discarding bi-quantum and bi-local models in the tripartite-line scenario\n", + "---\n", + "Now, we proceed to give an example of use of the method described above, by showing how it rightly identifies probability distributions that do not have realizations in the tripartite-line scenario in two different cases: when the sources distribute quantum states, and when they distribute classical variables. Explicitly, we show that the probability distribution $P^{22}$ in [Phys. Rev. A 85, 032119 (2012)](https://link.aps.org/doi/10.1103/PhysRevA.85.032119), when mixed with white noise giving rise to the noisy distribution $P_v=vP^{22}+(1-v)P_0$, fails to have a quantum realization in the tripartite-line scenario for $v>1/2$, and fails to have a bi-local hidden variable model for $v>1/4$.\n", + "\n", + "For doing so, we perform scalar extension to the moment matrices obtained in the standard application of the NPA hierarchy. However, instead of looking for a variable assignment that makes the moment matrix positive-semidefinite, due to better numerical stability we will solve the equivalent problem of optimizing the smallest eigenvalue of $\\tilde{\\Gamma}$. This is, we will solve problems of the form\n", + "\n", + "$$\\begin{aligned}\n", + "& \\text{maximize}\n", + "& & \\lambda \\\\\n", + "& \\text{such that}\n", + "& & \\tilde{\\Gamma} - \\lambda\\mathbb{1}\\geq 0.\n", + "\\end{aligned}$$\n", + "\n", + "In this problem a positive optimal value of $\\lambda$ indicates that there exists a variable assignment for which $\\tilde{\\Gamma}$ is positive-semidefinite, and a negative optimal value identifies the distribution employed to construct $\\tilde{\\Gamma}$ as not compatible with the scenario under scrutiny. We will show that in the case of non-commuting operators the optimal value of $\\lambda$ is negative whenever $v > 1/2$, and whenever $v > 1/4$ when we additionally impose all operators to commute.\n", + "\n", + "To improve readability of this notebook and ease of use, we placed the supporting functions to a separate file; please download it in the same folder as the notebook if you would like to evaluate it. The following dependencies must also be available: at least one SDP solver ([SDPA](http://sdpa.sourceforge.net/) as an executable in the path or [Mosek](https://mosek.com/) with its Python interface installed; cvxopt as a solver is not recommended) together with the [Ncpol2sdpa](http://pypi.python.org/pypi/ncpol2sdpa) package.\n", + "\n", + "First, we import everything we will need:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from scalar_extension_tools import fix_moments, get_factorization_constraints, get_moments_extracols\n", + "from ncpol2sdpa import flatten, generate_variables, generate_operators, \\\n", + " projective_measurement_constraints, SdpRelaxation\n", + "from numpy import eye\n", + "from time import time" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the sake of simplicity, we define functions that generate sets of commuting and noncommuting variables (taken from [this example](https://github.com/FlavioBaccari/Hierarchy-for-nonlocality-detection)), a function that, given a probability distribution and a set of measurements, generates all computable quantities inside the moment matrix, and another function that will transform the feasibility problem into an optimization problem." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def generate_commuting_measurements(party, label):\n", + " \"\"\"Generates the list of symbolic variables representing the measurements\n", + " for a given party. The variables are treated as commuting.\n", + "\n", + " :param party: configuration indicating the configuration of number m\n", + " of measurements and outcomes d for each measurement. It is a\n", + " list with m integers, each of them representing the number of\n", + " outcomes of the corresponding measurement.\n", + " :type party: list of int\n", + " :param label: label to represent the given party\n", + " :type label: str\n", + "\n", + " :returns: list of sympy.core.symbol.Symbol\n", + " \"\"\"\n", + " measurements = []\n", + " for i, p in enumerate(party):\n", + " measurements.append(generate_variables(label + '_%s' % i, p - 1,\n", + " hermitian=True))\n", + " return measurements\n", + "\n", + "def generate_noncommuting_measurements(party, label):\n", + " \"\"\"Generates the list of symbolic variables representing the measurements\n", + " for a given party. The variables are treated as noncommuting.\n", + "\n", + " :param party: configuration indicating the configuration of number m\n", + " of measurements and outcomes d for each measurement. It is a\n", + " list with m integers, each of them representing the number of\n", + " outcomes of the corresponding measurement.\n", + " :type party: list of int\n", + " :param label: label to represent the given party\n", + " :type label: str\n", + "\n", + " :returns: list of sympy.core.symbol.Symbol\n", + " \"\"\"\n", + " measurements = []\n", + " for i, p in enumerate(party):\n", + " measurements.append(generate_operators(label + '_%s' % i, p - 1,\n", + " hermitian=True))\n", + " return measurements\n", + "\n", + "def get_moment_constraints(probability, measurements):\n", + " \"\"\"Generates the list of moment equalities substitution for the SDP,\n", + " that is, the values of the correlators for a given probapility\n", + " distribution.\n", + " \n", + " :param probability: probability distribution.\n", + " :type probability: object\n", + " :param measurements: list of variables representing the local\n", + " measurements in the given scenario.\n", + " :type measurements: list of lists of sympy.core.symbol.Symbol\n", + " \n", + " :returns: dict of sympy.core.add.Add\n", + " \"\"\"\n", + " measA, measB, measC = measurements\n", + " moments = {measA[0][0]: probability.p_a(0, 0),\n", + " measA[1][0]: probability.p_a(0, 1),\n", + " measB[0][0]: probability.p_b(0, 0),\n", + " measB[1][0]: probability.p_b(0, 1),\n", + " measC[0][0]: probability.p_c(0, 0),\n", + " measC[1][0]: probability.p_c(0, 1),\n", + " measA[0][0] * measB[0][0]: probability.p_ab(0, 0, 0, 0),\n", + " measA[0][0] * measB[1][0]: probability.p_ab(0, 0, 0, 1),\n", + " measA[1][0] * measB[0][0]: probability.p_ab(0, 0, 1, 0),\n", + " measA[0][0] * measB[1][0]: probability.p_ab(0, 0, 1, 1),\n", + " measA[0][0] * measC[0][0]: probability.p_ac(0, 0, 0, 0),\n", + " measA[0][0] * measC[1][0]: probability.p_ac(0, 0, 0, 1),\n", + " measA[1][0] * measC[0][0]: probability.p_ac(0, 0, 1, 0),\n", + " measA[1][0] * measC[1][0]: probability.p_ac(0, 0, 1, 1),\n", + " measB[0][0] * measC[0][0]: probability.p_bc(0, 0, 0, 0),\n", + " measB[0][0] * measC[1][0]: probability.p_bc(0, 0, 0, 1),\n", + " measB[1][0] * measC[0][0]: probability.p_bc(0, 0, 1, 0),\n", + " measB[1][0] * measC[1][0]: probability.p_bc(0, 0, 1, 1),\n", + " measB[0][0] * measC[0][0]: probability.p_bc(0, 0, 0, 0),\n", + " measA[0][0] * measB[0][0] * measC[0][0]: probability.p(0, 0, 0, 0, 0, 0),\n", + " measA[0][0] * measB[0][0] * measC[1][0]: probability.p(0, 0, 0, 0, 0, 1),\n", + " measA[0][0] * measB[1][0] * measC[0][0]: probability.p(0, 0, 0, 0, 1, 0),\n", + " measA[0][0] * measB[1][0] * measC[1][0]: probability.p(0, 0, 0, 0, 1, 1),\n", + " measA[1][0] * measB[0][0] * measC[0][0]: probability.p(0, 0, 0, 1, 0, 0),\n", + " measA[1][0] * measB[0][0] * measC[1][0]: probability.p(0, 0, 0, 1, 0, 1),\n", + " measA[1][0] * measB[1][0] * measC[0][0]: probability.p(0, 0, 0, 1, 1, 0),\n", + " measA[1][0] * measB[1][0] * measC[1][0]: probability.p(0, 0, 0, 1, 1, 1)\n", + " }\n", + " return moments\n", + "\n", + "def add_lambda(problem):\n", + " \"\"\"Transforms the feasibility problem\n", + " find vars\n", + " such that M >= 0\n", + " into the optimization problem\n", + " maximize lambda\n", + " such that M - lambda * I >= 0\n", + " \n", + " :param problem: initial feasibility problem\n", + " :type problem: picos.problem.Problem\n", + " \n", + " :returns: picos.problem.Problem\n", + " \"\"\"\n", + " picos_problem = problem.convert_to_picos()\n", + " X = picos_problem.get_variable('X')\n", + " λ = picos_problem.add_variable('λ')\n", + " picos_problem.set_objective('max', λ)\n", + " constraint = picos_problem.get_constraint(0)\n", + " constraint.Exp1 -= λ * eye(X.size[0])\n", + " return picos_problem" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can focus on the problem at hand. First, we define the noisy version of the probability distribution $P^{22}$, which we will contrast against bi-local and bi-quantum hidden variable models, along with its marginals." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class P22(object):\n", + " def __init__(self, visibility):\n", + " self.v = visibility\n", + "\n", + " # Full distribution\n", + " def p(self, a, b, c, x, y, z):\n", + " return self.v * (1 + (-1) ** (a + b + c + x*y + y*z))/8 + (1 - self.v)/8\n", + "\n", + " # Two-party marginals\n", + " def p_ab(self, a, b, x, y):\n", + " return sum([self.p(a, b, c, x, y, 0) for c in range(2)])\n", + " def p_bc(self, b, c, y, z):\n", + " return sum([self.p(a, b, c, 0, y, z) for a in range(2)])\n", + " def p_ac(self, a, c, x, z):\n", + " return sum([self.p(a, b, c, x, 0, z) for b in range(2)])\n", + "\n", + " # Single-party marginals\n", + " def p_a(self, a, x):\n", + " return sum([self.p_ac(a, c, x, 0) for c in range(2)])\n", + " def p_b(self, b, y):\n", + " return sum([self.p_ab(a, b, 0, y) for a in range(2)])\n", + " def p_c(self, c, z):\n", + " return sum([self.p_ac(a, c, 0, z) for a in range(2)])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we define the parameters relevant to our scenario: the number of measurements and outputs of each of the parties, and the level of the NPA hierarchy we will consider." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "level = 3 # Level of the NPA hierarchy we will use\n", + "oA = [2, 2] # Number of outputs of each of Alice's measurements\n", + "oB = [2, 2] # Number of outputs of each of Bob's measurements\n", + "oC = [2, 2] # Number of outputs of each of Charlie's measurements" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From now on, we treat each of the cases separately.\n", + "\n", + "### Case 1: Non-existence of bi-quantum models for $v>1/2$\n", + "---\n", + "We begin defining the symbolic variables representing the operators, and the constraints they satisfy. In this case, operators representing different measurements of a same party do not commute." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Alice's measurements\n", + "measA = generate_noncommuting_measurements(oA, 'A')\n", + " \n", + "# Bob's measurements\n", + "measB = generate_noncommuting_measurements(oB, 'B')\n", + "\n", + "# Charlie's measurements\n", + "measC = generate_noncommuting_measurements(oC, 'C')\n", + "\n", + "measurements = [measA, measB, measC]\n", + "substitutions = projective_measurement_constraints(measurements)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we fix the visibility and create the noisy probability distribution $P_v$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "v = 1/2 + 1e-5\n", + "p_v = P22(v)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the distribution and the state and measurements are defined, one can begin calculating cells in the moment matrix. This is performed in three steps: first, we generate the computable moments in the $\\Gamma$ (the standard, NPA moment matrix) with ``get_moment_constraints()``" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "moments = get_moment_constraints(p_v, measurements)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Second, given the measurements for the parties that are causally-disconnected, we generate variables for the new columns that will be needed for the extension and the substitution rules for factorizing moments with ``get_factorization_constraints()``. Let us stress that if one wishes to obtain distribution-free constraints (and thus use the dual of the problem solution as a non-linear Bell inequality, for instance), then only the constraints that do not make use of explicit values of the probability distribution must be used." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "causally_factorizing_moments, extra_columns, \\\n", + "extra_column_names = get_factorization_constraints(parties=[measA, measC],\n", + " moments=moments,\n", + " substitutions=substitutions,\n", + " level=level,\n", + " return_column_names=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As described in the main text, we choose the new columns to be indexed by monomials of the form $\\left\\langle S_i \\right\\rangle\\mathbb{1}$, where $S_i$ is in the set" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "extra_column_names" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Third, for the new columns, we generate substitutions for the remaining moments that appear of which one of the factors is known (like $v_7=p_a(0|0) v_4$ in the example of the introduction) with ``get_moments_extracols()``. Again, these constraints should not be added in the case of looking for general certificates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "other_factorizing_moments = get_moments_extracols(moments, extra_columns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before proceeding, we do a bit of post-processing in order to eliminate numerical-precision errors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "moments = {**moments, **causally_factorizing_moments, **other_factorizing_moments}\n", + "moments = fix_moments(moments, 1e-10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can generate the extended moment matrix by complementing the standard NPA moment matrix $\\Gamma$ at the level specified by `level` with the columns represented by `extra_columns`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "time0 = time()\n", + "sdp = SdpRelaxation(flatten(measurements))\n", + "sdp.get_relaxation(level=level, # Initial level of the moment matrix\n", + " extramonomials=extra_columns, # Columns with which will be extended\n", + " substitutions=substitutions, # Idempotency and commutation rules\n", + " momentsubstitutions=moments # Variable substitutions\n", + " )\n", + "print(\"SDP relaxation was generated in \" + str(time()-time0) + \" seconds.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And finally we build solve the optimization problem\n", + "$$\\begin{aligned}\n", + "& \\text{maximize}\n", + "& & \\lambda \\\\\n", + "& \\text{such that}\n", + "& & \\tilde{\\Gamma} - \\lambda\\mathbb{1}\\geq 0.\n", + "\\end{aligned}$$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "problem = add_lambda(sdp)\n", + "problem.solve(solver='mosek', solve_via_dual=False, verbose=1, tol=1e-12)\n", + "print('λ: ' + str(problem.obj_value()))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "By varying the parameter $v$ it can be checked that for $v>1/2$ (up to numerical precision) the optimal value for the smallest eigenvalue of $\\tilde{\\Gamma}$ is negative, which is a certificate that the generated correlations cannot be explained by the sources sending quantum states and the parties performing measurements on their shares." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Case 2: Non-existence of bi-local models for $v>1/4$\n", + "---\n", + "As a last step, we additionally impose that variables representing different measurements of the same operator commute, and show that in this case no positive-semidefinite completion of the extended moment matrix can be found for $v>1/4$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Alice's measurements\n", + "measA = generate_commuting_measurements(oA, 'A')\n", + "subsA = projective_measurement_constraints(measA)\n", + "\n", + "# Bob's measurements\n", + "measB = generate_commuting_measurements(oB, 'B')\n", + "subsB = projective_measurement_constraints(measB)\n", + "\n", + "# Charlie's measurements\n", + "measC = generate_commuting_measurements(oC, 'C')\n", + "subsC = projective_measurement_constraints(measC)\n", + "\n", + "measurements = [measA, measB, measC]\n", + "substitutions = {**subsA, **subsB, **subsC}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "p_v.v = 1/4 + 1e-5 # We set the new visibility here\n", + "moments = get_moment_constraints(p_v, measurements)\n", + "causally_factorizing_moments, extra_columns, \\\n", + "extra_column_names = get_factorization_constraints(parties=[measA, measC],\n", + " moments=moments,\n", + " substitutions=substitutions,\n", + " level=level,\n", + " return_column_names=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case, the set of extra generating monomials is again $\\{\\left\\langle S_i \\right\\rangle\\mathbb{1}\\}_i$, where $S_i$ is in" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "extra_column_names" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us continue with the calculations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "time0 = time()\n", + "other_factorizing_moments = get_moments_extracols(moments, extra_columns)\n", + "\n", + "moments = {**moments, **causally_factorizing_moments, **other_factorizing_moments}\n", + "moments = fix_moments(moments, 1e-10)\n", + "print(\"Constraints were generated in \" + str(time()-time0) + \" seconds.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "time0 = time()\n", + "sdp = SdpRelaxation(flatten(measurements))\n", + "sdp.get_relaxation(level=level, extramonomials=extra_columns, substitutions=substitutions, momentsubstitutions=moments)\n", + "print(\"SDP relaxation was generated in \" + str(time()-time0) + \" seconds.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "probl = add_lambda(sdp)\n", + "probl.solve(solver='mosek', solve_via_dual=False, verbose=1, tol=1e-12)\n", + "print('λ: ' + str(probl.obj_value()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Indeed, the smallest eigenvalue of $\\tilde{\\Gamma}$, is negative for $v > 1/4$, which certifies that such distributions cannot be explained with bi-local hidden variable models." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..33fc61f --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +[![DOI](https://zenodo.org/badge/.svg)](https://zenodo.org/badge/latestdoi/) + +## Computational appendix of *[Bounding the sets of classical and quantum correlations in networks](https://www.arxiv.org/abs/1904......)* + +This is a repository containing the computational appendix of the article "*Bounding the sets of classical and quantum correlations in networks*. Alejandro Pozas-Kerstjens, Rafael Rabelo, Lukasz Rudnicki, Rafael Chaves, Daniel Cavalcanti, Miguel Navascués, and Antonio Acín. [arXiv:1904......](https://www.arxiv.org/abs/1904......)." It provides tools for performing scalar extension of moment matrices in order to develop SDP hierarchies (in the spirit of the Navascués-Pironio-Acín hierarchy) that bound the set of correlations compatible with quantum causal networks with causally-independent parties. + +All code is written both in Python. It requires [Ncpol2sdpa](https://ncpol2sdpa.readthedocs.io/en/stable/), NumPy, [PICOS](https://picos-api.gitlab.io/picos/) <= 1.1.3.post8, and SciPy. + +The file `scalar_extension_tools.py` contains the functions related to generating the extension and the corresponding constraints in the SDP, and a notebook is provided to show some examples. diff --git a/scalar_extension_tools.py b/scalar_extension_tools.py new file mode 100644 index 0000000..b314ef2 --- /dev/null +++ b/scalar_extension_tools.py @@ -0,0 +1,166 @@ +################################################################################ +#---------------Functions for scalar extension of moment matrices--------------# +################################################################################ +# Alejandro Pozas-Kerstjens, 2019 + +from __future__ import print_function, division +from ncpol2sdpa import generate_variables, flatten +from ncpol2sdpa.nc_utils import get_all_monomials +from numpy import prod, iscomplex, isscalar +from sympy import Symbol, S +from sympy.physics.quantum.operator import HermitianOperator + +def fix_moments(moments, tolerance): + '''Removes residual imaginary parts and moments that evaluate to zero but + are written as some residual floating-point number. + + :param moments: correlators of some obervables + :type moments: dict + :param tolerance: maximum value which will be regarded as numerical noise + :type tol: float + + :returns: dict of fixed moments + ''' + assert tolerance > 0, 'The tolerance should be positive' + for moment, item in moments.items(): + # Check and fix residual complex noises + if iscomplex(item): + if abs(item.imag) > tolerance: + raise Exception('Your moment ' + moment + + ' has a complex expectation value') + moments[moment] = item.real + item = item.real + # Check and fix residual real noises + if isscalar(item): + if abs(item) < tolerance: + moments[moment] = 0 + else: + if len(item.args) > 1: + if ((item.args[0].is_constant()) + and (abs(item.args[0]) < tolerance)): + moments[moment] = 0 + return moments + +def get_factorization_constraints(parties, moments, substitutions, level, + all_parties=False, return_column_names=False): + '''Creates all the constraints in moments related to n-locality, namely + the factorizations = ..., where P_i, P_j, ... are + collections of operators of spacelike-separated parties i, j... + + :param parties: list of measurements for each of the parties spacelike + separated. The structure is [party1, party2...], where + party_i are the measurements of party i, arranged in + the structure [meas1, meas2...], where meas_i is a + list containing the symbols of the operators of + measurement i. + :type parties: list of lists of lists of sympy.core.Symbol + :param moments: known moments obtained with get_moment_constraints. + :type moments: dict + :param substitutions: Measurement constraints (commuting, projective...) + for the operators involved. Required by + get_all_monomials. + :type substitutions: dict + :param level: level of the moment matrix + :type level: int + :param all_parties: Optional flag for specifying whether the columns for all + parties should be created instead of a minimal set. + :type all_parties: bool + :param return_column_names: Optional flag to return the moments to which + the extra columns correspond + :type return_column_names: bool + + :returns momentsbilocal: dict with = ... constraints. + :returns extracolumns: list of sympy.core.Symbol that correspond to the + extra monomials created. + :returns columnsnames: list of original monomials corresponding to the + names of the extra monomials created. + ''' + # Factorizations will at most be of size 1|2*level-1 + parties_moments = [get_all_monomials(flatten(party), None, + substitutions, 2 * level - 1)[1:] + for party in parties] + # Strictly speaking, we need to build extra columns of all except one party + # to sucessfully implement all factorization constraints. + if not all_parties: + parties_moments = parties_moments[:-1] + + # Generate commuting symbols for all the additional columns + parties_columns = [generate_variables( + str(party_moments[0])[0].split('_')[0].lower() + '_', + len(party_moments)) + for party_moments in parties_moments] + # Substitute symbols whose values are known + parties_columns = [[moments.get( + parties_moments[i][parties_columns[i].index(element)], + element) + for element in party] for i, party in enumerate(parties_columns)] + # Obtain actual additional columns + extracolumns = [extra for extra in flatten(parties_columns) + if isinstance(extra, Symbol)] + columnsnames = [symbol for i, symbol in enumerate(flatten(parties_moments)) + if flatten(parties_columns)[i] in extracolumns] + + # Add identities for later computations + partiesplus1 = [party_moments + [S.One] + for party_moments in parties_moments] + extramomentsplus1 = [extracols + [1] for extracols in parties_columns] + + momentsbilocal = {} + for monomial in get_all_monomials(flatten(parties), None, + substitutions, 2 * level)[1:]: + monomial = monomial.as_ordered_factors() + party_monomials = [[element for element in monomial + if element in flatten(party)] for party in parties] + factors = [prod(party) for party in party_monomials] + if len(monomial) <= level: + for z in flatten([extracolumns, 1]): + key = prod([factor for factor in [z] + factors if factor != 1]) + if all_parties: + item = prod([z] + + [extramomentsplus1[i][partiesplus1[i].index(factors[i])] + for i in range(len(factors))] + ) + else: + item = prod([z] + + [extramomentsplus1[i][partiesplus1[i].index(factors[i])] + for i in range(len(factors) - 1)] + + [moments.get(factors[-1], factors[-1])] + ) + if key != item: + momentsbilocal[key] = item + else: + if prod([len(party_monomial) < 2 * level + for party_monomial in party_monomials]): + key = prod([factor for factor in factors if factor != 1]) + if all_parties: + item = prod( + [extramomentsplus1[i][partiesplus1[i].index(factors[i])] + for i in range(len(factors))]) + else: + item = prod( + [extramomentsplus1[i][partiesplus1[i].index(factors[i])] + for i in range(len(factors) - 1)] + + [moments.get(factors[-1], factors[-1])] + ) + if key != item: + momentsbilocal[key] = item + if return_column_names: + return momentsbilocal, extracolumns, columnsnames + return momentsbilocal, extracolumns + +def get_moments_extracols(known_moments, extracolumns): + '''Creates the entries in the moments dictionary that correspond to known + correlators times some extra moment in the matrix columns, replacing the + correlator with its numerical value + + :param known_moments: known values of the correlators + :type known_moments: dict + :param newcolumns: labels of the additional columns (additional moments) + in the moment matrix. + :type newcolumns: dict of sympy.core.symbol.Symbol + ''' + moments_extra = {} + for key, val in known_moments.items(): + for extra_col in extracolumns: + moments_extra[key * extra_col] = val * extra_col + return moments_extra diff --git a/tripartite_line.png b/tripartite_line.png new file mode 100644 index 0000000000000000000000000000000000000000..861559b0e4fde522b6e58a988014ead27ea667cc GIT binary patch literal 35620 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 P&~@@pRb)z~4B!7B*=^g5 literal 0 HcmV?d00001