<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on Xavier Valcarce</title>
        <link>/posts/</link>
        <description>Recent content in Posts on Xavier Valcarce</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <copyright>&lt;a href=&#34;https://creativecommons.org/licenses/by-nc/4.0/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CC BY-NC 4.0&lt;/a&gt;</copyright>
        <lastBuildDate>Sun, 22 May 2022 00:00:00 +0000</lastBuildDate>
        <atom:link href="/posts/index.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>Quantum bound on the CHSH inequality: NPA in Julia with NCTSSOS</title>
            <link>/posts/npa_julia/</link>
            <pubDate>Sun, 22 May 2022 00:00:00 +0000</pubDate>
            
            <guid>/posts/npa_julia/</guid>
            <description>The CHSH inequality is used to grasp the non-local nature of bipartite games in which each party perform one out of two dichotomic measurements on a shared state. The Tsilerson bound of the CHSH inequality is the maximum violation of this inequality under the best quantum strategy [1]. I.e. the highest CHSH score that can be obtained over all quantum states and measurements.
Finding the best CHSH score can be seen as an optimization of a polynomial of non-commutative variables.</description>
            <content type="html"><![CDATA[<p>The CHSH inequality is used to grasp the non-local nature of bipartite games in which each party perform one out of two dichotomic measurements on a shared state.
The Tsilerson bound of the CHSH inequality is the maximum violation of this inequality under the best quantum strategy [1].
I.e. the highest CHSH score that can be obtained over all quantum states and measurements.</p>
<p>Finding the best CHSH score can be seen as an optimization of a polynomial of non-commutative variables. Such optimization can be relaxed to a hierarchy of SDP [2], known as a NPA hierarchy [3]. We here use the Juia package <code>NCTSSOS</code> to perform such a relaxation. More on that package can be found here [4].</p>
<p>The optimization problem is</p>
<p>\[\begin{align}
\max_{E,\rho} \quad &amp; \sum_{i,j=0}^1 (-1)^{ij} Tr[E_i E_j \rho] \\
\text{s.t.} \quad &amp; Tr[\rho] = 1 \\
&amp; E_i^\dagger = E_i \\
&amp; E_i E_j = \delta_{ij} E_i, \quad E_i,E_j \in M_k, \forall M_k \\
&amp; \sum_i E_i = 1 \\
&amp; [E_i,E_j] = 0, \quad E_i\in [M_1,M_2],\quad E_j\in [M_3,M_4]
\end{align}
\]</p>
<p>We start by defining 8 non-commutative variables (2 projectors per measurement) using the <code>DynamicPolynomials</code> package</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span><span style="color:#ff79c6">using</span> DynamicPolynomials
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>@ncpolyvar A1[<span style="color:#bd93f9">1</span><span style="color:#ff79c6">:</span><span style="color:#bd93f9">2</span>] A2[<span style="color:#bd93f9">1</span><span style="color:#ff79c6">:</span><span style="color:#bd93f9">2</span>] B1[<span style="color:#bd93f9">1</span><span style="color:#ff79c6">:</span><span style="color:#bd93f9">2</span>] B2[<span style="color:#bd93f9">1</span><span style="color:#ff79c6">:</span><span style="color:#bd93f9">2</span>]
</span></span><span style="display:flex;"><span>A <span style="color:#ff79c6">=</span> [A1,A2]
</span></span><span style="display:flex;"><span>B <span style="color:#ff79c6">=</span> [B1,B2]
</span></span></code></pre></div><p>We then define a function returning all the relevant constraints on the projectors composing the measurements</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span><span style="color:#ff79c6">function</span> constraints_projectors(A,B)
</span></span><span style="display:flex;"><span>	cons <span style="color:#ff79c6">=</span> <span style="color:#8be9fd">Vector</span>{<span style="color:#8be9fd">Polynomial</span>{<span style="color:#8be9fd">false</span>,<span style="color:#8be9fd">Float64</span>}}() <span style="color:#6272a4">#empty vector of polynomials</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">for</span> M <span style="color:#ff79c6">in</span> [A,B]
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">for</span> m <span style="color:#ff79c6">in</span> M
</span></span><span style="display:flex;"><span>			append!(cons,[m[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">*</span>m[<span style="color:#bd93f9">2</span>]]) <span style="color:#6272a4"># orthogonality</span>
</span></span><span style="display:flex;"><span>			<span style="color:#ff79c6">for</span> e <span style="color:#ff79c6">in</span> m
</span></span><span style="display:flex;"><span>				append!(cons,[e<span style="color:#ff79c6">^</span><span style="color:#bd93f9">2</span><span style="color:#ff79c6">-</span>e])
</span></span><span style="display:flex;"><span>			<span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>	<span style="color:#6272a4"># commutativity</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">for</span> a <span style="color:#ff79c6">in</span> A
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">for</span> e <span style="color:#ff79c6">in</span> a
</span></span><span style="display:flex;"><span>			<span style="color:#ff79c6">for</span> b <span style="color:#ff79c6">in</span> B
</span></span><span style="display:flex;"><span>				<span style="color:#ff79c6">for</span> f <span style="color:#ff79c6">in</span> b
</span></span><span style="display:flex;"><span>					append!(cons,[e<span style="color:#ff79c6">*</span>f<span style="color:#ff79c6">-</span>f<span style="color:#ff79c6">*</span>e])
</span></span><span style="display:flex;"><span>				<span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>			<span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">return</span> cons
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>eq <span style="color:#ff79c6">=</span> constraints_projectors(A,B)
</span></span></code></pre></div><p>The objective function is a weighted sum of correlators. They are expressed using expectation value that we define with the function</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span>expect(M_x;outcomes<span style="color:#ff79c6">=</span>[<span style="color:#bd93f9">1</span>,<span style="color:#ff79c6">-</span><span style="color:#bd93f9">1</span>]) <span style="color:#ff79c6">=</span> outcomes[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">*</span>M_x[<span style="color:#bd93f9">1</span>] <span style="color:#ff79c6">+</span> outcomes[<span style="color:#bd93f9">2</span>]<span style="color:#ff79c6">*</span>M_x[<span style="color:#bd93f9">2</span>] 
</span></span><span style="display:flex;"><span>C <span style="color:#ff79c6">=</span> expect<span style="color:#ff79c6">.</span>([A1,A2,B1,B2])
</span></span></code></pre></div><p>Finally we express the objective function as the CHSH score</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span>obj <span style="color:#ff79c6">=</span> <span style="color:#ff79c6">-</span>(C[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">*</span>C[<span style="color:#bd93f9">3</span>] <span style="color:#ff79c6">+</span> C[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">*</span>C[<span style="color:#bd93f9">4</span>] <span style="color:#ff79c6">+</span> C[<span style="color:#bd93f9">2</span>]<span style="color:#ff79c6">*</span>C[<span style="color:#bd93f9">3</span>] <span style="color:#ff79c6">-</span> C[<span style="color:#bd93f9">2</span>]<span style="color:#ff79c6">*</span>C[<span style="color:#bd93f9">4</span>])
</span></span></code></pre></div><p>Note that the minus sign is due to <code>NCTSSOS</code> that will minimize and not maximize the objective function.</p>
<p>Finally, we send everything to <code>NCTSSOS</code> that will construct and solve the problem.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span><span style="color:#ff79c6">using</span> NCTSSOS
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>level <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">1</span> <span style="color:#6272a4">#level of the hierarchy</span>
</span></span><span style="display:flex;"><span>n_eq <span style="color:#ff79c6">=</span> length(eq)
</span></span><span style="display:flex;"><span>pop <span style="color:#ff79c6">=</span> [obj; eq]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>opt, data <span style="color:#ff79c6">=</span> nctssos_first(pop, [A1<span style="color:#ff79c6">...</span>,A2<span style="color:#ff79c6">...</span>,B1<span style="color:#ff79c6">...</span>,B2<span style="color:#ff79c6">...</span>], level, numeq<span style="color:#ff79c6">=</span>n_eq, TS<span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#34;block&#34;</span>);
</span></span></code></pre></div><p>Here is the result for the first level of the hierarchy</p>
<pre tabindex="0"><code>***************************NCTSSOS***************************
NCTSSOS is launching...
Starting to compute the block structure...
------------------------------------------------------
The sizes of PSD blocks:
[9]
[1]
------------------------------------------------------
Obtained the block structure in 0.000528174 seconds. The maximal size of blocks is 9.
There are 45 affine constraints.
Assembling the SDP...
SDP assembling time: 0.000512516 seconds.
Solving the SDP...
Problem
  Name                   :                 
  Objective sense        : max             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 45              
  Cones                  : 0               
  Scalar variables       : 29              
  Matrix variables       : 1               
  Integer variables      : 0               

Optimizer started.
Presolve started.
Linear dependency checker started.
Linear dependency checker terminated.
Eliminator started.
Freed constraints in eliminator : 0
Eliminator terminated.
Eliminator started.
Freed constraints in eliminator : 0
Eliminator terminated.
Eliminator - tries                  : 2                 time                   : 0.00            
Lin. dep.  - tries                  : 1                 time                   : 0.00            
Lin. dep.  - number                 : 0               
Presolve terminated. Time: 0.00    
Problem
  Name                   :                 
  Objective sense        : max             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 45              
  Cones                  : 0               
  Scalar variables       : 29              
  Matrix variables       : 1               
  Integer variables      : 0               

Optimizer  - threads                : 4               
Optimizer  - solved problem         : the primal      
Optimizer  - Constraints            : 45
Optimizer  - Cones                  : 1
Optimizer  - Scalar variables       : 14                conic                  : 14              
Optimizer  - Semi-definite variables: 1                 scalarized             : 45              
Factor     - setup time             : 0.00              dense det. time        : 0.00            
Factor     - ML order time          : 0.00              GP order time          : 0.00            
Factor     - nonzeros before factor : 1035              after factor           : 1035            
Factor     - dense dim.             : 0                 flops                  : 3.98e+04        
ITE PFEAS    DFEAS    GFEAS    PRSTATUS   POBJ              DOBJ              MU       TIME  
0   1.0e+00  1.0e+00  1.0e+00  0.00e+00   0.000000000e+00   0.000000000e+00   1.0e+00  0.00  
1   2.9e-01  2.9e-01  4.1e-01  -6.84e-01  -1.325948088e+00  -2.628521667e+00  2.9e-01  0.00  
2   5.1e-02  5.1e-02  2.0e-02  4.00e-01   -3.126913608e+00  -3.133309605e+00  5.1e-02  0.01  
3   1.6e-03  1.6e-03  1.4e-04  1.25e+00   -2.818018898e+00  -2.821554903e+00  1.6e-03  0.01  
4   2.0e-05  2.0e-05  2.1e-07  9.90e-01   -2.828462112e+00  -2.828524906e+00  2.0e-05  0.01  
5   1.5e-06  1.5e-06  4.3e-09  9.96e-01   -2.828433218e+00  -2.828437977e+00  1.5e-06  0.01  
6   4.8e-08  4.8e-08  2.5e-11  9.99e-01   -2.828427384e+00  -2.828427541e+00  4.8e-08  0.01  
7   4.7e-10  4.7e-10  2.4e-14  1.00e+00   -2.828427128e+00  -2.828427129e+00  4.7e-10  0.01  
Optimizer terminated. Time: 0.01    

SDP solving time: 0.014336663 seconds.
optimum = -2.8284271275550936
</code></pre><p>We observe a maximum score of 2.8284271275550936 corresponding to 2√2, the expected results.</p>
<hr>
<p>[1] Clauser, J. F.; Horne, M. A.; Shimony, A. &amp; Holt, R. A. <a href="https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.23.880">Proposed Experiment to Test Local Hidden-Variable Theories.</a> Physical Review Letters, 1969, 23, 880-884.<br>
[2] Pironio, S.; Navascués, M. &amp; Acín, A. <a href="https://epubs.siam.org/doi/10.1137/090760155">Convergent Relaxations of Polynomial Optimization Problems with Noncommuting Variables.</a> Siam Journal on Optimization, 2010, 20, 2157&ndash;2180.<br>
[3] Navascués, M.; Pironio, S. &amp; Acín, A. <a href="https://iopscience.iop.org/article/10.1088/1367-2630/10/7/073013">A convergent hierarchy of semidefinite programs characterizing the set of quantum correlations.</a> New Journal of Physics, 2008, 10, 073013.<br>
[4] Wang, J. &amp; Magron, V. <a href="https://arxiv.org/abs/2010.06956">Exploiting term sparsity in Noncommutative Polynomial Optimization.</a> Arxiv:2010.06956</p>
]]></content>
        </item>
        
        <item>
            <title>Python - LP/SDP for Quantum Information with PICOS</title>
            <link>/posts/picos_quantuminfo/</link>
            <pubDate>Mon, 13 Dec 2021 00:00:00 +0000</pubDate>
            
            <guid>/posts/picos_quantuminfo/</guid>
            <description>SDP interface and Solver PICOS is the Python interface I recommend to write/solve LP/SDP problem. It is under the GPLv3 free-license, probably supports your favorite solver, has crucial features for quantum information and, most importantly, has an attentive and friendly developer community.
Regarding SDP solvers, I had best performance with MOSEK. Sadly, this solver is proprietary (if price is of your concern, MOSEK offers a free one-year license for students). CVXOPT is a relatively good free-licensed alternative to MOSEK.</description>
            <content type="html"><![CDATA[<h2 id="sdp-interface-and-solver">SDP interface and Solver</h2>
<p><a href="https://gitlab.com/picos-api/picos">PICOS</a> is the Python interface I recommend to write/solve LP/SDP problem. It is under the GPLv3 free-license, probably supports your favorite solver, has crucial features for quantum information and, most importantly, has an attentive and friendly developer community.</p>
<p>Regarding SDP solvers, I had best performance with <a href="https://www.mosek.com">MOSEK</a>. Sadly, this solver is proprietary (if price is of your concern, MOSEK offers a free one-year license for students). <a href="https://cvxopt.org">CVXOPT</a> is a relatively good free-licensed alternative to MOSEK. However, in my experience, CVXOPT might lead to some issues (memory-leakage, unstable with complex SDP), and an important optimization time compare to MOSEK.</p>
<h2 id="lp-local-correlations-a-membership-problem">LP: Local correlations, a membership problem</h2>
<p>For this section we need the following import</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ff79c6">import</span> picos <span style="color:#ff79c6">as</span> pcs
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">import</span> numpy <span style="color:#ff79c6">as</span> np
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">from</span> itertools <span style="color:#ff79c6">import</span> product
</span></span></code></pre></div><p>Consider a scenario where a state is shared between <code>N</code> parties, each having <code>m</code> measurement choices (inputs) with <code>d</code> possible results (outputs). The correlations between the parties admit a local hidden-variable model iff the correlations belong to a <a href="https://valcarce.fr/physics/master_thesis.pdf#section.2.2"><em>local polytope</em></a> [1,2].<br>
To know if correlations of a given scenario are local, it is sufficient to check if these correlations belong, i.e. are &ldquo;inside&rdquo;, the local polytope.</p>
<p>Correlations are in a vector of probability \[p = {p(a_1 \dots a_N|x_1 \dots x_N)}\] for all inputs x_i and output a_i.
The vertices of the local polytope are the deterministic strategies <code>p_d</code>, i.e. <code>p</code> is composed of 0s and 1s.
The local polytope can be written as the set of its vertices <code>L=p_d</code>.<br>
Here a simple function that construct such a set</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ff79c6">def</span> <span style="color:#50fa7b">local_polytope</span>(N,m,d):
</span></span><span style="display:flex;"><span>    <span style="color:#f1fa8c">&#34;&#34;&#34;Local Polytope generation.
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    Generate :math:`d^</span><span style="color:#f1fa8c">{m.N}</span><span style="color:#f1fa8c">` vertices of the Local Polytpe for a system with ``N`` partite, each having ``m`` measurement/input and ``d`` output.
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    Parameters
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    ----------
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    N : int
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        number of partite
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    m : int
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        number of input of one partite
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    d : int
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        number of output of one partite
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    Returns
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    -------
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    vertices : array_like
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        Polytope. Each row is a vertex (corresponding to a deterministic strategy), each column is the :math:`n^</span><span style="color:#f1fa8c">{th}</span><span style="color:#f1fa8c">` element to that vertice
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    D <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>zeros((d<span style="color:#ff79c6">**</span>m,m), dtype<span style="color:#ff79c6">=</span><span style="color:#8be9fd;font-style:italic">int</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">for</span> _ <span style="color:#ff79c6">in</span> <span style="color:#8be9fd;font-style:italic">range</span>(d<span style="color:#ff79c6">**</span>m):
</span></span><span style="display:flex;"><span>        D[_][:] <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>array(np<span style="color:#ff79c6">.</span>unravel_index(_,(d,)<span style="color:#ff79c6">*</span>m))
</span></span><span style="display:flex;"><span>    vertices <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>zeros(((d<span style="color:#ff79c6">**</span>(m<span style="color:#ff79c6">*</span>N),)<span style="color:#ff79c6">+</span>(m,)<span style="color:#ff79c6">*</span>N<span style="color:#ff79c6">+</span>(d,)<span style="color:#ff79c6">*</span>N))
</span></span><span style="display:flex;"><span>    c <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">for</span> _ <span style="color:#ff79c6">in</span> product(<span style="color:#8be9fd;font-style:italic">range</span>(d<span style="color:#ff79c6">**</span>m), repeat<span style="color:#ff79c6">=</span>N):
</span></span><span style="display:flex;"><span>        <span style="color:#ff79c6">for</span> x <span style="color:#ff79c6">in</span> product(<span style="color:#8be9fd;font-style:italic">range</span>(m), repeat<span style="color:#ff79c6">=</span>N):
</span></span><span style="display:flex;"><span>            vertices[(c,)<span style="color:#ff79c6">+</span>x<span style="color:#ff79c6">+</span><span style="color:#8be9fd;font-style:italic">tuple</span>([D[_[i]][x[i]] <span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#8be9fd;font-style:italic">range</span>(N)])]<span style="color:#ff79c6">=</span><span style="color:#bd93f9">1</span>
</span></span><span style="display:flex;"><span>        c <span style="color:#ff79c6">+=</span> <span style="color:#bd93f9">1</span>
</span></span><span style="display:flex;"><span>    shape <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>prod(np<span style="color:#ff79c6">.</span>delete(vertices<span style="color:#ff79c6">.</span>shape[:],<span style="color:#bd93f9">0</span>,<span style="color:#bd93f9">0</span>))
</span></span><span style="display:flex;"><span>    polytope <span style="color:#ff79c6">=</span> vertices<span style="color:#ff79c6">.</span>reshape(vertices<span style="color:#ff79c6">.</span>shape[<span style="color:#bd93f9">0</span>],shape)
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">return</span> polytope
</span></span></code></pre></div><p>A correlation vector <code>p</code> is described by a local model iff <code>p</code> can be written as a convex sum of the local-polytope vertices.
I.e. iff <code>p</code> is inside the local polytope.
This is a linear programming problem: find a vector <code>v</code> such that <code>v*L=p</code>, with <code>sum(v)=1</code> (convexity) and <code>v&gt;0</code> (each element of <code>v</code> positive).
If <code>v</code> exists then <code>p</code> is compatible with a local model.</p>
<p>Using <code>PICOS</code> we write this linear program</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ff79c6">def</span> <span style="color:#50fa7b">is_local</span>(correlation,polytope):
</span></span><span style="display:flex;"><span>	pb <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>Problem() <span style="color:#6272a4"># Create a picos Problem instance</span>
</span></span><span style="display:flex;"><span>	<span style="color:#6272a4"># The two constants of our problem</span>
</span></span><span style="display:flex;"><span>	L <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>Constant(<span style="color:#f1fa8c">&#34;L&#34;</span>, polytope)     <span style="color:#6272a4"># local polytope</span>
</span></span><span style="display:flex;"><span>	p <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>Constant(<span style="color:#f1fa8c">&#34;p&#34;</span>, correlation)  <span style="color:#6272a4"># correlation vector</span>
</span></span><span style="display:flex;"><span>	<span style="color:#6272a4"># The variable v (the coefficient of the convex sum)</span>
</span></span><span style="display:flex;"><span>	dim <span style="color:#ff79c6">=</span> L<span style="color:#ff79c6">.</span>shape[<span style="color:#bd93f9">0</span>]                    <span style="color:#6272a4"># number of vertices</span>
</span></span><span style="display:flex;"><span>	v <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>RealVariable(<span style="color:#f1fa8c">&#34;v&#34;</span>, dim)      <span style="color:#6272a4"># v is a real vector with dim element</span>
</span></span><span style="display:flex;"><span>	<span style="color:#6272a4"># Constraints</span>
</span></span><span style="display:flex;"><span>	pb<span style="color:#ff79c6">.</span>add_constraint(v <span style="color:#ff79c6">&gt;=</span> <span style="color:#bd93f9">0</span>)           <span style="color:#6272a4"># all elements of v are positive</span>
</span></span><span style="display:flex;"><span>	pb<span style="color:#ff79c6">.</span>add_constraint(<span style="color:#8be9fd;font-style:italic">sum</span>(v) <span style="color:#ff79c6">==</span> <span style="color:#bd93f9">1</span>)      <span style="color:#6272a4"># sum of elements of v is 1</span>
</span></span><span style="display:flex;"><span>	pb<span style="color:#ff79c6">.</span>add_constraint(L<span style="color:#ff79c6">.</span>T<span style="color:#ff79c6">*</span>v <span style="color:#ff79c6">==</span> p)       <span style="color:#6272a4"># v is the coefficient of the convex sum of all L vertices</span>
</span></span><span style="display:flex;"><span>	<span style="color:#6272a4"># Objective</span>
</span></span><span style="display:flex;"><span>	pb<span style="color:#ff79c6">.</span>set_objective(<span style="color:#f1fa8c">&#34;min&#34;</span>, <span style="color:#bd93f9">1</span> <span style="color:#ff79c6">|</span> v)      <span style="color:#6272a4"># dummy objective</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#6272a4"># Solving the LP</span>
</span></span><span style="display:flex;"><span>	pb<span style="color:#ff79c6">.</span>solve(solver<span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#34;cvxopt&#34;</span>,primals<span style="color:#ff79c6">=</span><span style="color:#ff79c6">False</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">if</span> pb<span style="color:#ff79c6">.</span>status <span style="color:#ff79c6">==</span> <span style="color:#f1fa8c">&#34;optimal&#34;</span>:
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">return</span> <span style="color:#ff79c6">True</span>                     <span style="color:#6272a4"># if an optimal solution exists, p belongs to L</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">else</span>:
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">return</span> <span style="color:#ff79c6">False</span>                    <span style="color:#6272a4"># otherwise p is non-local</span>
</span></span></code></pre></div><p>To test our LP implementation let&rsquo;s now create a function that returns a local correlation vector <code>p</code>, by construction.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ff79c6">def</span> <span style="color:#50fa7b">local_correlation</span>(polytope):
</span></span><span style="display:flex;"><span>	nb_vertices <span style="color:#ff79c6">=</span> <span style="color:#8be9fd;font-style:italic">len</span>(polytope) <span style="color:#6272a4"># Number of vertices composing the polytope</span>
</span></span><span style="display:flex;"><span>	coeff <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>random<span style="color:#ff79c6">.</span>random(nb_vertices) <span style="color:#6272a4"># Random coefficients, one per vertices</span>
</span></span><span style="display:flex;"><span>	coeff <span style="color:#ff79c6">/=</span> np<span style="color:#ff79c6">.</span>sum(coeff) <span style="color:#6272a4"># Normalised coefficients</span>
</span></span><span style="display:flex;"><span>	p <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>sum([c<span style="color:#ff79c6">*</span>v <span style="color:#ff79c6">for</span> (c,v) <span style="color:#ff79c6">in</span> <span style="color:#8be9fd;font-style:italic">zip</span>(coeff,polytope)],axis<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>) <span style="color:#6272a4"># p is a convex sum of the polytopes vertices</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">return</span> p
</span></span></code></pre></div><p>We verify our implementation with two examples, one local, one non-local</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>L <span style="color:#ff79c6">=</span> local_polytope(<span style="color:#bd93f9">2</span>,<span style="color:#bd93f9">2</span>,<span style="color:#bd93f9">2</span>)
</span></span><span style="display:flex;"><span>p_l <span style="color:#ff79c6">=</span> local_correlation(L)
</span></span><span style="display:flex;"><span>p_nl <span style="color:#ff79c6">=</span> L[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">+</span><span style="color:#bd93f9">1e-3</span>           <span style="color:#6272a4"># A non local correlation -&gt; we take a vertice and we add 0.01 to each of its elements</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">print</span>(is_local(p_l,L))     <span style="color:#6272a4"># Output True</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">print</span>(is_local(p_nl,L))    <span style="color:#6272a4"># Output False</span>
</span></span></code></pre></div><h2 id="complex-sdp-maximize-a-bell-inequality">(Complex) SDP: Maximize a Bell inequality</h2>
<p>For this section, import and constant definition needed</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ff79c6">import</span> numpy <span style="color:#ff79c6">as</span> np
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">import</span> picos <span style="color:#ff79c6">as</span> pcs
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># Paulis</span>
</span></span><span style="display:flex;"><span>Z <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>array([[<span style="color:#bd93f9">1.</span>,<span style="color:#bd93f9">0.</span>],[<span style="color:#bd93f9">0.</span>,<span style="color:#ff79c6">-</span><span style="color:#bd93f9">1.</span>]])
</span></span><span style="display:flex;"><span>X <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>array([[<span style="color:#bd93f9">0.</span>,<span style="color:#bd93f9">1.</span>],[<span style="color:#bd93f9">1.</span>,<span style="color:#bd93f9">0.</span>]])
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># Kroenecker product</span>
</span></span><span style="display:flex;"><span>K <span style="color:#ff79c6">=</span> np<span style="color:#ff79c6">.</span>kron
</span></span></code></pre></div><p>Consider a scenario where Alice and Bob share a two-qubit state <code>rho</code>. They each have two measurements : <code>A0,A1</code> for Alice, <code>B0,B1</code> for Bob.
These measurements are of the form \[M_i = \cos(\theta)\sigma_x + (-1)^i \sin(\theta)\sigma_z\] with <code>i</code> the measurement choice, 0 or 1, and <code>θ</code> the angle between measurement 0 and 1. Alice set <code>θ=a</code> while Bob set <code>θ=b</code>.<br>
A bell operator can be seen as a linear combination of the four correlators <code>AxBy</code>. For example the well-known CHSH operator <code>S=A0(B0+B1)+A1(B0-B1)</code>. Here is a function to generate such operators (return CHSH by default)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ff79c6">def</span> <span style="color:#50fa7b">bell_op</span>(a<span style="color:#ff79c6">=</span>np<span style="color:#ff79c6">.</span>pi<span style="color:#ff79c6">/</span><span style="color:#bd93f9">4</span>,b<span style="color:#ff79c6">=</span>np<span style="color:#ff79c6">.</span>pi<span style="color:#ff79c6">/</span><span style="color:#bd93f9">4</span>,coeff<span style="color:#ff79c6">=</span>[<span style="color:#bd93f9">1</span>,<span style="color:#bd93f9">1</span>,<span style="color:#bd93f9">1</span>,<span style="color:#ff79c6">-</span><span style="color:#bd93f9">1</span>]):
</span></span><span style="display:flex;"><span>    <span style="color:#f1fa8c">&#34;&#34;&#34; Return Bell operator, for specific angle between measurements (for each partite resp.)
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    Parameters
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    ----------
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    a : float
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        Angle between observabe, Alice side.
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    b : float
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        Angle between observabe, Bob side.
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    coeff : array
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        Numpy array of four elements, for A0B0, A1B0, A0B1, A1B1.
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    Return
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    ------
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    bell : ndarray
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        Bell operator
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    O <span style="color:#ff79c6">=</span> <span style="color:#ff79c6">lambda</span> x,a : np<span style="color:#ff79c6">.</span>cos(a)<span style="color:#ff79c6">*</span>X <span style="color:#ff79c6">+</span> (<span style="color:#ff79c6">-</span><span style="color:#bd93f9">1</span>)<span style="color:#ff79c6">**</span>x<span style="color:#ff79c6">*</span>np<span style="color:#ff79c6">.</span>sin(a)<span style="color:#ff79c6">*</span>Z
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">if</span> coeff <span style="color:#ff79c6">==</span> [<span style="color:#bd93f9">1</span>,<span style="color:#bd93f9">1</span>,<span style="color:#bd93f9">1</span>,<span style="color:#ff79c6">-</span><span style="color:#bd93f9">1</span>]:
</span></span><span style="display:flex;"><span>        <span style="color:#6272a4">#CHSH case</span>
</span></span><span style="display:flex;"><span>        bell <span style="color:#ff79c6">=</span> K(O(<span style="color:#bd93f9">0</span>,a),O(<span style="color:#bd93f9">0</span>,b)<span style="color:#ff79c6">+</span>O(<span style="color:#bd93f9">1</span>,b)) <span style="color:#ff79c6">+</span> K(O(<span style="color:#bd93f9">1</span>,a),O(<span style="color:#bd93f9">0</span>,b)<span style="color:#ff79c6">-</span>O(<span style="color:#bd93f9">1</span>,b))
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">else</span>:
</span></span><span style="display:flex;"><span>        bell <span style="color:#ff79c6">=</span> coeff[<span style="color:#bd93f9">0</span>]<span style="color:#ff79c6">*</span>K(O(<span style="color:#bd93f9">0</span>,a),O(<span style="color:#bd93f9">0</span>,b))<span style="color:#ff79c6">+</span>coeff[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">*</span>K(O(<span style="color:#bd93f9">1</span>,a),O(<span style="color:#bd93f9">0</span>,b))<span style="color:#ff79c6">+</span>coeff[<span style="color:#bd93f9">2</span>]<span style="color:#ff79c6">*</span>K(O(<span style="color:#bd93f9">0</span>,a),O(<span style="color:#bd93f9">1</span>,b))<span style="color:#ff79c6">+</span>coeff[<span style="color:#bd93f9">3</span>]<span style="color:#ff79c6">*</span>K(O(<span style="color:#bd93f9">1</span>,a),O(<span style="color:#bd93f9">1</span>,b))
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">return</span> bell
</span></span></code></pre></div><p>The CHSH score achieved by <code>rho</code> is given by the linear operation \[\text{Tr}[S\rho]\]. Since all two-qubits state are semi-positive definite and the CHSH value is linear (in <code>rho</code>) we can use semi-definite programming (SDP) to find the maximum CHSH score a two-qubit state can achieve. Such an SDP reads
\[ \max_\rho \qquad \text{Tr}[S\rho]\]
\[ \text{s.t.} \qquad \rho \succeq 0\]
\[\qquad \quad \text{Tr}[\rho]=1\]
with <code>rho</code> a 4x4 Hermitian matrix.</p>
<p>Using <code>PICOS</code>, we can write this SDP as follow</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ff79c6">def</span> <span style="color:#50fa7b">max_bell</span>(operator):
</span></span><span style="display:flex;"><span>    <span style="color:#f1fa8c">&#34;&#34;&#34; Compute the max(Tr[operator*rho]) over all rho = two-qubits state
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    Parameters
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    ----------
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    operator : np.ndarray
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        Two-qubits operator
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    sdp <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>Problem()
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">#SDP &#34;constant&#34;, the bell operator</span>
</span></span><span style="display:flex;"><span>    bell_operator <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>Constant(operator)
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">#SDP variable (quantum state)</span>
</span></span><span style="display:flex;"><span>    rho <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>HermitianVariable(<span style="color:#f1fa8c">&#39;rho&#39;</span>,<span style="color:#bd93f9">4</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">#Constraints of the SDP :</span>
</span></span><span style="display:flex;"><span>        <span style="color:#6272a4">#semi positive definite</span>
</span></span><span style="display:flex;"><span>    sdp<span style="color:#ff79c6">.</span>add_constraint(rho <span style="color:#ff79c6">&gt;&gt;</span> <span style="color:#bd93f9">0</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#6272a4">#Trace 1</span>
</span></span><span style="display:flex;"><span>    sdp<span style="color:#ff79c6">.</span>add_constraint(pcs<span style="color:#ff79c6">.</span>trace(rho) <span style="color:#ff79c6">==</span> <span style="color:#bd93f9">1</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4"># Objective of the SDP: Tr[Bell*rho]</span>
</span></span><span style="display:flex;"><span>    obj <span style="color:#ff79c6">=</span> pcs<span style="color:#ff79c6">.</span>trace(bell_operator<span style="color:#ff79c6">*</span>rho)<span style="color:#ff79c6">.</span>real
</span></span><span style="display:flex;"><span>    sdp<span style="color:#ff79c6">.</span>set_objective(<span style="color:#f1fa8c">&#39;max&#39;</span>,obj)
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4"># Some print stuff</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">print</span>(<span style="color:#f1fa8c">&#34;Solving: &#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">print</span>(sdp)
</span></span><span style="display:flex;"><span>    sol <span style="color:#ff79c6">=</span> sdp<span style="color:#ff79c6">.</span>solve(solver<span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#39;cvxopt&#39;</span>,verbosity<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">print</span>(<span style="color:#f1fa8c">f</span><span style="color:#f1fa8c">&#34;Solved with </span><span style="color:#f1fa8c">{</span>sol<span style="color:#ff79c6">.</span>claimedStatus<span style="color:#f1fa8c">}</span><span style="color:#f1fa8c"> status&#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">print</span>(<span style="color:#f1fa8c">f</span><span style="color:#f1fa8c">&#34;Optimal violation: </span><span style="color:#f1fa8c">{</span>obj<span style="color:#f1fa8c">}</span><span style="color:#f1fa8c">&#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">print</span>(<span style="color:#f1fa8c">f</span><span style="color:#f1fa8c">&#34;State reaching this violation:</span><span style="color:#f1fa8c">\n</span><span style="color:#f1fa8c">{</span>rho<span style="color:#f1fa8c">}</span><span style="color:#f1fa8c">&#34;</span>)
</span></span></code></pre></div><p>Let&rsquo;s test our implementation</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>S <span style="color:#ff79c6">=</span> bell_op()
</span></span><span style="display:flex;"><span>max_bell(S)
</span></span></code></pre></div><p>Running this output</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>Solving <span style="color:#8be9fd;font-style:italic">max</span>(Tr[CHSH<span style="color:#ff79c6">*</span>rho] over <span style="color:#8be9fd;font-style:italic">all</span> two<span style="color:#ff79c6">-</span>qubit states
</span></span><span style="display:flex;"><span>Solving:
</span></span><span style="display:flex;"><span>Complex Semidefinite Program
</span></span><span style="display:flex;"><span>  maximize Re(tr([<span style="color:#bd93f9">4</span>×<span style="color:#bd93f9">4</span>]·rho))
</span></span><span style="display:flex;"><span>  over
</span></span><span style="display:flex;"><span>    <span style="color:#bd93f9">4</span>×<span style="color:#bd93f9">4</span> hermitian variable rho
</span></span><span style="display:flex;"><span>  subject to
</span></span><span style="display:flex;"><span>    rho ≽ <span style="color:#bd93f9">0</span>
</span></span><span style="display:flex;"><span>    tr(rho) <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">1</span>
</span></span><span style="display:flex;"><span>Solved <span style="color:#ff79c6">with</span> optimal status
</span></span><span style="display:flex;"><span>Optimal violation: <span style="color:#bd93f9">2.8284271145023476</span>
</span></span><span style="display:flex;"><span>State reaching this violation:
</span></span><span style="display:flex;"><span>[ <span style="color:#bd93f9">7.32e-02</span><span style="color:#ff79c6">-</span>j0<span style="color:#bd93f9">.00e+00</span>  <span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">-</span>j1<span style="color:#bd93f9">.85e-17</span>  <span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">+</span>j5<span style="color:#bd93f9">.72e-18</span> <span style="color:#ff79c6">-</span><span style="color:#bd93f9">7.32e-02</span><span style="color:#ff79c6">+</span>j2<span style="color:#bd93f9">.73e-17</span>]
</span></span><span style="display:flex;"><span>[ <span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">+</span>j1<span style="color:#bd93f9">.85e-17</span>  <span style="color:#bd93f9">4.27e-01</span><span style="color:#ff79c6">-</span>j0<span style="color:#bd93f9">.00e+00</span>  <span style="color:#bd93f9">4.27e-01</span><span style="color:#ff79c6">+</span>j5<span style="color:#bd93f9">.60e-17</span> <span style="color:#ff79c6">-</span><span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">+</span>j4<span style="color:#bd93f9">.77e-17</span>]
</span></span><span style="display:flex;"><span>[ <span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">-</span>j5<span style="color:#bd93f9">.72e-18</span>  <span style="color:#bd93f9">4.27e-01</span><span style="color:#ff79c6">-</span>j5<span style="color:#bd93f9">.60e-17</span>  <span style="color:#bd93f9">4.27e-01</span><span style="color:#ff79c6">-</span>j0<span style="color:#bd93f9">.00e+00</span> <span style="color:#ff79c6">-</span><span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">+</span>j7<span style="color:#bd93f9">.19e-17</span>]
</span></span><span style="display:flex;"><span>[<span style="color:#ff79c6">-</span><span style="color:#bd93f9">7.32e-02</span><span style="color:#ff79c6">-</span>j2<span style="color:#bd93f9">.73e-17</span> <span style="color:#ff79c6">-</span><span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">-</span>j4<span style="color:#bd93f9">.77e-17</span> <span style="color:#ff79c6">-</span><span style="color:#bd93f9">1.77e-01</span><span style="color:#ff79c6">-</span>j7<span style="color:#bd93f9">.19e-17</span>  <span style="color:#bd93f9">7.32e-02</span><span style="color:#ff79c6">-</span>j0<span style="color:#bd93f9">.00e+00</span>]
</span></span></code></pre></div><p>We obtain the expected violation of <code>2.8284...</code> which corresponds to 2√2 achieved by Bell states [2].</p>
<h2 id="references">References</h2>
<p>[1] Pironio S., J. Phys. A: Math. theor. 47 (<a href="https://iopscience.iop.org/article/10.1088/1751-8113/47/42/424020">424020</a>)<br>
[2] Brunner N. et. al., Rev. Mod. Phys. 86, (<a href="https://journals.aps.org/rmp/abstract/10.1103/RevModPhys.86.419">419</a>)</p>
]]></content>
        </item>
        
        <item>
            <title>Setup DNSCrypt with NetworkManager</title>
            <link>/posts/dnscrypt/</link>
            <pubDate>Tue, 20 Apr 2021 00:00:00 +0000</pubDate>
            
            <guid>/posts/dnscrypt/</guid>
            <description>To avoid your ISP eavesdropping on website you visit and other url you try to resolv, using privacy friendly DNS server is a necessity.
dnscrypt-proxy supports the encryption of your DNS request over HTTPS, and makes use of the DNSCrypt protocol. Here is a small guide to set this up alongside NetworkManager.
Installation Install the dnscrypt package provided by your distribution:
+ dnscrypt-proxy for ArchLinux
+ dnscrypt-proxy for Debian-based distribution</description>
            <content type="html"><![CDATA[<p>To avoid your ISP eavesdropping on website you visit and other url you try to resolv, using privacy friendly DNS server is a necessity.<br>
<code>dnscrypt-proxy</code> supports the encryption of your DNS request over HTTPS, and makes use of the DNSCrypt protocol.
Here is a small guide to set this up alongside NetworkManager.</p>
<h2 id="installation">Installation</h2>
<p>Install the dnscrypt package provided by your distribution:<br>
+ <a href="https://archlinux.org/packages/?name=dnscrypt-proxy">dnscrypt-proxy</a> for ArchLinux<br>
+ <a href="https://packages.debian.org/search?keywords=dnscrypt-proxy">dnscrypt-proxy</a> for Debian-based distribution</p>
<h2 id="configuration">Configuration</h2>
<h3 id="networkmanager">NetworkManager</h3>
<p>In its default config, NetworkManager overwrite <code>/etc/resolv.conf</code>.
In order to stop this behaviour, create a configuration file under <code>/etc/NetworkManager/conf.d/</code>, e.g. <code>/etc/NetworkManager/conf.d/00-dns.conf</code>, containing</p>
<pre tabindex="0"><code>[main]
dns=none
</code></pre><p>Restart <code>NetworkManager.service</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; sudo systemctl restart NetworkManager.service
</span></span></code></pre></div><h3 id="resolvconf">resolv.conf</h3>
<p><code>/etc/resolv.conf</code> is now a dead symlink.
Remove the file and create a new one with nameserver pointing to your localhost.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; sudo rm /etc/resolv.conf
</span></span><span style="display:flex;"><span>&gt; sudoedit /etc/resolv.conf
</span></span></code></pre></div><pre tabindex="0"><code>nameserver ::1
nameserver 127.0.0.1
options edns0 single-request-reopen
</code></pre><h3 id="dnscrypt-proxy">dnscrypt-proxy</h3>
<p>Make sure no other service makes use of port <code>:53</code> by running</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; ss -lp <span style="color:#f1fa8c">&#39;sport = :domain&#39;</span>
</span></span></code></pre></div><p>If the command output something more than one line (starting with <code>Netid</code>), a process is using the port 53 (common ones are <code>dnsmasq</code> and <code>systemd-resolv</code>).</p>
<p>By default, <code>dnscrypt-proxy</code> will chose the fastest resolver from the servers listed in <code>/etc/dnscrypt-proxy/dnscrypt-proxy.toml</code> under <code>[sources]</code>.
Optionally you can setup specific resolvers.
For an up-to-date list of server see the <a href="https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md">upstream page</a>.</p>
<p>Enable and start the <code>dnscrypt-proxy</code> service.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; sudo systemctl start dnscrypt-proxy.service
</span></span><span style="display:flex;"><span>&gt; sudo systemctl <span style="color:#8be9fd;font-style:italic">enable</span> dnscrypt-proxy.service
</span></span></code></pre></div><h2 id="test-your-config">Test your config</h2>
<p>NetworkManager still shows the DNS server reported by your router:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; nmcli dev show | grep IP4.DNS
</span></span></code></pre></div><p>However, using <code>nslookup</code> should show localhost on port 53 as the resolver:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; nslookup valcarce.fr
</span></span><span style="display:flex;"><span>Server:         ::1
</span></span><span style="display:flex;"><span>Address:        ::1#53
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Non-authoritative answer:
</span></span><span style="display:flex;"><span>Name:   valcarce.fr
</span></span><span style="display:flex;"><span>Address: 51.15.121.4
</span></span><span style="display:flex;"><span>Name:   valcarce.fr
</span></span><span style="display:flex;"><span>Address: 2001:bc8:1824:e4e::1
</span></span></code></pre></div><p>Finally, you can test your DNS via dnsleak websites such as <a href="https://dnsleaktest.com/">dnsleaktest.com</a> or <a href="https://mullvad.net/en/check/">mullvad.net</a>.<br>
Notice for Firefox user: by default (in the US) Firefox uses DNS-over-HTTPS (DoH) and send all your DNS requests to CloudFlare.
To prevent this, open Firefox <code>Preferences</code>, search for <code>Network Settings</code>, click on <code>Settings...</code> and disable <code>Enable DNS over HTTPS</code>.</p>
]]></content>
        </item>
        
        <item>
            <title>Julia - One-Time Pad (XOR)</title>
            <link>/posts/onetimepadjl/</link>
            <pubDate>Thu, 06 Feb 2020 00:00:00 +0000</pubDate>
            
            <guid>/posts/onetimepadjl/</guid>
            <description>Disclaimer This is a pet project to help me understand the relatively new programming language Julia. I don’t guarantee that the code in this blog post is optimal, nor respect all Julia conventions.
Algorithm objective An implementation of the one-time pad encryption algorithm, based on the XOR gate. The code should be able to encrypt any given file by generating a key of this file’s size and XORing the file with the key, bit-by-bit.</description>
            <content type="html"><![CDATA[<h2 id="disclaimer">Disclaimer</h2>
<p>This is a pet project to help me understand the relatively new programming language <a href="https://julialang.org">Julia</a>. I don’t guarantee that the code in this blog post is optimal, nor respect all Julia conventions.</p>
<h2 id="algorithm-objective">Algorithm objective</h2>
<p>An implementation of the one-time pad encryption algorithm, based on the XOR gate. The code should be able to encrypt any given file by generating a key of this file’s size and XORing the file with the key, bit-by-bit. We want the code to also be able to do the reverse; given a key and an encrypted file, run the XOR to get the original file.</p>
<h2 id="code">Code</h2>
<h3 id="part-1-arguments-and-help">Part 1: Arguments and help</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span>HELP <span style="color:#ff79c6">=</span> <span style="color:#f1fa8c">&#34;xore.jl usage:
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    xore.jl [enc|dec] [filename [keyfile]]
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">    Options:
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        enc : encrypt file. Generated file will be the filename.enc and generated key filename.key
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        dec : decrypt file. [keyfile] argument required
</span></span></span><span style="display:flex;"><span><span style="color:#f1fa8c">        &#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># Test arguments</span>
</span></span><span style="display:flex;"><span>@assert (length(<span style="color:#8be9fd;font-style:italic">ARGS</span>)<span style="color:#ff79c6">==</span><span style="color:#bd93f9">2</span> <span style="color:#ff79c6">||</span> length(<span style="color:#8be9fd;font-style:italic">ARGS</span>)<span style="color:#ff79c6">==</span><span style="color:#bd93f9">3</span>) HELP
</span></span><span style="display:flex;"><span>@assert (<span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">==</span><span style="color:#f1fa8c">&#34;enc&#34;</span> <span style="color:#ff79c6">||</span> <span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">==</span><span style="color:#f1fa8c">&#34;dec&#34;</span>) HELP
</span></span><span style="display:flex;"><span>@assert isfile(<span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">2</span>]) <span style="color:#f1fa8c">&#34;Can not find provided file&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">if</span> <span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">==</span><span style="color:#f1fa8c">&#34;dec&#34;</span>
</span></span><span style="display:flex;"><span>    @assert length(<span style="color:#8be9fd;font-style:italic">ARGS</span>)<span style="color:#ff79c6">==</span><span style="color:#bd93f9">3</span> <span style="color:#f1fa8c">&#34;Keyfile argument missing&#34;</span>
</span></span><span style="display:flex;"><span>    @assert isfile(<span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">3</span>]) <span style="color:#f1fa8c">&#34;Can not find provided keyfile&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># Filling variable</span>
</span></span><span style="display:flex;"><span>filename <span style="color:#ff79c6">=</span> <span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">2</span>]
</span></span><span style="display:flex;"><span>extension <span style="color:#ff79c6">=</span> findlast(isequal(<span style="color:#f1fa8c">&#39;.&#39;</span>),<span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">2</span>])
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">if</span> extension!<span style="color:#ff79c6">=</span><span style="color:#8be9fd;font-style:italic">nothing</span>
</span></span><span style="display:flex;"><span>    file <span style="color:#ff79c6">=</span> filename[<span style="color:#bd93f9">1</span><span style="color:#ff79c6">:</span>extension<span style="color:#ff79c6">-</span><span style="color:#bd93f9">1</span>]
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">else</span>
</span></span><span style="display:flex;"><span>    file <span style="color:#ff79c6">=</span> filename
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">end</span>
</span></span></code></pre></div><p>This the meta part of our program. Our program takes 2 or 3 arguments. The first one, either enc or dec set the mode of our program (decryption or encryption mode). The second one is the file to encrypt/decrypt. Finally, if the decryption mode is trigge, we need the file containing the key .
Some checks are made using assert to ensure that provided arguments, and arguments number, are correct.</p>
<h3 id="part-2-io">Part 2: I/O</h3>
<p>Let’s now study how one can read a given file and store it into a variable.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span><span style="color:#6272a4"># Read file to byte arrays</span>
</span></span><span style="display:flex;"><span>f <span style="color:#ff79c6">=</span> open(filename, <span style="color:#f1fa8c">&#34;r&#34;</span>)
</span></span><span style="display:flex;"><span>data <span style="color:#ff79c6">=</span> <span style="color:#8be9fd">UInt8</span>[]
</span></span><span style="display:flex;"><span>readbytes!(f,data,<span style="color:#8be9fd;font-style:italic">Inf</span>)
</span></span><span style="display:flex;"><span>close(f)
</span></span></code></pre></div><p>This open the file with the open function — argument r is for read only. We then create an array of type UInt8. Finally, we read the file by byte, and store them in the previously declared array. The Inf argument is to read to entire file — this way we don’t need to provide the length (number of byte) of our file.</p>
<h3 id="part-3-encryption">Part 3: Encryption</h3>
<p>Here is the encryption section in which we generate the key, encrypt the file and save both the encrypted version of the file and the key.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span><span style="color:#ff79c6">if</span> <span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">1</span>]<span style="color:#ff79c6">==</span><span style="color:#f1fa8c">&#34;enc&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4"># Genearting key of the file&#39;s size</span>
</span></span><span style="display:flex;"><span>    key <span style="color:#ff79c6">=</span> rand(<span style="color:#8be9fd">UInt8</span>,size(data)[<span style="color:#bd93f9">1</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4"># Generating encrypted file</span>
</span></span><span style="display:flex;"><span>    enc <span style="color:#ff79c6">=</span> <span style="color:#8be9fd">UInt8</span>[]
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">for</span> (i,d) <span style="color:#ff79c6">in</span> enumerate(data)
</span></span><span style="display:flex;"><span>        push!(enc,xor(d,key[i]))
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4"># Saving everything</span>
</span></span><span style="display:flex;"><span>    @assert <span style="color:#ff79c6">!</span>isfile(file<span style="color:#ff79c6">*</span><span style="color:#f1fa8c">&#34;.scrt&#34;</span>) <span style="color:#f1fa8c">&#34;enc.scrt file already exist in current directory&#34;</span>
</span></span><span style="display:flex;"><span>    enc_file <span style="color:#ff79c6">=</span> open(file<span style="color:#ff79c6">*</span><span style="color:#f1fa8c">&#34;.scrt&#34;</span>, <span style="color:#f1fa8c">&#34;w&#34;</span>)
</span></span><span style="display:flex;"><span>    write(enc_file, enc)
</span></span><span style="display:flex;"><span>    close(enc_file)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    @assert <span style="color:#ff79c6">!</span>isfile(file<span style="color:#ff79c6">*</span><span style="color:#f1fa8c">&#34;.key&#34;</span>) <span style="color:#f1fa8c">&#34;enc.key file already exist in current directory&#34;</span>
</span></span><span style="display:flex;"><span>    key_file <span style="color:#ff79c6">=</span> open(file<span style="color:#ff79c6">*</span><span style="color:#f1fa8c">&#34;.key&#34;</span>, <span style="color:#f1fa8c">&#34;w&#34;</span>)
</span></span><span style="display:flex;"><span>    write(key_file, key)
</span></span><span style="display:flex;"><span>    close(key_file)
</span></span></code></pre></div><p>The key is generated using the rand function. The key consists of an UInt8 array of the file’s size (number of byte).
We then proceed to the encryption by XOR-ing the file and the key, storing everything in the newly created enc array. The XOR bit-wise operation is done by the built-in xor function.
Finally, we save the encrypted file as well as the key using the name of the file (without the extension). A small check is made for the existence of such file, in order not to erase unintentionally potential files.</p>
<h3 id="part-3-decryption">Part 3: Decryption</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-julia" data-lang="julia"><span style="display:flex;"><span><span style="color:#ff79c6">else</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4"># Read the keyfile</span>
</span></span><span style="display:flex;"><span>    k <span style="color:#ff79c6">=</span> open(<span style="color:#8be9fd;font-style:italic">ARGS</span>[<span style="color:#bd93f9">3</span>], <span style="color:#f1fa8c">&#34;r&#34;</span>)
</span></span><span style="display:flex;"><span>    key <span style="color:#ff79c6">=</span> <span style="color:#8be9fd">UInt8</span>[]
</span></span><span style="display:flex;"><span>    readbytes!(k,key,<span style="color:#8be9fd;font-style:italic">Inf</span>)
</span></span><span style="display:flex;"><span>    close(k)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4"># Decryption</span>
</span></span><span style="display:flex;"><span>    dec <span style="color:#ff79c6">=</span> <span style="color:#8be9fd">UInt8</span>[]
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">for</span> (i,d) <span style="color:#ff79c6">in</span> enumerate(data)
</span></span><span style="display:flex;"><span>        push!(dec,xor(d,key[i]))
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">#Saving decrypted file</span>
</span></span><span style="display:flex;"><span>    dec_file <span style="color:#ff79c6">=</span> open(file<span style="color:#ff79c6">*</span><span style="color:#f1fa8c">&#34;.clear&#34;</span>, <span style="color:#f1fa8c">&#34;w&#34;</span>)
</span></span><span style="display:flex;"><span>    write(dec_file, dec)
</span></span><span style="display:flex;"><span>    close(dec_file)
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">end</span>
</span></span></code></pre></div><p>This is the decryption mode. It works in a similar manner as the encryption process, no further explanation are required to understand this part of the code.</p>
]]></content>
        </item>
        
    </channel>
</rss>
