Constructing operators
Start by importing PauliStrings:
using PauliStrings
import PauliStrings as ps
To construct an operator we first need to declare an empty operator of $N$ qubits:
H = Operator(N)
PauliStrings.jl
supports up to 128 qubits.
We can add a term of the form $J X_i$ by doing
H += J, "X", i
and a term of the form $J X_iX_j$ by doing
H += J, "X", i, "X", j
Similarly, we add a term of the form $J X_iX_jX_k$ by doing
H += J, "X", i, "X", j, "X", k
etc.
1D transverse Ising model
Let's construct the Hamiltonian of a 1D transverse Ising model $H=-J(\sum_{<i,j>}Z_i Z_j +g \sum_i X_i)$
function ising1D(N, J, g)
H = Operator(N)
for j in 1:(N - 1)
H += "Z",j,"Z",j+1
end
H += "Z",1,"Z",N # periodic boundary condition
for j in 1:N
H += g,"X",j
end
return -J*H
end
ising1D (generic function with 1 method)
Note that the first qubit starts at index 1, following Julia's 1-based index.
Operators can be printed in strings format with the println
function:
println(ising1D(3, 1, 0.5))
(-1.0 + 0.0im) Z1Z
(-1.0 + 0.0im) 1ZZ
(-0.5 + 0.0im) 1X1
(-0.5 + 0.0im) X11
(-1.0 + 0.0im) ZZ1
(-0.5 + 0.0im) 11X
2D transverse Ising model
Here we construct a 2D Ising model on a square lattice of L*L sites, with no periodic boundary conditions.
function ising2D(L, J, g)
H = ps.Operator(L * L)
for x in 1:L-1
for y in 1:L
# convert x,y to qubit index
i = L * (y - 1) + x
j = L * (y - 1) + (x + 1)
# horizontal interaction terms
H += ("Z", i, "Z", j)
# convert x,y to qubit index
i = L * (x - 1) + y
j = L * x + y
# vertical interaction terms
H += ("Z", i, "Z", j)
end
end
for j in 1:L*L
H += g, "X", j
end
return -J * H
end
println(ising2D(3, 1.0, 0.5))
(-0.5 + 0.0im) 111111X11
(-0.5 + 0.0im) 1X1111111
(-1.0 + 0.0im) 1111111ZZ
(-0.5 + 0.0im) 11X111111
(-1.0 + 0.0im) 1111ZZ111
(-1.0 + 0.0im) 1Z11Z1111
(-0.5 + 0.0im) 1111111X1
(-0.5 + 0.0im) 1111X1111
(-1.0 + 0.0im) 1111Z11Z1
(-1.0 + 0.0im) 111111ZZ1
(-1.0 + 0.0im) 111Z11Z11
(-1.0 + 0.0im) 111ZZ1111
(-0.5 + 0.0im) 11111X111
(-1.0 + 0.0im) 1ZZ111111
(-1.0 + 0.0im) 11Z11Z111
(-0.5 + 0.0im) X11111111
(-1.0 + 0.0im) Z11Z11111
(-0.5 + 0.0im) 11111111X
(-1.0 + 0.0im) 11111Z11Z
(-1.0 + 0.0im) ZZ1111111
(-0.5 + 0.0im) 111X11111
We can also construct a 2d operator using the string_2d
function,
function ising2D(L, J, g)
H = Operator(L * L)
for x in 1:L
for y in 1:L
# horizontal interaction
(x < L) && (H += string_2d(("Z", x, y, "Z", x + 1, y), L, L))
# vertical interaction
(y < L) && (H += string_2d(("Z", x, y, "Z", x, y + 1), L, L))
# transverse field
H += g * string_2d(("X", x, y), L, L)
end
end
return -J * H
end
println(ising2D(3, 1.0, 0.5))
(-0.5 + 0.0im) 111111X11
(-0.5 + 0.0im) 1X1111111
(-1.0 + 0.0im) 1111111ZZ
(-0.5 + 0.0im) 11X111111
(-1.0 + 0.0im) 1111ZZ111
(-1.0 + 0.0im) 1Z11Z1111
(-0.5 + 0.0im) 1111111X1
(-0.5 + 0.0im) 1111X1111
(-1.0 + 0.0im) 1111Z11Z1
(-1.0 + 0.0im) 111111ZZ1
(-1.0 + 0.0im) 111Z11Z11
(-1.0 + 0.0im) 111ZZ1111
(-0.5 + 0.0im) 11111X111
(-1.0 + 0.0im) 1ZZ111111
(-1.0 + 0.0im) 11Z11Z111
(-0.5 + 0.0im) X11111111
(-1.0 + 0.0im) Z11Z11111
(-0.5 + 0.0im) 11111111X
(-1.0 + 0.0im) 11111Z11Z
(-1.0 + 0.0im) ZZ1111111
(-0.5 + 0.0im) 111X11111