brownadder / magpy

Magnus based time-integration for spins and qubits under a magnetic field
MIT License
1 stars 2 forks source link

Sigma class #20

Closed brownadder closed 4 months ago

brownadder commented 1 year ago

Sigma class

I = Sigma() is the identity operator O = Sigma(scale=0.0) is the 0 operator

Sigma(x=1) is sigma x on 1st spin Sigma(x=8) is on 8th spin

Sigma(x={3,5}) on 3 and 5th spins (set so that nothing is repeated – list has this problem)

Sigma(x={3,5}, y=7, z=1) for sigma x on 3,5, y on 7 and z on 1

Sigma(x=3, z=1) * Sigma(x=5, y=7) should give the same result as above.

Sigma.X() should return same as Sigma(x=1)
Sigma.X(1) should return same as Sigma(x=1) Sigma.X(3,5) should return Sigma(x={3,5})

Multiplication:

           Sigma.X(3) * Sigma.X(5) * Sigma.Y(7) * Sigma.Z(1) should have the same result as our older example, i.e. Sigma(x={3,5}, y=7, z=1)

But you could also do

           Sigma.X(3,5) * Sigma.Y(7) * Sigma.Z(1)

If you import Sigma as sg, then it will be more compact:

           sg.X(3,5) * sg.Y(7) * sg.Z(1)

Someone who is even more keen could directly import X,Y,Z and use without “sg.” prefix.

Then these could be sent to HOps, where they appear in a list against some scalar function of time. e.g. a Homonuclear Hamiltonian will three spins would look something like:

H = Hop({ f : [sg.X(1), sg.X(2), sg.X(3)], g : [sg.Y(1), sg.Y(2), sg.Y(3)], O1 : sg.Z(1), O2 : sg.Z(2), O3 : sg.Z(3), J12 : [sg.X(1,2), sg.Y(1,2), sg.Z(1,2)], J13 : [sg.X(1,3), sg.Y(1,3), sg.Z(1,3)], J23 : [sg.X(2,3), sg.Y(2,3), sg.Z(2,3)] })

We need to allow simple rescaling here e.g.

from magpy.Sigma import X,Y,Z

H = Hop({ f : [X(1), X(2), 0*X(3)], g : [Y(1), Y(2), 0*Y(3)], O1 : Z(1), O2 : Z(2), O3 : Z(3), J12 : [X(1,2), Y(1,2), Z(1,2)], J13 : [X(1,3), 2*Y(1,3), Z(1,3, scale=0)], J23 : [-X(2,3), Y(2,3), 0*Z(2,3)] })

Here we have multiplied X(3) and Y(3) by 0, Y(1,3) by 2, Z(1,3) by 0, X(2,3) by -1, Z(2,3) by 0

dannygoodacre commented 1 year ago

Internal representation:

A dictionary of sites and their respective Pauli matrices.

$\sigma_x \otimes I \otimes \sigma_y$ is stored internally as { 1 : 'x', 3 : 'y' }.

This allows for multiplication by combining the internal dictionaries, and concatenating strings for operators that are in the same site.

$(\sigma_x \otimes \sigma_z) (\sigma_y \otimes I)$ would be stored as { 1 : 'xy', 2 : 'z' }.

The presence of the Identity matrix is inferred.

dannygoodacre commented 1 year ago

Scalar coefficients:

Stored internally as a complex, starting at 1.

Sigma's __mul__ should check for instances of Sigma and float, and calculate as expected.

$(2\sigma_x)(3\sigma_y)$ would be stored as { 1 : 'xy' }, scale = 6.0.

Also define __imul__ and __rmul__ accordingly.

dannygoodacre commented 1 year ago

Multiplying by zero:

When a Sigma object is instantiated with a scale of zero, all specified spins are disregarded.

Also, when multiplying by zero, whether by a Sigma instance or by an integer, the resultant Sigma instance will have no stored spins.

0 * Sigma(x=1, y=2, scale=4) and Sigma(x=1, scale=0) are both stored as {}, scale = 0.

dannygoodacre commented 1 year ago

Product of Sigma instances

This has been moved to its own issue here.

dannygoodacre commented 1 year ago

Commutators and Anticommutators

[A,B] = \bigg(1 - \prod_{t=1}^n(-1)^{1-\delta_{\alpha_t,\beta_t}}\bigg)AB
\{A,B\} = \bigg(1 + \prod_{t=1}^n(-1)^{1-\delta_{\alpha_t,\beta_t}}\bigg)AB
[A,B] = 0 \;\;\Leftrightarrow\;\;\prod_{t=1}^n(-1)^{\delta_{\alpha_t,\beta_t}} = (-1)^n

This is equivalent to saying that the number of coincidences $\alpha_t = \beta_t$ is even when $n$ is even, and odd when $n$ is odd. Similarly for the anticommutator: odd $n$ and an even number of coincidences, and vice versa.

For any two Sigma instances, $n$ is the largest key in the union of their dictionaries.

This provides a quick way to determine if two operators commute or anticommute, and a not-too-demanding way to calculate the resultant operator if not.

Source