Skip to main content

Quantum Spin

This is a little package that will help with learning how quantum spin and entanglement work. It is meant to complement some of the “theoretical minimum” lectures and other web resources:

[ Quantum state; Pauli matrices; Singlet state; Triplet state; Density matrix; Quantum entanglement; Entropy; Quantum logic gate ]

Link to documentation on readthedocs

Install

pip install --upgrade qspin

Out-of-the box tests:

$ python
>>> import qspin
>>> qspin.all_tests()

Examples of code use

Spin states

up, down and linear combinations to form mixed states

>>> from qspin import bra,ket,u,d,s0,sx,sy,sz
>>> u
|u>
>>> d
|d>
>>> u + d
|u>  + |d>
>>> i = 1j
>>> u + i*d
|u>  + i |d>

Operators

>>> sx # Pauli spin matrix
[[0 1]
 [1 0]]
>>> sy
[[ 0.+0.j -0.-1.j]
 [ 0.+1.j  0.+0.j]]
>>> sz
[[ 1  0]
 [ 0 -1]]
>>> sz*u
|u>
>>> sz*d
- |d>

Expected value of an observable

sz is the observable for z-component of spin, For the “up” state, the only outcome us +1, so the expected value is +1.

>> u.H*sz*u
1.0
>> sz.average(u) # another way to compute the average of an observable
1.0

(q.H is Hermetian conjugate; it converts a ket to a bra, as in \(\Braket{u|s_z|u}\)). The operator (sz in this case) is known in quantum mechanics as an observable, meaning it measures something. Here it is the z-component of spin. The eigenvalues of the observable are the possible outcomes the observation. Underlying each state is a wave function. We store the wave function internally as vector, with each component being the wave function value for the basis eigenstate. The operators (observables) are stored as matrices, also defined on the same basis. The assumed basis throughout qspin is \(\Ket{u}\) and \(\Ket{d}\) for single particles.

>>> u
|u>
>>> u.phi
matrix([[ 1.],
        [ 0.]])

Eigenvalues

We can evaluate the eigenvalues and eigenvectors of observables. “.matrix” pulls out the matrix representation of the operator.

>>> import numpy as np
>>> sz
[[ 1  0]
 [ 0 -1]]
>>> ev, evec = np.linalg.eig(sz.matrix)
>>> ev
array([ 1., -1.])
>>> evec
matrix([[ 1.,  0.],
        [ 0.,  1.]])
>>> sx # spin x
[[0 1]
 [1 0]]
>>> ev, evec = np.linalg.eig(sx.matrix)
>>> ev
array([ 1., -1.])
>>> evec
matrix([[ 0.70710678, -0.70710678],
        [ 0.70710678,  0.70710678]])

There is a handy ‘eig’ method that produces a list of eigenvalues and a list of eigenvectors, with the eigenvectors being states:

>>> ev, evec = sx.eig()
>>> ev
array([1.,=1.])
>>> evec
[0.707107 |u> + 0.707107 |d> , -0.707107 |u> + 0.707107 |d> ]
>>> sz.eig()
(array([ 1., -1.]), [|u> , |d> ])

Note that the spin-x observerable has the same eigenvalues as spin-z, +1 and -1. But the eigenvectors are different, in our basis, since we are using the {\(\Ket{u}\), \(\Ket{d}\)} basis. They are \((\Ket{u} + \Ket{d})/\sqrt{2}\), which measures as sx = +1, and \((\Ket{u} - \Ket{d})/\sqrt{2}\), which measures as sx = -1.

Conditional Probabilities

Conditional probabilities are calculated using inner products of states with the eigenvectors of the measurment, squared. So the probability of measuring sx = +1 given the particle is prepared in state \(\Ket{u}\) is:

>>> l = (u+d).N # "left" state. The .N normalizes the state
>>> (bra(l)*ket(u))**2   # expected value of up given left
0.5
>>> np.abs( l.H * u )**2 # another way to do this. The .H means Hermetian conjugate; converts ket to bra
0.5
>>> l.prob(sx,l)
1.0
>>> l.prob(sx,u)
0.5

Measurement

The quantum measurement of an observable involves ‘collapsing’ the state to one of the eigen states of the obserable.

>>> l = (u+d).N
>>> sz.measure(l)
(1.0, |u>)

The result is random, either up or down (with 50-50 probability in this case where the particle starts out in state ‘spin left’). The measure function returns the value of the measurment, 1.0 in this case, and the collapsed state, \(\Ket{u}\).

String Representation of State

We can use strings to refer to basis states.

>>> u = ket('|u>') # or ket('u')  (the vert line and bracket are optional)
>>> d = ket('|d>') # or ket('d')
>>> u
|u>
>>> d
|d>

The string representation of basis functions defaults to ‘u’ and ‘d’. As an alternative, the representation can be set to ‘0’ and ‘1’ or to up and down arrows (the later require your terminal to have the ability to display unicode characters).

>>> qspin.set_base_repr('01')
>>> u = ket('0')
>>> d = ket('1')
>>> (u + d).N
0.707107 |0> + 0.707107 |1>

With qspin.set_base_repr('arrow'), u=ket([1,0]) renders as \(\Ket{\uparrow}\) This provides cute printout, but is not too useful for string entry, since the up and down arrows are unicode.

Wave Function Definition

States can also be defined using the wave function, given in the form of a matrix column vector. And it is good practice to normalize states.

>>> w = ket( np.matrix([1.,1.]).T).N
>>> w
0.707106781187 |u>  + 0.707106781187 |d>

Form a projection operator from outer products of basis states.

>> rho = ket('|u>') * bra('<u|') + ket('|d>') * bra('<d|')
>> # can also do this:
>> u = ket('|u>'); d = ket('|d>');
>> rho = ket(u) * bra(u) + ket(d) * bra(d)
>>> rho
[[ 1.  0.]
 [ 0.  1.]]
>>> u
1.0 |u>
>>> rho*u
1.0 |u>
>>> rho*d
1.0 |d>

Note that bra(ket(…)) and ket(bra(…)) convert, and takes care of the complex-conjugating.

>> u.kind
'ket'
>> bra(u).kind
'bra'

Density Matrix and Entropy

Create a density matrix for an ensemble of single particles.

>> from qspin import entropy
>> P = [0.5, 0.5]
>> rho = P[0] * bra('|u>').density() + P[1] * bra('|d>').density() # make sure the probabilities add to one
>> entropy(rho) # it's not zero because there is a mixture of states
0.69314718055994529
>> rho = ( bra('|u>') + bra('|d>') ).N.density()
>> entropy(rho) # this is zero because all electrons are prepared in the "u+d" state
0

Make sure you normalize any states you define, using the post-operation .N.

The von Neumann entropy is \(S = -\sum_i(p_i log(p_i))\) where \(p_i\) are the density matrix eigenvalues. The entropy is essentially the randomness in a measurement of the quantum state. It can be applied to any density matrix for either pure or mixed states. (A pure state has zero entropy.)

Multi-particle States

Multi-particle states are in the space formed from the Kronecker product of Hilbert spaces of the individual particles. Since multi-particle quantum states can be mixed states, there are far more possible state vectors (\(2^n\) dimensional vector space) than for classical systems (which are in only \(n\) dimensional space)

We build up multi-particle states with Kronecker products ‘**’ (meaning \(\otimes\)), or with strings

>>> uu = u**u
>>> dd = ket('|dd>') # or ket('dd')
>>> s = (d**u**u + u**d**u + d**d**u).N
>>> s
0.57735 |udu> + 0.57735 |duu> + 0.57735 |ddu>

Multi-particle operators are similarly built up with Kronecker products

>>> s2x = sx**sx
>>> s2x
[[0 0 0 1]
 [0 0 1 0]
 [0 1 0 0]
 [1 0 0 0]

Partial Trace

The density matrix for a multi-particle state is \(2^n \times 2^n\). A partial trace is a way to form the density matrix for a subset of the particles. ‘Tracing out’ \(m\) of the particles results in a \(2^{n-m} \times 2^{n-m}\) density matrix. Partial traces are important in many aspects of analyzing the multi-particle state, including evaluating the entanglement.

>>> sing = (u**d - d**u).N
>>> rho = sing.density()
>>> rho
matrix([[ 0. ,  0. ,  0. ,  0. ],
        [ 0. ,  0.5, -0.5,  0. ],
        [ 0. , -0.5,  0.5,  0. ],
        [ 0. ,  0. ,  0. ,  0. ]])
>>> rhoA = ptrace(rho,[1]) # trace over particle 1 ('Bob') to get particle 0 ('Alice') density
>>> rhoA
matrix([[0.5, 0. ],
        [0. , 0.5]])

Entangled States

Once you have created a (possibly) entangled state of two particles, you can test it for entanglement:

>>> sing = (u**d - d**u).N
>>> sing.entangled()
True
>>> (u**u).entangled()
False

The test for entanglement is to check the entropy of one of the particles after the other particle has been ‘traced out.’

Quantum Computing

Several quantum logic gates are now defined in qspin including: Hadamard, NOT, SWAP, controlled gates, square root gates, and phase shift gates.

>>> from qspin import u,d,gate
>>> SWAP = gate('SWAP')
>>> SWAP*(u**d)
|du>
>>> H = gate('Hadamard')
>>> H*u
0.707 |u> + 0.707 |d>
>>> H*d
0.707 |u> - 0.707 |d>

shows that SWAP interchanges the q-bits, and Hadamard makes the Bell states from spin up and spin down.

Metadata

Release files for qspin 2.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qspin 2.3.3
File Size Uploaded
qspin-2.3.3.tar.gz 22.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qspin 2.3.3
File Interpreter ABI Platform
qspin-2.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 41.7 kB

Release files / qspin-2.3.3.tar.gz

Download URL qspin-2.3.3.tar.gz
Size 22.6 kB
Tags Source
SHA-256 checksum
How to use checksums
79e305b5851c46669f4d626e0c9906ab9a4a3ba18d180386dcd4a44107a7e2cf
BLAKE2b-256 checksum
How to use checksums
7d5e505826edd26dd10d82a245441826798f00de3a5ba844456b98e3a86576bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.6

Release files / qspin-2.3.3-py3-none-any.whl

Download URL qspin-2.3.3-py3-none-any.whl
Size 19.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9cb6ae298467cf23cf7b3cbf0b78e15789b04c6b8021aa709bd4c377d4533260
BLAKE2b-256 checksum
How to use checksums
bfb864818a23755e3f7760c253893be1a8de52c40ec22196f58b600c182bd4e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.6

Release history Release notifications | RSS feed

This release

2.3.3 This release

2 release files

2.3.2

2 release files

2.3.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

0.1.8

2 release files

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page