Use this topic to ask your questions about the QHack 2023 challenge: A Noisy Heisenberg Model
HI Pennylane Team, I’ve been a bit confused with the problem statement and the coding that I’ve been doing. Can you please guide me on it? Following is the code.
I’m unsure whether I understand the problem statement correctly or the implementation issue, so I need your suggestions.
t=0.1
while t<=time:
for d in range(depth):
for i in range(num_wires-1):
qml.CNOT([i,i+1])
qml.DepolarizingChannel(p, wires=i+1)
qml.RX(couplings[0]*t, wires=i+1)
qml.CNOT([i+1,i])
qml.DepolarizingChannel(p, wires=i)
qml.CNOT([i,i+1])
qml.DepolarizingChannel(p, wires=i+1)
qml.RY(couplings[1]*t, wires=i+1)
qml.CNOT([i+1,i])
qml.DepolarizingChannel(p, wires=i)
qml.CNOT([i,i+1])
qml.DepolarizingChannel(p, wires=i+1)
qml.RZ(couplings[2]*t, wires=i+1)
qml.CNOT([i+1,i])
qml.DepolarizingChannel(p, wires=i)
for i in range(num_wires):
qml.RX(couplings[3]*t, wires=i)
t+=0.01
return qml.state()
Hi @roysuman088
Your implementation is indeed incorrect and I think it’s due to a combination of understanding the concepts and implementation details.
I’d say the main one is that you don’t need a while loop. When you use a gate to evolve a state up to time t
, you’re evolving it from time 0 up to time t
. So here what you’re actually doing is evolving many times from time 0 to different t
times, which is not what the challenge asks.
You may also want to draw your circuit to see if it’s actually looking the way you expect. I hope this helps!
Hello,
Can someone help me understand why my implementation does not work ? I am very close from the expected answer but not close enough.
# Put your code here #
N = num_wires
J_x, J_y, J_z, h = couplings
for j in range(1, depth+1):
for i in range(N):
# implementing ising XX
qml.RY(np.pi/2, i)
qml.RY(np.pi/2, (i+1)%N)
qml.CNOT([i, (i+1)%N])
qml.DepolarizingChannel(p, (i+1)%N)
qml.RZ(-2*J_x*time/depth, (i+1)%N)
qml.CNOT([i, (i+1)%N])
qml.DepolarizingChannel(p, (i+1)%N)
qml.RY(-np.pi/2, i)
qml.RY(-np.pi/2, (i+1)%N)
# implementing ising YY
qml.RX(np.pi/2, i)
qml.RX(np.pi/2, (i+1)%N)
qml.CNOT([i, (i+1)%N])
qml.DepolarizingChannel(p, (i+1)%N)
qml.RZ(-2*J_y*time/depth, (i+1)%N)
qml.CNOT([i, (i+1)%N])
qml.DepolarizingChannel(p, (i+1)%N)
qml.RX(-np.pi/2, i)
qml.RX(-np.pi/2, (i+1)%N)
# implementing ising ZZ
qml.CNOT([i, (i+1)%N])
qml.DepolarizingChannel(p, (i+1)%N)
qml.RZ(-2*J_z*time/depth, (i+1)%N)
qml.CNOT([i, (i+1)%N])
qml.DepolarizingChannel(p, (i+1)%N)
# implementing X
qml.RX(-2*h*time/depth, i)
return qml.state()
Thanks
Hi @yoshypdf ,
It looks like you’ve got some gates wrong and you’re overcomplicating yourself in some things. For example you don’t need to use modulo %. You’ve also got errors in the ranges you’re using for i and j. Why don’t you try running this locally or on Google Colab for a small circuit and trying to draw it or run it? That can help you debug it!
Hello all,
I am very close to getting the correct result, but I can’t figure out what I’m getting wrong, any help will be appreciated! My approach was to decompose the RZZ, RYY, and RXX gates and then just apply them to every pair of wires in the closed loop.
# Put your code here #
def RXX_decomposed(theta, wires, p):
"""Decomposes the RXX gate using RX, RY, RZ, and CNOT gates with noise after each CNOT.
Args:
theta (float): The rotation angle.
wires (list): The two qubits the gate acts on.
p (float): The depolarization probability after each CNOT gate.
"""
qml.Hadamard(wires=wires[0])
qml.Hadamard(wires=wires[1])
qml.CNOT(wires=[wires[0], wires[1]])
qml.DepolarizingChannel(p, wires=wires[1])
qml.RZ(theta, wires=wires[1])
qml.CNOT(wires=[wires[0], wires[1]])
qml.DepolarizingChannel(p, wires=wires[1])
qml.Hadamard(wires=wires[0])
qml.Hadamard(wires=wires[1])
def RYY_decomposed(theta, wires, p):
"""Decomposes the RYY gate using RX, RY, RZ, and CNOT gates with noise after each CNOT.
Args:
theta (float): The rotation angle.
wires (list): The two qubits the gate acts on.
p (float): The depolarization probability after each CNOT gate.
"""
qml.RX(np.pi / 2, wires=wires[0])
qml.RX(np.pi / 2, wires=wires[1])
qml.CNOT(wires=[wires[0], wires[1]])
qml.DepolarizingChannel(p, wires=wires[1])
qml.RZ(theta, wires=wires[1])
qml.CNOT(wires=[wires[0], wires[1]])
qml.DepolarizingChannel(p, wires=wires[1])
qml.RX(-np.pi / 2, wires=wires[0])
qml.RX(-np.pi / 2, wires=wires[1])
def RZZ_decomposed(theta, wires, p):
"""Decomposes the RZZ gate using RX, RY, RZ, and CNOT gates with noise after each CNOT.
Args:
theta (float): The rotation angle.
wires (list): The two qubits the gate acts on.
p (float): The depolarization probability after each CNOT gate.
"""
qml.CNOT(wires=[wires[0], wires[1]])
qml.DepolarizingChannel(p, wires=wires[1])
qml.RZ(theta, wires=wires[1])
qml.CNOT(wires=[wires[0], wires[1]])
qml.DepolarizingChannel(p, wires=wires[1])
# Unpack couplings
Jx, Jy, Jz, h = couplings
n_qubits = num_wires
dt = time / depth # Time step for Trotterization
def heisenberg_step():
# Apply local magnetic field in X direction
for i in range(num_wires):
qml.RX(-h * dt, wires=i)
# ZZ coupling
for i in range(num_wires):
RZZ_decomposed(-Jz * dt, wires=[i, (i + 1) % num_wires], p=p)
# YY coupling
for i in range(num_wires):
RYY_decomposed(-Jy * dt, wires=[i, (i + 1) % num_wires], p=p)
# XX coupling
for i in range(num_wires):
RXX_decomposed(-Jx * dt, wires=[i, (i + 1) % num_wires], p=p)
# Apply Trotter steps
for _ in range(depth):
heisenberg_step()
return qml.state()
Hi @Andrea_Delgado, it’s great to see you here!
You are indeed close but there’s still some work to do. Check your decompositions for RXX and RYY as well as your heisenberg step. For RXX for example take a look at PennyLane’s IsingXX decomposition. I hope this helps!