An Introduction to Majorana's "Stellar" Representation of Spin

A "star"

We're all familiar with the qubit.

It's just about the simplest quantum system that there is.

To get started, let's choose some basis states. If we quantize along the $Z$ axis, we can write the state of a qubit as a complex linear superposition of basis states $\mid \uparrow \rangle = \begin{pmatrix} 1 \\ 0 \end{pmatrix}$ and $\mid \downarrow \rangle = \begin{pmatrix} 0 \\ 1 \end{pmatrix}$:

$\mid \psi \rangle = \alpha\mid \uparrow \rangle + \beta \mid \downarrow \rangle = \begin{pmatrix} \alpha \\ \beta \end{pmatrix}$

where $|\alpha|^2 + |\beta|^2 = 1$.

There are many qubits in nature: in fact, any two dimensional quantum system can be used as a qubit. But the original point of a qubit was to represent the intrinsic angular momentum, or spin, of a spin-$\frac{1}{2}$ particle. Indeed, a qubit is an irriducible representation of $SU(2)$, which is the double cover of the 3D rotation group $SO(3)$.

If we consider the expectation values $(\langle \psi \mid \hat{X} \mid \psi \rangle, \langle \psi \mid \hat{Y} \mid \psi \rangle, \langle \psi \mid \hat{Z} \mid \psi \rangle)$, with the Pauli matrices:

$\hat{X} = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}$, $\hat{Y} = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix}$, $\hat{Z} = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}$

we can associate the qubit uniquely with a point on the unit sphere, which picks out its "average rotation axis." It turns out that this point uniquely determines the state (up to complex phase).

In [17]:
from spheres import *

qubit = qt.rand_ket(2)
print(qubit)
print("xyz: %s" % ([qt.expect(qt.sigmax(), qubit),\
                    qt.expect(qt.sigmay(), qubit),\
                    qt.expect(qt.sigmaz(), qubit)]))
Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
Qobj data =
[[-0.50212694+0.50076549j]
 [ 0.54008752-0.45321952j]]
xyz: [-0.9962983741962657, -0.08576693188845602, 0.005795081390174539]

We can visualize it with matplotlib:

In [18]:
%matplotlib notebook
fig = viz_spin(qubit)

Or with vpython (in a notebook or in the console, the latter being better for interactive visuals):

In [ ]:
scene = vp.canvas(background=vp.color.white)
m = MajoranaSphere(qubit, scene=scene)

Now one way of seeing that the state is uniquely determined by this point (up to complex phase) is to consider a perhaps less familiar construction:

Given a qubit $\mid \psi \rangle = \begin{pmatrix} \alpha \\ \beta \end{pmatrix}$, form the complex ratio $\frac{\beta}{\alpha}$. If $\alpha=0$, then this will go to $\infty$, which is fine, as we'll see!

So we have some $c = \frac{\beta}{\alpha}$. Suppose $c \neq \infty$. Then this is just a point on the complex plane: $c = x + iy$. Now imagine there's a unit sphere at the origin cut at the equator by the complex plane. And imagine you're standing at the South Pole, and you have a laser pointer, and you point the beam at $c$.

The beam will intersect the sphere in exactly one location. If $c$ is outside the unit circle on the plane, you'll get a point on the southern hemisphere, and if $c$ is inside the unit circle, you'll get a point on the northern hemisphere. Every point in the plane, in this way, can be mapped to a point on the sphere--except we have a point left over, the South Pole itself! So if $\alpha = 0$, and therefore $c = \infty$, we map that point to the South Pole. In other words, we can think of $z = \frac{\beta}{\alpha}$ as being a point on the extended complex plane (the plane plus an extra point at infinity), which is just the sphere. This map is known as the stereographic projection.

Explicitly, if $c = x + iy$, then we have $(\frac{2x}{1+x^2+y^2}, \frac{2y}{1+x^2+y^2}, \frac{1-x^2-y^2}{1+x^2+y^2})$ or $(0,0,-1)$ if $z=\infty$.

Below, the map is depicted (where the pole of projection is the North Pole):

Moreover, we can go in reverse: $c = \frac{x}{1+z} + i\frac{y}{1+z}$ or $\infty$ if $z=-1$.

In [19]:
c = spinor_c(qubit) # gives us our complex ratio
print("c: %s" % c)

xyz = c_xyz(c) # stereographically projects to the sphere
print("xyz: %s" % xyz)
c: (-0.9905580099071644-0.08527276925028497j)
xyz: [-0.99629837 -0.08576693  0.00579508]

As you can see, we get the same point which we obtained before via the expectation values $(\langle \hat{X} \rangle, \langle \hat{Y} \rangle, \langle \hat{Z} \rangle)$. Moreover, it's clear that every state will give us a unique point on the sphere, and vice versa, up to complex phase. And the bit about the phase is true because clearly if we rephase both $\alpha$ and $\beta$ by the same amount in $c = \frac{\beta}{\alpha}$, we'll end up with the same $c$. And we're only allowed to rephase, and not rescale, because of the normalization condition $|\alpha|^2 + |\beta|^2 = 1$.

And by the way, the phase matters: watch what happens to the phase (depicted in green), as we do a full rotation:

In [ ]:
scene = vp.canvas(background=vp.color.white)
m = MajoranaSphere(qubit, show_phase=True, scene=scene)
m.snapshot()
m.evolve(qt.jmat(1/2, 'y'), T=2*np.pi)

The phase goes to the negative of itself. Only after a full two turns does the state come back to itself completely, and this is what characterizes spin-$\frac{1}{2}$ representations. $SU(2)$ is the double cover of $SO(3)$ and what this means is that for every element in the usual rotation group, there are two elements of $SU(2)$.

In [ ]:
scene = vp.canvas(background=vp.color.white)
m = MajoranaSphere(qubit, show_phase=True, scene=scene)
m.snapshot()
m.evolve(qt.jmat(1/2, 'y'), T=4*np.pi)

In any case, by means of the stereographic projection, we obtain the "Riemann sphere" (here depicted with the North Pole being the pole of projection:

We've just seen how each these cardinal directions can be associated with qubit states: in fact, the eigenstates of the Pauli matrices. And thus we observe the interesting fact that antipodal points on the sphere become orthogonal vectors in Hilbert space.

In [20]:
print([spinor_c(v) for v in qt.sigmax().eigenstates()[1]])
print([spinor_c(v) for v in qt.sigmay().eigenstates()[1]])
print([spinor_c(v) for v in qt.sigmaz().eigenstates()[1]])
[(-1+0j), (1.0000000000000002+0j)]
[-1j, (-0+1.0000000000000002j)]
[inf, 0j]

spheres.coordinates provides useful functions for going back and forth between coordinate systems on the sphere. E.g.:

In [21]:
print(xyz_c(xyz)) # back to extended complex coordinates
print(xyz_sph(xyz)) # spherical coordinates
print(c_sph(c)) # spherical coordinates, etc
print(c_spinor(c)) # back to a qubit, up to phase
print(compare_nophase(qubit, c_spinor(c)))
(-0.9905580099071642-0.08527276925028496j)
[1.56500121 3.22746653]
[1.56500121 3.22746653]
Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket
Qobj data =
[[ 0.70915269+0.j        ]
 [-0.70245688-0.06047141j]]
True

A "constellation"

So we can represent a spin-$\frac{1}{2}$ state by a point on the "Bloch sphere" plus a complex phase, which gives us an intuitive geometrical picture of the quantum state, one which isn't immediately obvious when you look at it represented as a complex linear superpositon, say, of $Z$ eigenstates.

But what about higher spin states? Recall that spin representations are labeled by $j$ values, which count up from $0$ by half integers, and their dimensionality is $2j + 1$. Each basis state is associated with an $m$ value ranging from $-j$ to $j$, counting up by $1$. So basis states can be labeled $\mid j, m \rangle$. E.g.:

For spin-$0$: $\mid 0, 0 \rangle$.

For spin-$\frac{1}{2}$: $\mid \frac{1}{2}, \frac{1}{2} \rangle, \mid \frac{1}{2}, -\frac{1}{2} \rangle$.

For spin-$1$: $\mid 1, 1 \rangle, \mid 1, 0 \rangle, \mid 1, -1 \rangle$.

For spin-$\frac{3}{2}$: $\mid \frac{3}{2}, \frac{3}{2} \rangle, \mid \frac{3}{2}, \frac{1}{2} \rangle, \mid \frac{3}{2}, -\frac{1}{2} \rangle, \mid \frac{3}{2}, -\frac{3}{2} \rangle$.

And so on.

One might wonder if our simple geometrical representation for a qubit generalizes for higher spin. And the answer is yes! In fact, it was first proposed way back in 1932 by Ettore Majorana. The answer is both simple and elegant: a spin-$j$ state can be represented by a constellation of $2j$ points on the sphere (up to phase). These points are often poetically termed "stars" in the literature.

So just as a spin-$\frac{1}{2}$ can be specified by a point on a sphere, a spin-$1$ state can be specified by two points on the sphere, a spin-$\frac{3}{2}$ state by three points on the sphere, and so on (again, up to phase).


The basic construction is this.

Given a spin-$j$ state in the $\mid j, m \rangle$ representation, $\mid \psi \rangle = \begin{pmatrix}a_{0} \\ a_{1} \\ a_{2} \\a_{3} \\ \vdots\end{pmatrix}$, form a complex polynomial in an unknown $z$:

$$ p(z) = \sum_{m=-j}^{m=j} (-1)^{j+m} \sqrt{\binom{2j}{j-m}} a_{j+m} z^{j-m} $$

The roots of this polynomial, called the Majorana polynomial, when stereographically projected from the complex plane to the sphere, yield the constellation. If you lose a degree, (i.e. if the coefficients for the highest powers of $z$ are $0$) then you add a root "at infinity" for each one, and so the spin-$j$ state can always be specified by $2j$ point on the sphere.

In other words, by the fundamental theorem of algebra, no less, a spin-$j$ state factorizes into $2j$ pieces.

As the above image indicates, the $\mid j, m\rangle$ basis states (assuming we've quantized along the $Z$ direction) consist of (in the case of spin-$\frac{3}{2}$) three stars at the North Pole, none at the South Pole; two stars at the North Pole, one at the South Pole; one at the North Pole, two at the South Pole; none at the North Pole, three at the South Pole. Any spin state can be expressed as a complex linear superposition of these basis states/constellations.

At the same time, thanks to Majorana, we can also interpret the spin state as a polynomial and find its roots. Each corresponds to a little monomial whose product (as opposed to sum) determines the same state. Each root is associated with a direction in 3D, and under rotations, the stars transform rigidly as a whole constellation.

In [22]:
from spheres import *
spin = xyz_spin([[1,0,0], [0,1,0],[0,0,1]])
print("cartesian stars:\n%s" % spin_xyz(spin))
print("spherical stars:\n%s" % spin_sph(spin))
print("extended complex stars:\n%s" % "\n".join([str(c) for c in spin_c(spin)]))
cartesian stars:
[[2.22044605e-16 1.00000000e+00 2.22044605e-16]
 [1.00000000e+00 8.32667268e-17 2.22044605e-16]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]
spherical stars:
[[1.57079633e+00 1.57079633e+00]
 [1.57079633e+00 8.32667268e-17]
 [0.00000000e+00 0.00000000e+00]]
extended complex stars:
(2.220446049250313e-16+0.9999999999999998j)
(0.9999999999999998+8.326672684688674e-17j)
0j
In [ ]:
scene = vp.canvas(background=vp.color.white)
m = MajoranaSphere(spin, scene=scene)
m.evolve(qt.jmat(3/2, 'y'), dt=0.01, T=5)

We can use matplotlib for this too:

In [23]:
%matplotlib notebook
anim = animate_spin(spin, qt.jmat(3/2, 'y'))