Werner States, Steerable Weight, and Critical Visibility
Quantum steering sits between entanglement and Bell nonlocality. Alice measures her half of a shared state, and she can steer Bob’s conditional states in a way that no local hidden state model can reproduce. In this post we decide steerability numerically with a semidefinite program (SDP), using a two-qubit Werner state as a concrete example.
1. The problem
Alice and Bob share a state $\rho_{AB}$. Alice chooses a measurement setting $x \in {1,\dots,m}$ and obtains an outcome $a \in {0,1}$, described by projectors $P_{a|x}$. Bob’s unnormalized conditional states form the assemblage

The assemblage is unsteerable if it admits a local hidden state (LHS) model:
$$
\sigma_{a|x} = \sum_{\lambda} D(a|x,\lambda),\sigma_\lambda,
\qquad \sigma_\lambda \succeq 0 ,
$$
where $\lambda = (\lambda_1,\dots,\lambda_m)$ runs over all $2^m$ deterministic strategies and $D(a|x,\lambda)=\delta_{a,\lambda_x}$. Since there are finitely many $\lambda$ and every constraint is linear in $\sigma_\lambda$, this is a semidefinite feasibility problem.
Steerable weight
Instead of a yes/no answer, we compute a quantitative measure, the steerable weight. We split the assemblage into an unsteerable part and a remainder, and maximize the weight of the unsteerable part:
$$
\begin{aligned}
\mu^\star = \max_ \quad & \sum_\lambda \mathrm{Tr},\sigma_\lambda \
\text{s.t.} \quad & \sum_{\lambda}D(a|x,\lambda),\sigma_\lambda \preceq \sigma_{a|x}\quad \forall a,x,\
& \sigma_\lambda \succeq 0 ,
\end{aligned}
\qquad
\mathrm{SW} = 1-\mu^\star .
$$
The assemblage is unsteerable exactly when $\mathrm{SW}=0$.
Critical visibility in a single SDP
Take the Werner state
$$
\rho(p) = p,|\psi^-\rangle\langle\psi^-| + (1-p),\frac{\mathbb{1}}{4},
\qquad |\psi^-\rangle=\frac{|01\rangle-|10\rangle}{\sqrt2}.
$$
For a projective measurement along the unit vector $\vec n$, the assemblage is
$$
\sigma_{a|x}(p) = \frac14\Big(\mathbb{1} - p,(-1)^a,\vec n_x\cdot\vec\sigma\Big)
= p,\sigma^{\rm singlet}_{a|x} + (1-p)\frac{\mathbb{1}}{4}.
$$
Bob’s conditional Bloch vectors therefore have length $p$. Since $p$ enters the constraints linearly, we can make it an SDP variable and find the critical visibility $p_c$ in one shot:
$$
p_c = \max_{p,{\sigma_\lambda}}\ p
\quad\text{s.t.}\quad
\sum_{\lambda:,\lambda_x=a}\sigma_\lambda = p,\sigma^{\rm singlet}_{a|x}+(1-p)\frac{\mathbb{1}}{4},\ \ \sigma_\lambda\succeq0 .
$$
For $p\le p_c$ the state is unsteerable with the chosen settings, and for $p>p_c$ it is steerable.
2. The worked example
We study three things:
- Critical visibility versus number of settings. We use $m=2$ (the $x,z$ axes), $m=3$ (the $x,y,z$ axes), $m=4$ (four cube diagonals), and $m=6$ (six icosahedron axes).
- Steerable weight curves $\mathrm{SW}(p)$ for $m=2,3,4$.
- Two settings at relative angle $\theta$, which gives a 3D surface $\mathrm{SW}(p,\theta)$. The critical curve is expected to be
$$
p_c(\theta)=\frac{1}{\sqrt{1+\sin\theta}} .
$$
Known reference values are $p_c=1/\sqrt2\approx0.7071$ for two orthogonal settings, $p_c=1/\sqrt3\approx0.5774$ for three orthogonal settings, and $p_c\to 1/2$ in the limit of infinitely many projective settings.
3. Source code
1 | import itertools |
4. Walking through the code
Building blocks (sections 1 and 2)
werner_state(p) builds $\rho(p)=p|\psi^-\rangle\langle\psi^-|+(1-p)\mathbb 1/4$ as a $4\times4$ matrix. projector(n, a) returns $P_{a|n}=\tfrac12\big(\mathbb 1+(-1)^a,\vec n\cdot\vec\sigma\big)$, the spin projector along an arbitrary axis, normalized internally so that non-unit vectors like $(1,1,1)$ also work.
assemblage computes $\sigma_{a|x}=\mathrm{Tr}A[(P{a|x}\otimes\mathbb 1)\rho]$. The product $(P\otimes\mathbb 1)\rho$ is reshaped into a rank-4 tensor with indices $(i,j,i’,k)$, where the first pair labels Alice and Bob on the row side and the second pair labels them on the column side. The partial trace over Alice is then the contraction "ijik->jk", which sets the two Alice indices equal and sums over them.
The solver helper prefers Clarabel, an interior-point solver that is accurate to roughly $10^{-9}$ and well suited to small SDPs. If it is missing, it falls back to SCS with a tight tolerance.
SDP (A): steerable weight (section 3)
The function enumerates all deterministic strategies with itertools.product((0, 1), repeat=m), which gives $2^m$ tuples $\lambda=(\lambda_1,\dots,\lambda_m)$. Each strategy gets a Hermitian $2\times2$ variable $\sigma_\lambda$ with the constraint s >> 0.
For every setting $x$ and outcome $a$, the expression part is $\sum_{\lambda:\lambda_x=a}\sigma_\lambda$. The constraint sigma[x][a] - part >> 0 enforces $\sigma_{a|x}-\sum_\lambda D(a|x,\lambda)\sigma_\lambda\succeq0$. The objective maximizes $\mathrm{Re},\mathrm{Tr}\sum_\lambda\sigma_\lambda=\mu$, and the function returns $\mathrm{SW}=1-\mu^\star$, clipped at zero to remove tiny negative solver noise.
SDP (B) and SDP (C): finding $p_c$ (sections 4 and 5)
critical_p_bisection is the straightforward approach. It repeatedly solves the steerable-weight SDP at a trial value of $p$, moving the upper bound down if $\mathrm{SW}>10^{-6}$ and the lower bound up otherwise. With 22 iterations this costs 22 SDPs per critical visibility.
critical_p_direct is the accelerated version. The only change is that $p$ becomes a scalar cp.Variable(), and the inequality becomes the equality
$$
\sum_{\lambda:\lambda_x=a}\sigma_\lambda=p,\sigma^{\rm singlet}_{a|x}+(1-p)\frac{\mathbb 1}{4}.
$$
Maximizing $p$ then returns $p_c$ directly. The feasible set in $p$ is an interval $[0,p_c]$, because the problem is convex, so the maximum is exactly the threshold. One SDP replaces 22, and the program stays small: the matrices are always $2\times2$, with $2^m$ of them.
Settings (section 6)
The four sets of measurement directions are:
- $m=2$: the $x$ and $z$ axes.
- $m=3$: the $x$, $y$ and $z$ axes. The $y$ axis makes some matrices complex, which is why the variables are declared
hermitian=True. - $m=4$: four cube diagonals.
- $m=6$: six axes through the vertices of an icosahedron, using the golden ratio $\varphi=(1+\sqrt5)/2$.
Experiments (sections 7 to 10)
Experiment 1 loops over the settings with the fast solver and prints a table. Section 8 compares bisection against the one-shot SDP on $m=4$, and both must agree on $p_c$. Experiment 2 sweeps $p$ from $0.4$ to $1$ and evaluates $\mathrm{SW}$ for $m=2,3,4$.
Experiment 3 fixes the first setting along $z$ and rotates the second by an angle $\theta$ in the $x$–$z$ plane. It builds an $18\times21$ grid of $\mathrm{SW}(p,\theta)$ values for the 3D surface, then computes $p_c(\theta)$ by the fast SDP at 40 angles and compares it with $1/\sqrt{1+\sin\theta}$.
Plotting (section 11)
All four graphs are placed in a single figure with a $2\times2$ layout. The m=4 curve is dashed so that it remains visible even where it lies exactly on top of the m=3 curve. In panel (d), Bob’s conditional Bloch vector is recovered from each conditional state $s$ as $r_i=\mathrm{Tr}(s,\sigma_i)/\mathrm{Tr}(s)$.
5. Console output
================================================================
Experiment 1: critical visibility p_c of the Werner state
================================================================
settings m strategies 2^m p_c (SDP) time [s]
2 4 0.707107 0.138
3 8 0.577350 0.258
4 16 0.577350 0.436
6 64 0.539345 2.713
Reference: 1/sqrt(2) = 0.707107, 1/sqrt(3) = 0.577350, 1/2 = 0.500000
================================================================
Speed comparison (m = 4 settings)
================================================================
bisection (22 SDPs): p_c = 0.577351, time = 8.040 s
one-shot SDP : p_c = 0.577350, time = 0.151 s
speed-up : x53.2
================================================================
Experiment 2: steerable weight SW(p)
================================================================
p SW (m=2) SW (m=3) SW (m=4)
0.40 0.000000 0.000000 0.000000
0.46 0.000000 0.000000 0.000000
0.52 0.000000 0.000000 0.000000
0.58 0.000000 0.006269 0.006269
0.64 0.000000 0.148231 0.148231
0.70 0.000000 0.290192 0.290192
0.76 0.180589 0.432154 0.432154
0.82 0.385442 0.574115 0.574115
0.88 0.590294 0.716077 0.716077
0.94 0.795147 0.858038 0.858038
1.00 1.000000 1.000000 1.000000
================================================================
Experiment 3: two settings at angle theta
================================================================
theta [deg] p_c (SDP) 1/sqrt(1+sin)
15.0 0.891289 0.891289
30.0 0.816497 0.816497
45.0 0.765367 0.765367
60.0 0.732051 0.732051
75.0 0.713208 0.713208
90.0 0.707107 0.707107
max |SDP - formula| over the scan = 1.85e-08
Reading the console output
- Experiment 1. The SDP reproduces $p_c=1/\sqrt2\approx0.7071$ for two settings and $p_c=1/\sqrt3\approx0.5774$ for three. Four cube diagonals give the same value as three orthogonal axes, $0.5774$, so the extra setting adds nothing here. Six icosahedron axes lower the threshold to about $0.5393$, approaching the continuum limit of $1/2$. The runtime column shows the cost growing with the number of strategies $2^m$, yet even $m=6$ remains cheap.
- Speed comparison. Both methods return the same $p_c$ to within the bisection tolerance, but the one-shot SDP is faster by more than an order of magnitude because it replaces 22 SDP solves with a single one.
- Experiment 2. The table shows $\mathrm{SW}=0$ below the threshold and a linear rise above it up to $\mathrm{SW}=1$ at $p=1$. For two settings, for example, $\mathrm{SW}\approx0.3172$ at $p=0.8$.
- Experiment 3. The SDP values of $p_c(\theta)$ match $1/\sqrt{1+\sin\theta}$ essentially to solver precision, so the closed form is confirmed numerically.
6. Graphs

Panel (a): steerable weight versus noise
Every curve is flat at zero until its own critical visibility, marked by the dotted vertical line, and then rises linearly to $\mathrm{SW}=1$ at $p=1$. In all the cases computed here the rise follows
$$
\mathrm{SW}(p)=\max!\left(0,\ \frac{p-p_c}{1-p_c}\right),
$$
so the whole curve is determined by $p_c$. The red curve ($m=2$) starts rising at $p\approx0.707$, while the blue and green curves ($m=3$ and $m=4$) start at $p\approx0.577$. The blue and green curves coincide exactly, which is why the dashed green line sits on top of the blue one: four cube diagonals reveal no more steering than three orthogonal axes for the Werner state.
Panel (b): critical visibility versus number of settings
This is the central result. Each additional well-chosen setting lets Alice detect steering in noisier states, so the threshold falls from $0.7071$ at $m=2$ to $0.5774$ at $m=3$ and $0.5393$ at $m=6$. The dashed line at $1/2$ is the continuum limit, which no finite set of settings can cross. Panel (b) also shows that the number of settings is not the only thing that matters: their geometry does too, since $m=4$ with cube diagonals gains nothing over $m=3$.
Panel (c): the 3D surface $\mathrm{SW}(p,\theta)$
The two horizontal axes are the Werner parameter $p$ and the angle $\theta$ between Alice’s two measurement axes, and the height is the steerable weight. The surface is a flat plain at $\mathrm{SW}=0$ in the unsteerable region, and it rises into a ramp that reaches $\mathrm{SW}=1$ at $p=1$ for large $\theta$. The red curve on the floor is $p_c(\theta)=1/\sqrt{1+\sin\theta}$, and it follows the foot of the ramp exactly.
At small $\theta$ the two measurements are nearly the same, so they carry almost no incompatibility and the critical visibility approaches $1$. As $\theta$ grows to $90^\circ$ the settings become maximally incompatible and the threshold falls to $1/\sqrt2$. The steerable region therefore widens as the measurements become more incompatible.
Panel (d): Bob’s conditional states on the Bloch sphere
For $m=3$, each setting and outcome produces one point on or inside the Bloch sphere. At $p=1$ (red) all six points lie on the surface at $\pm\hat x,\pm\hat y,\pm\hat z$, which means Alice steers Bob into pure states. Lowering $p$ shrinks all six points toward the center, giving orange at $p=0.8$ and blue at $p=1/\sqrt3\approx0.577$. At the critical visibility the shrunken octahedron has just become small enough that a local hidden state ensemble can reproduce it, which is where the SDP reports $\mathrm{SW}=0$.
7. Why the fast version matters
Each steering test involves $2^m$ matrix variables, so the cost grows exponentially with the number of settings. Locating a threshold by bisection multiplies that cost by the number of iterations. Turning $p$ into an SDP variable removes this factor entirely, because the threshold becomes the optimum of a single convex program. The comparison section of the console output makes the difference concrete, and the saving is largest in the regime where each SDP is already expensive, with $m=6$ and beyond.
8. Conclusion
Steerability with a finite set of measurements is a semidefinite feasibility problem. Solving it for the Werner state reproduces the textbook thresholds $1/\sqrt2$, $1/\sqrt3$, and the closed form $1/\sqrt{1+\sin\theta}$ for two settings at angle $\theta$. The same code can be applied to any two-qubit state or any set of measurements by changing werner_state and SETTINGS.










is the partial trace over the two-dimensional output factor, and the constraint is exactly trace preservation, $\sum_jR_j^\dagger R_j=I_{16}$.
for every pair $(j,k)$ at once. The same function scores every strategy, which keeps the comparison fair: the uncoded qubit uses $R=I$ with $A_k=K_k$, and the coded cases use $16\times2$ operators $A_k$.







