Skip to content

Commit

Permalink
Adding custom lattice to spin and FH model
Browse files Browse the repository at this point in the history
  • Loading branch information
javinoram committed May 23, 2024
1 parent e1562d8 commit 98204ed
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 98204ed

Please sign in to comment.