I am not able to find the correct RX and RZ operators for this qubit. For Y I have used the decomposition Y = S \ RX(-\pi) \ S^{\dagger}
Hey @AvanishM! Super close! The first two operators are correct. You should only need 4 gates. We know from the previous exercise that the Hadamard gate is:
phi, theta, omega = np.pi/2, np.pi/2, np.pi/2
@qml.qnode(dev)
def hadamard_with_rz_rx():
qml.RZ(phi, wires=0)
qml.RX(theta, wires=0)
qml.RZ(omega, wires=0)
I would do the same exercise for S, T^\dagger, and Y individually and then put it all together! Let me know if this helps.
Hello @isaacdevlugt ! Thank you for the response. Here are my decompositions for S, T^{\dagger}, Y. Let me know where I am going wrong
def S_with_rz_rx():
qml.RZ(np.pi/2, wires=0)
def adj_T_with_rz_rx():
qml.RZ(-np.pi/4, wires=0)
def Y_with_rz_rx():
qml.RZ(np.pi/2, wires=0) # S
qml.RX(-np.pi, wires=0)
qml.RZ(-np.pi/2, wires=0) # adj S
where I have used the fact Y = RY(\pi) = S \ RX(-\pi) \ S^{\dagger}. Collating these into one function:
def convert_to_rz_rx():
qml.RZ(np.pi/2, wires=0)
qml.RX(np.pi/2, wires=0)
qml.RZ(np.pi/2 + np.pi/2 - np.pi/4 + np.pi/2, wires=0)
qml.RX(-np.pi, wires=0)
qml.RZ(-np.pi/2, wires=0)
Close! I can give you the answer here, but definitely try and understand why this is the case:
qml.RZ(np.pi / 2, wires=0)
qml.RX(np.pi / 2, wires=0)
qml.RZ(7 * np.pi / 4, wires=0)
qml.RX(np.pi, wires=0)
Another thing to note here as well is that you can try to check each operation by doing something like this:
@qml.qnode(dev)
def my_op_with_rx_rz():
qml.RZ(np.pi/2, wires=0) # your proposed S gate
qml.adjoint(qml.S(wires=0)) # the adjoint of S should "undo" the previous operation
return qml.probs(wires=0) # resulting state should just be |0>, or [1, 0] as an array
Hope this helps!
Thank you @isaacdevlugt for your assistance! I understand how you arrived at that answer, using the decomposition Y= Z \ RX(\pi)
I have also tried your hint to see why my code was failing, and I got some insight by running:
@qml.qnode(dev)
def my_op_with_rx_rz():
qml.RZ(np.pi/2, wires=0)
qml.RX(-np.pi, wires=0)
qml.RZ(-np.pi/2, wires=0) # my different decomposition of Y
qml.adjoint(qml.PauliY(wires=0)) # adjoint of Y
return qml.probs(wires=0)
Instead of getting [1,0] I got [1, 3e-33]. So is it right to conclude my method was correct but was less efficient and thus introduced some machine error?
3e-33
is very small . That shouldn’t be causing a problem.
Hm, if that’s the case then my function for the Y operator should be correct, and I’m still not sure why my circuit was incorrect.
I found the reason my old circuit was incorrect, coming from a core ordering mistake
I forgot to reverse the ordering of the matrix multiplication when building the circuit so my old function:
def Y_with_rz_rx():
qml.RZ(np.pi/2, wires=0) # S
qml.RX(-np.pi, wires=0)
qml.RZ(-np.pi/2, wires=0) # adj S
should actually be:
def Y_with_rz_rx():
qml.RZ(-np.pi/2, wires=0) # adj S
qml.RX(-np.pi, wires=0)
qml.RZ(np.pi/2, wires=0) # S
# this collated function now works
def convert_to_rz_rx():
qml.RZ(np.pi/2, wires=0)
qml.RX(np.pi/2, wires=0)
qml.RZ(np.pi/2 + np.pi/2 - np.pi/4 - np.pi/2, wires=0)
qml.RX(-np.pi, wires=0)
qml.RZ(np.pi/2, wires=0)
However, there is still one thing I’m thinking about. When I implemented the circuit in the wrong order and and called the adjoint, the resulting state was still \vert 0 \rangle, so would this also be a valid decomposition? I’m guessing up to a global phase.
Ah! Nice catch .
When I implemented the circuit in the wrong order and and called the adjoint, the resulting state was still …
If I’m understanding your statement correctly, if you apply any unitary operator and then apply its adjoint, the result will be as if you did nothing . No global phases, even!