• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

qspin/H17-Mar-2019-1,5581,288

qspin.egg-info/H03-May-2022-399307

PKG-INFOH A D17-Mar-201914.3 KiB399307

README.rstH A D06-May-201810.4 KiB376285

setup.cfgH A D17-Mar-201980 85

setup.pyH A D17-Mar-20191.2 KiB3633

README.rst

1Quantum Spin
2============
3
4This is a little package that will help with learning how quantum spin and entanglement work.
5It is meant to complement some of the "theoretical minimum" lectures and other web resources:
6
7[
8`Quantum state <https://en.wikipedia.org/wiki/Quantum_state>`_;
9`Pauli matrices <https://en.wikipedia.org/wiki/Pauli_matrices>`_;
10`Singlet state <https://en.wikipedia.org/wiki/Singlet_state>`_;
11`Triplet state <https://en.wikipedia.org/wiki/Triplet_state>`_;
12`Density matrix <https://en.wikipedia.org/wiki/Density_matrix>`_;
13`Quantum entanglement <https://en.wikipedia.org/wiki/Quantum_entanglement>`_;
14`Entropy <https://en.wikipedia.org/wiki/Von_Neumann_entropy>`_;
15`Quantum logic gate <https://en.wikipedia.org/wiki/Quantum_logic_gate>`_
16]
17
18- Book: **Quantum Mechanics - The Theoretical Minimum**, Leanoard Susskind and Art Friedman, Basic Books, 2014. (mostly chapters 6&7)
19- http://theoreticalminimum.com/courses/quantum-mechanics/2012/winter/lecture-6 and lecture-7
20
21`Link to documentation on readthedocs <http://qspin.readthedocs.io>`_
22
23**Install**
24------------
25
26.. code:: bash
27
28    pip install --upgrade qspin
29
30**Out-of-the box tests:**
31--------------------------
32.. code:: python
33
34    $ python
35    >>> import qspin
36    >>> qspin.all_tests()
37
38Examples of code use
39--------------------
40
41**Spin states**
42~~~~~~~~~~~~~~~~~~~~~~~~~~
43
44up, down and linear combinations to form mixed states
45
46.. code:: python
47
48    >>> from qspin import bra,ket,u,d,s0,sx,sy,sz
49    >>> u
50    |u>
51    >>> d
52    |d>
53    >>> u + d
54    |u>  + |d>
55    >>> i = 1j
56    >>> u + i*d
57    |u>  + i |d>
58
59**Operators**
60~~~~~~~~~~~~~~~~~~~~~~~~~~
61
62.. code:: python
63
64    >>> sx # Pauli spin matrix
65    [[0 1]
66     [1 0]]
67    >>> sy
68    [[ 0.+0.j -0.-1.j]
69     [ 0.+1.j  0.+0.j]]
70    >>> sz
71    [[ 1  0]
72     [ 0 -1]]
73    >>> sz*u
74    |u>
75    >>> sz*d
76    - |d>
77
78**Expected value of an observable**
79~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
80
81sz is the observable for z-component of spin, For the "up" state, the only
82outcome us +1, so the expected value is +1.
83
84.. code:: python
85
86    >> u.H*sz*u
87    1.0
88    >> sz.average(u) # another way to compute the average of an observable
89    1.0
90
91(`q.H` is Hermetian conjugate; it converts a ket to a bra, as in :math:`\Braket{u|s_z|u}`).
92The operator (sz in this case) is known in quantum mechanics as an observable,
93meaning it measures something. Here it is the z-component of spin.
94The eigenvalues of the observable are the possible outcomes the observation.
95Underlying each state is a wave function. We store the wave function internally
96as vector, with each component being the wave function value for the basis eigenstate.
97The operators (observables) are stored as matrices, also defined on the same basis.
98The assumed basis throughout qspin is :math:`\Ket{u}` and :math:`\Ket{d}` for single particles.
99
100.. code:: python
101
102    >>> u
103    |u>
104    >>> u.phi
105    matrix([[ 1.],
106            [ 0.]])
107
108**Eigenvalues**
109~~~~~~~~~~~~~~~~~~~~~~~~~~
110
111We can evaluate the eigenvalues and eigenvectors of observables. ".matrix" pulls out the matrix
112representation of the operator.
113
114.. code:: python
115
116    >>> import numpy as np
117    >>> sz
118    [[ 1  0]
119     [ 0 -1]]
120    >>> ev, evec = np.linalg.eig(sz.matrix)
121    >>> ev
122    array([ 1., -1.])
123    >>> evec
124    matrix([[ 1.,  0.],
125            [ 0.,  1.]])
126    >>> sx # spin x
127    [[0 1]
128     [1 0]]
129    >>> ev, evec = np.linalg.eig(sx.matrix)
130    >>> ev
131    array([ 1., -1.])
132    >>> evec
133    matrix([[ 0.70710678, -0.70710678],
134            [ 0.70710678,  0.70710678]])
135
136There is a handy 'eig' method that produces a list of eigenvalues and a
137list of eigenvectors, with the eigenvectors being states:
138
139.. code:: python
140
141    >>> ev, evec = sx.eig()
142    >>> ev
143    array([1.,=1.])
144    >>> evec
145    [0.707107 |u> + 0.707107 |d> , -0.707107 |u> + 0.707107 |d> ]
146    >>> sz.eig()
147    (array([ 1., -1.]), [|u> , |d> ])
148
149Note that the spin-x observerable has the same eigenvalues as spin-z, +1 and -1. But the eigenvectors
150are different, in our basis, since we are using the {:math:`\Ket{u}`, :math:`\Ket{d}`} basis. They are
151:math:`(\Ket{u} + \Ket{d})/\sqrt{2}`, which measures as sx = +1, and
152:math:`(\Ket{u} - \Ket{d})/\sqrt{2}`, which measures as sx = -1.
153
154**Conditional Probabilities**
155~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
156
157Conditional probabilities are calculated using inner products of states with the
158eigenvectors of the measurment, squared. So the probability
159of measuring sx = +1 given the particle is prepared in state :math:`\Ket{u}` is:
160
161.. code:: python
162
163    >>> l = (u+d).N # "left" state. The .N normalizes the state
164    >>> (bra(l)*ket(u))**2   # expected value of up given left
165    0.5
166    >>> np.abs( l.H * u )**2 # another way to do this. The .H means Hermetian conjugate; converts ket to bra
167    0.5
168    >>> l.prob(sx,l)
169    1.0
170    >>> l.prob(sx,u)
171    0.5
172
173
174**Measurement**
175~~~~~~~~~~~~~~~~~~~~~~~~~~
176
177The quantum measurement of an observable involves 'collapsing' the state
178to one of the eigen states of the obserable.
179
180.. code:: python
181
182    >>> l = (u+d).N
183    >>> sz.measure(l)
184    (1.0, |u>)
185
186The result is random, either up or down
187(with 50-50 probability in this case where the particle starts out in state 'spin left').
188The measure function returns the value of the measurment, 1.0 in this case,
189and the collapsed state, :math:`\Ket{u}`.
190
191**String Representation of State**
192~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193
194We can use strings to refer to basis states.
195
196.. code:: python
197
198    >>> u = ket('|u>') # or ket('u')  (the vert line and bracket are optional)
199    >>> d = ket('|d>') # or ket('d')
200    >>> u
201    |u>
202    >>> d
203    |d>
204
205The string representation of basis functions defaults to 'u' and 'd'. As
206an alternative, the representation can be set to
207'0' and '1' or to up and down arrows (the later require your
208terminal to have the ability to display unicode characters).
209
210.. code:: python
211
212    >>> qspin.set_base_repr('01')
213    >>> u = ket('0')
214    >>> d = ket('1')
215    >>> (u + d).N
216    0.707107 |0> + 0.707107 |1>
217
218With :code:`qspin.set_base_repr('arrow')`, :code:`u=ket([1,0])` renders as :math:`\Ket{\uparrow}`
219This provides cute printout, but is not too useful for string entry, since the up and
220down arrows are unicode.
221
222**Wave Function Definition**
223~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
224
225States can also be defined using the wave function, given
226in the form of a matrix column vector. And it is good practice
227to normalize states.
228
229.. code:: python
230
231    >>> w = ket( np.matrix([1.,1.]).T).N
232    >>> w
233    0.707106781187 |u>  + 0.707106781187 |d>
234
235
236Form a projection operator from outer products of basis states.
237
238.. code:: python
239
240    >> rho = ket('|u>') * bra('<u|') + ket('|d>') * bra('<d|')
241    >> # can also do this:
242    >> u = ket('|u>'); d = ket('|d>');
243    >> rho = ket(u) * bra(u) + ket(d) * bra(d)
244    >>> rho
245    [[ 1.  0.]
246     [ 0.  1.]]
247    >>> u
248    1.0 |u>
249    >>> rho*u
250    1.0 |u>
251    >>> rho*d
252    1.0 |d>
253
254Note that bra(ket(...)) and ket(bra(...)) convert, and takes care of the complex-conjugating.
255
256.. code:: python
257
258    >> u.kind
259    'ket'
260    >> bra(u).kind
261    'bra'
262
263**Density Matrix and Entropy**
264~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
265
266Create a density matrix for an ensemble of single particles.
267
268.. code:: python
269
270    >> from qspin import entropy
271    >> P = [0.5, 0.5]
272    >> rho = P[0] * bra('|u>').density() + P[1] * bra('|d>').density() # make sure the probabilities add to one
273    >> entropy(rho) # it's not zero because there is a mixture of states
274    0.69314718055994529
275    >> rho = ( bra('|u>') + bra('|d>') ).N.density()
276    >> entropy(rho) # this is zero because all electrons are prepared in the "u+d" state
277    0
278
279Make sure you normalize any states you define, using the post-operation .N.
280
281The von Neumann **entropy** is
282:math:`S = -\sum_i(p_i log(p_i))` where :math:`p_i` are the density matrix eigenvalues.
283The entropy is essentially the randomness in a measurement of the quantum state. It
284can be applied to any density matrix for either pure or mixed states. (A
285pure state has zero entropy.)
286
287**Multi-particle States**
288~~~~~~~~~~~~~~~~~~~~~~~~~~
289
290Multi-particle states are in the space formed from the Kronecker product of Hilbert spaces
291of the individual particles. Since multi-particle quantum states can be mixed states, there
292are far more possible state vectors (:math:`2^n` dimensional vector space) than for classical
293systems (which are in only :math:`n` dimensional space)
294
295We build up multi-particle states with Kronecker products '**' (meaning :math:`\otimes`), or with strings
296
297.. code:: python
298
299    >>> uu = u**u
300    >>> dd = ket('|dd>') # or ket('dd')
301    >>> s = (d**u**u + u**d**u + d**d**u).N
302    >>> s
303    0.57735 |udu> + 0.57735 |duu> + 0.57735 |ddu>
304
305Multi-particle operators are similarly built up with Kronecker products
306
307.. code:: python
308
309    >>> s2x = sx**sx
310    >>> s2x
311    [[0 0 0 1]
312     [0 0 1 0]
313     [0 1 0 0]
314     [1 0 0 0]
315
316**Partial Trace**
317~~~~~~~~~~~~~~~~~~~~~~~~~~
318
319The density matrix for a multi-particle state is :math:`2^n \times 2^n`. A partial
320trace is a way to form the density matrix for a subset of the particles. 'Tracing out'
321:math:`m` of the particles results in a :math:`2^{n-m} \times 2^{n-m}` density matrix.
322Partial traces are important in many aspects of analyzing the multi-particle state,
323including evaluating the entanglement.
324
325.. code:: python
326
327    >>> sing = (u**d - d**u).N
328    >>> rho = sing.density()
329    >>> rho
330    matrix([[ 0. ,  0. ,  0. ,  0. ],
331            [ 0. ,  0.5, -0.5,  0. ],
332            [ 0. , -0.5,  0.5,  0. ],
333            [ 0. ,  0. ,  0. ,  0. ]])
334    >>> rhoA = ptrace(rho,[1]) # trace over particle 1 ('Bob') to get particle 0 ('Alice') density
335    >>> rhoA
336    matrix([[0.5, 0. ],
337            [0. , 0.5]])
338
339**Entangled States**
340~~~~~~~~~~~~~~~~~~~~~~~~~~
341
342Once you have created a (possibly) entangled state of two particles, you can test it for entanglement:
343
344.. code:: python
345
346    >>> sing = (u**d - d**u).N
347    >>> sing.entangled()
348    True
349    >>> (u**u).entangled()
350    False
351
352The test for entanglement is to check the entropy of one of the particles after
353the other particle has been 'traced out.'
354
355Quantum Computing
356~~~~~~~~~~~~~~~~~~~~~~~~~~
357
358
359Several quantum logic gates are now defined in qspin including:
360Hadamard, NOT, SWAP, controlled gates, square root gates, and phase shift gates.
361
362.. code:: python
363
364    >>> from qspin import u,d,gate
365    >>> SWAP = gate('SWAP')
366    >>> SWAP*(u**d)
367    |du>
368    >>> H = gate('Hadamard')
369    >>> H*u
370    0.707 |u> + 0.707 |d>
371    >>> H*d
372    0.707 |u> - 0.707 |d>
373
374shows that SWAP interchanges the q-bits, and Hadamard makes the Bell states
375from spin up and spin down.
376