{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tight informationally complete quantum measurements" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import scipy as sc\n", "import scipy.linalg\n", "np.set_printoptions(precision=6, suppress=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Spherical t-designs\n", "\n", "We begin with \"spherical t-designs.\" They're useful for numerical integration. Basically instead of integrating a polynomial over some space, you can instead take a finite sum of the values of the polynomial at some specially chosen points: and you get the same answer!\n", "\n", "So: a spherical t-design is a set of $n$ normalized vectors such that the average value of any $t$-th order (homogeneous) polynomial over the set is equal to the average of over all normalized vectors.\n", "\n", "In other words, working with a unit 2-sphere, and a $t$-th order polynomial $f_{t}(\\psi)$, and $n$ points $\\{ |\\psi_{i}\\rangle \\}$:\n", "\n", "$$ \\frac{1}{4\\pi}\\int_{S^2} p(\\psi) d\\psi = \\frac{1}{n}\\sum_{i=0}^{n} p(\\psi_{i}) $$\n", "\n", "As we'll see, a set of $t$-design vectors have the property that they minimize the $t$-th order frame potential:\n", "\n", "$$ \\sum_{i,j} |\\langle \\psi_{i} | \\psi_{j} \\rangle|^{2t} $$ \n", "\n", "So let's look for one! We'll use `jax` for some just-in-time complication and for taking derivatives, and `scipy.optimize` for the constrained optimization." ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [], "source": [ "import jax\n", "import jax.numpy as jp\n", "\n", "def spherical_design(d, n, t):\n", " @jax.jit\n", " def frame_potential(V):\n", " R = V.reshape(d, n)\n", " return sum([jp.abs(jp.dot(a, b))**(2*t) for b in R.T for a in R.T])\n", " frame_potential_jac = jax.jit(jax.jacrev(frame_potential))\n", " @jax.jit\n", " def norm_constraint(V):\n", " R = V.reshape(d,n)\n", " return jp.linalg.norm(jp.linalg.norm(R, axis=0) - jp.ones(n))**2\n", " norm_jac = jax.jit(jax.jacrev(norm_constraint))\n", " result = sc.optimize.minimize(frame_potential,\\\n", " np.random.randn(d*n),\\\n", " jac=frame_potential_jac,\\\n", " constraints=[{\"type\": \"eq\",\\\n", " \"fun\": norm_constraint,\\\n", " \"jac\": norm_jac}],\\\n", " tol=1e-14,\\\n", " options={\"ftol\": 1e-14,\\\n", " \"disp\": True,\\\n", " \"maxiter\": 5000},\\\n", " method=\"SLSQP\")\n", " return result.x.reshape(d, n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we'll look for a spherical 2-design on the 2-sphere in $\\mathbb{R}^3$ with six elements." ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Optimization terminated successfully. (Exit mode 0)\n", " Current function value: 7.2000274658203125\n", " Iterations: 178\n", " Function evaluations: 437\n", " Gradient evaluations: 178\n" ] }, { "data": { "text/plain": [ "array([[ 0.654425, -0.138834, -0.029355, -0.804426, -0.871627, -0.378888],\n", " [ 0.251973, -0.97831 , 0.589923, 0.586375, -0.381487, 0.378301],\n", " [-0.712908, 0.153738, 0.806925, 0.095198, -0.307788, -0.84459 ]])" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d, n, t = 3, 6, 2\n", "R = spherical_design(d, n, t); R" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's make up some random 2nd order homogeneous polynomial:" ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [], "source": [ "poly = lambda xyz: xyz[0]**2 + xyz[0]*xyz[1] + 6*xyz[2]**2 + 5*xyz[2]*xyz[0] + xyz[1]**2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll use `quadpy` for the numerical integration. (Ironically, of course, under the hood, they basically do the same thing!)" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [], "source": [ "import quadpy\n", "scheme = quadpy.u3.get_good_scheme(19)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have $\\frac{1}{n}\\sum_{i=0}^{n} p(\\psi_{i})$:" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.6670280946135927" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(1/n)*sum([poly(r) for r in R.T])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And $\\frac{1}{4\\pi}\\int_{S^2} p(\\psi) d\\psi$:" ] }, { "cell_type": "code", "execution_count": 107, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "2.6666666666666665" ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(1/(4*np.pi))*scheme.integrate(poly, np.zeros(3), 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pretty darn close! Let's look at the magical points on the sphere:" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "