Skip to content

Commit

Permalink
Adding custom lattice to spin and FH model
Browse files Browse the repository at this point in the history
Adding custom lattice to spin and FH model
  • Loading branch information
javinoram authored May 23, 2024
2 parents e1562d8 + 98204ed commit 93bd6a1
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 108 deletions.
27 changes: 26 additions & 1 deletion quantumsim/lattice/lattice.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,29 @@ def lattice(params):
elif params['lattice'] == 'hexagon':
lattice = nx.hexagonal_lattice_graph(params['size'][0], params['size'][1], periodicity)

return lattice.edges(), lattice.nodes()
return lattice.edges(), lattice.nodes()

"""
Funcion para construir una grilla custom
input:
params: diccionario con los parametros de la lattice
- node: numero de nodos en cada eje [X, Y]
- edges: lista de conecciones entre los nodos (n1, n2)
return:
edges: lista con las conexiones entre los nodos
node: lista con los nodos del sistema
"""
def custom_lattice(params):
nodes = []
for i in range( params['node'][0] ):
nodes = nodes + [ (i,j) for j in range( params['node'][1] ) ]

edges = []
for edge in params['edges']:
x1 = edge[0]
x2 = edge[1]

t1 = ( x1%params['node'][0], x1//params['node'][0] )
t2 = ( x2%params['node'][0], x2//params['node'][0] )
edges.append( (t1, t2) )
return edges, nodes
84 changes: 42 additions & 42 deletions quantumsim/variational/adapt/fermihubbard.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .base import adap_base
import pennylane as qml
from quantumsim.lattice import lattice
from quantumsim.lattice import lattice, custom_lattice
from pennylane import numpy as np
from pennylane import FermiC, FermiA

Expand All @@ -18,52 +18,52 @@ class adap_fermihubbard(adap_base):
def __init__(self, params, lat):
self.qubits = params["sites"]*2
fermi_sentence = 0.0

if lat['lattice'] == 'custom':
pass
else:
x,y = lat['size']

x,y = lat['size']
if lat['lattice'] != 'custom':
lattice_edge, lattice_node = lattice(lat)
else:
lattice_edge, lattice_node = custom_lattice(lat)

#Construir terminos asociados al termino -t
hopping = -params["hopping"]
fermi_hopping = 0.0
for pair in lattice_edge:
p1, p2 = pair
fermi_hopping += FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p1[0] + p1[1]))
fermi_hopping += FermiC(2*(y*p1[0] + p1[1])+1)*FermiA(2*(y*p2[0] + p2[1])+1) + FermiC(2*(y*p2[0] + p2[1])+1)*FermiA(2*(y*p1[0] + p1[1])+1)
#Construir terminos asociados al termino -t
hopping = -params["hopping"]
fermi_hopping = 0.0
for pair in lattice_edge:
p1, p2 = pair
fermi_hopping += FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p1[0] + p1[1]))
fermi_hopping += FermiC(2*(y*p1[0] + p1[1])+1)*FermiA(2*(y*p2[0] + p2[1])+1) + FermiC(2*(y*p2[0] + p2[1])+1)*FermiA(2*(y*p1[0] + p1[1])+1)

fermi_sentence = hopping*fermi_hopping
fermi_sentence = hopping*fermi_hopping

#Construir terminos asociados al potencial U
if 'U' in params:
Upotential = params["U"]
fermi_U = 0.0
for node in lattice_node:
p1, p2 = node
fermi_U += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)*FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += Upotential*fermi_U
#Construir terminos asociados al potencial U
if 'U' in params:
u_potential = params["U"]
fermi_u = 0.0
for node in lattice_node:
p1, p2 = node
fermi_u += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)*FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += u_potential*fermi_u

#Construir terminos asociados al campo electroico E
if 'E' in params:
Efield = params["E"]
fermi_E = 0.0
for node in lattice_node:
p1, p2 = node
fermi_E += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)
fermi_E += FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += Efield*fermi_E
#Construir terminos asociados al campo electroico E
if 'E' in params:
e_field = params["E"]
fermi_e = 0.0
for node in lattice_node:
p1, p2 = node
fermi_e += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)
fermi_e += FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += e_field*fermi_e

#Construir terminos asociados al potencial V
if 'V' in params:
Vpotencial = params["V"]
fermi_V = 0.0
for pair in lattice_edge:
p1, p2 = pair
n_i = FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p1[0] + p1[1])) + FermiC(2*(y*p1[0] + p1[1]) +1)*FermiA(2*(y*p1[0] + p1[1]) +1)
n_j = FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]) +1)*FermiA(2*(y*p2[0] + p2[1]) +1)
fermi_V += n_i*n_j
fermi_sentence += Vpotencial*fermi_V
#Construir terminos asociados al potencial V
if 'V' in params:
v_potencial = params["V"]
fermi_v = 0.0
for pair in lattice_edge:
p1, p2 = pair
n_i = FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p1[0] + p1[1])) + FermiC(2*(y*p1[0] + p1[1]) +1)*FermiA(2*(y*p1[0] + p1[1]) +1)
n_j = FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]) +1)*FermiA(2*(y*p2[0] + p2[1]) +1)
fermi_v += n_i*n_j
fermi_sentence += v_potencial*fermi_v


#Transformar los terminos de segunda cuantizacion a espines
Expand All @@ -81,4 +81,4 @@ def __init__(self, params, lat):
terms.pop(index)

#Almacenar hamiltoniano
self.hamiltonian = qml.Hamiltonian(np.real(np.array(coeff)), terms)
self.hamiltonian = qml.Hamiltonian(np.real(np.array(coeff)), terms)
84 changes: 42 additions & 42 deletions quantumsim/variational/vqe/fermihubbard.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .base import vqe_base
from quantumsim.lattice import lattice
from quantumsim.lattice import lattice, custom_lattice
from pennylane import FermiC, FermiA
import pennylane as qml
from pennylane import numpy as np
Expand All @@ -18,52 +18,52 @@ class vqe_fermihubbard(vqe_base):
def __init__(self, params, lat):
self.qubits = params["sites"]*2
fermi_sentence = 0.0

if lat['lattice'] == 'custom':
pass
else:
x,y = lat['size']

x,y = lat['size']
if lat['lattice'] != 'custom':
lattice_edge, lattice_node = lattice(lat)
else:
lattice_edge, lattice_node = custom_lattice(lat)

#Construir terminos asociados al termino -t
hopping = -params["hopping"]
fermi_hopping = 0.0
for pair in lattice_edge:
p1, p2 = pair
fermi_hopping += FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p1[0] + p1[1]))
fermi_hopping += FermiC(2*(y*p1[0] + p1[1])+1)*FermiA(2*(y*p2[0] + p2[1])+1) + FermiC(2*(y*p2[0] + p2[1])+1)*FermiA(2*(y*p1[0] + p1[1])+1)
#Construir terminos asociados al termino -t
hopping = -params["hopping"]
fermi_hopping = 0.0
for pair in lattice_edge:
p1, p2 = pair
fermi_hopping += FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p1[0] + p1[1]))
fermi_hopping += FermiC(2*(y*p1[0] + p1[1])+1)*FermiA(2*(y*p2[0] + p2[1])+1) + FermiC(2*(y*p2[0] + p2[1])+1)*FermiA(2*(y*p1[0] + p1[1])+1)

fermi_sentence = hopping*fermi_hopping
fermi_sentence = hopping*fermi_hopping

#Construir terminos asociados al potencial U
if 'U' in params:
Upotential = params["U"]
fermi_U = 0.0
for node in lattice_node:
p1, p2 = node
fermi_U += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)*FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += Upotential*fermi_U
#Construir terminos asociados al potencial U
if 'U' in params:
u_potential = params["U"]
fermi_u = 0.0
for node in lattice_node:
p1, p2 = node
fermi_u += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)*FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += u_potential*fermi_u

#Construir terminos asociados al campo electroico E
if 'E' in params:
Efield = params["E"]
fermi_E = 0.0
for node in lattice_node:
p1, p2 = node
fermi_E += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)
fermi_E += FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += Efield*fermi_E
#Construir terminos asociados al campo electroico E
if 'E' in params:
e_field = params["E"]
fermi_e = 0.0
for node in lattice_node:
p1, p2 = node
fermi_e += FermiC(y*p1 + 2*p2)*FermiA(y*p1 + 2*p2)
fermi_e += FermiC(y*p1 + 2*p2+1)*FermiA(y*p1 + 2*p2+1)
fermi_sentence += e_field*fermi_e

#Construir terminos asociados al potencial V
if 'V' in params:
Vpotencial = params["V"]
fermi_V = 0.0
for pair in lattice_edge:
p1, p2 = pair
n_i = FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p1[0] + p1[1])) + FermiC(2*(y*p1[0] + p1[1]) +1)*FermiA(2*(y*p1[0] + p1[1]) +1)
n_j = FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]) +1)*FermiA(2*(y*p2[0] + p2[1]) +1)
fermi_V += n_i*n_j
fermi_sentence += Vpotencial*fermi_V
#Construir terminos asociados al potencial V
if 'V' in params:
v_potencial = params["V"]
fermi_v = 0.0
for pair in lattice_edge:
p1, p2 = pair
n_i = FermiC(2*(y*p1[0] + p1[1]))*FermiA(2*(y*p1[0] + p1[1])) + FermiC(2*(y*p1[0] + p1[1]) +1)*FermiA(2*(y*p1[0] + p1[1]) +1)
n_j = FermiC(2*(y*p2[0] + p2[1]))*FermiA(2*(y*p2[0] + p2[1])) + FermiC(2*(y*p2[0] + p2[1]) +1)*FermiA(2*(y*p2[0] + p2[1]) +1)
fermi_v += n_i*n_j
fermi_sentence += v_potencial*fermi_v

#Transformar los terminos de segunda cuantizacion a espines
coeff, terms = qml.jordan_wigner( fermi_sentence, ps=True ).hamiltonian().terms()
Expand All @@ -80,4 +80,4 @@ def __init__(self, params, lat):
terms.pop(index)

#Almacenar hamiltoniano
self.hamiltonian = qml.Hamiltonian(np.real(np.array(coeff)), terms)
self.hamiltonian = qml.Hamiltonian(np.real(np.array(coeff)), terms)
46 changes: 23 additions & 23 deletions quantumsim/variational/vqe/spin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .base import vqe_base
from quantumsim.lattice import lattice
from quantumsim.lattice import lattice, custom_lattice
from pennylane import numpy as np
import pennylane as qml

Expand All @@ -18,31 +18,31 @@ def __init__(self, params, lat):
self.qubits = params['sites']
terms = []
coeff = []

if lat['lattice'] == 'custom':
pass
else:
x,y = lat['size']

x,y = lat['size']
if lat['lattice'] != 'custom':
lattice_edge, lattice_node = lattice(lat)

#Construir terminos asociados al exchange -J
for pair in lattice_edge:
termz = qml.PauliZ(wires=[ x*pair[0][0] + pair[0][1]])@qml.PauliZ(wires=[x*pair[1][0] + pair[1][1]])
termx = qml.PauliX(wires=[ x*pair[0][0] + pair[0][1]])@qml.PauliX(wires=[x*pair[1][0] + pair[1][1]])
termy = qml.PauliY(wires=[ x*pair[0][0] + pair[0][1]])@qml.PauliY(wires=[x*pair[1][0] + pair[1][1]])
else:
lattice_edge, lattice_node = custom_lattice(lat)

#Construir terminos asociados al exchange -J
for pair in lattice_edge:
termz = qml.PauliZ(wires=[ x*pair[0][0] + pair[0][1]])@qml.PauliZ(wires=[x*pair[1][0] + pair[1][1]])
termx = qml.PauliX(wires=[ x*pair[0][0] + pair[0][1]])@qml.PauliX(wires=[x*pair[1][0] + pair[1][1]])
termy = qml.PauliY(wires=[ x*pair[0][0] + pair[0][1]])@qml.PauliY(wires=[x*pair[1][0] + pair[1][1]])

terms.extend( [termx, termy, termz] )
coeff.extend( [-params["J"][0]/4.0, -params["J"][1]/4.0, -params["J"][2]/4.0] )

#Construir terminos asociados al campo magnetico h
if 'h' in params:
for pair in lattice_node:
termz = qml.PauliZ(wires=[ x*pair[0] + pair[1]])
termx = qml.PauliX(wires=[ x*pair[0] + pair[1]])
termy = qml.PauliY(wires=[ x*pair[0] + pair[1]])

terms.extend( [termx, termy, termz] )
coeff.extend( [-params["J"][0]/4.0, -params["J"][1]/4.0, -params["J"][2]/4.0] )

#Construir terminos asociados al campo magnetico h
if 'h' in params:
for pair in lattice_node:
termz = qml.PauliZ(wires=[ x*pair[0] + pair[1]])
termz = qml.PauliX(wires=[ x*pair[0] + pair[1]])
termz = qml.PauliY(wires=[ x*pair[0] + pair[1]])

terms.extend( [termx, termy, termz] )
coeff.extend( [params["h"][0]/2.0, params["h"][1]/2.0, params["h"][2]/2.0] )
coeff.extend( [params["h"][0]/2.0, params["h"][1]/2.0, params["h"][2]/2.0] )

#Eliminar terminos cuyos coefficientes son 0
to_delete = [i for i,c in enumerate(coeff) if np.abs(c)<1e-10 ]
Expand Down

0 comments on commit 93bd6a1

Please sign in to comment.