Problem in I.9.2 and I.9.3 of codebook

Hi everyone, I am not able to understand what these lines are doing in below code:

def y_basis_rotation():
    qml.Hadamard(wires=0)
    qml.S(wires=0)

Please explain me this logic?
This is problem I.9.2 from the codebook.

##################
# YOUR CODE HERE #
##################

# WRITE A QUANTUM FUNCTION THAT PREPARES (1/2)|0> + i(sqrt(3)/2)|1>
def prepare_psi():
    state = np.array([1/2, 1j*np.sqrt(3)/2])
    qml.MottonenStatePreparation(state_vector= state, wires=0)
    



# WRITE A QUANTUM FUNCTION THAT SENDS BOTH |0> TO |y_+> and |1> TO |y_->
def y_basis_rotation():
    qml.Hadamard(wires=0)
    qml.S(wires=0)

Also, I having problem in I.9.3. I am not sure why are we doing adjoint.

dev = qml.device("default.qubit", wires=1)

@qml.qnode(dev)
def measure_in_y_basis():
    ##################
    # YOUR CODE HERE #
    ##################
    
    # PREPARE THE STATE
    prepare_psi()

    # PERFORM THE ROTATION BACK TO COMPUTATIONAL BASIS
    qml.adjoint(qml.S)(wires=0)
    qml.adjoint(qml.Hadamard)(wires=0)

    # RETURN THE MEASUREMENT OUTCOME PROBABILITIES

    return qml.probs(wires=0) 

print(measure_in_y_basis())

It would be great if someone can explain me this and also its connection with the related theory in Section I.9

Hi @Manu_Chaudhary,

At the end of a quantum computation, we typically measure some physical observable relative to some basis (can sometimes be thought of as relative to some ‘orientation’ or axis). In many cases, these measurements are done in the computational basis, meaning relative to the |0 \rangle, |1 \rangle states.

For example, if we wanted to measure generic state |\psi \rangle in the computational basis, you can think of it as expressing |\psi \rangle as superposition of the computational basis states |\psi \rangle = c_{0} |0 \rangle + c_{1} |1 \rangle. Then doing a measurement on |\psi \rangle in the computational basis would yield the the state |0\rangle with probability |c_{0}|^{2} or it would yield the state |1\rangle with probability |c_{1}|^{2}.

In some cases, it is useful to do a measurement in a different basis. With our current example, that means you can also measure the state |\psi\rangle in a different basis, say the |y_{+}\rangle and |y_{+}\rangle states (which you should check/confirm form a basis). In that case, you can think of it as expressing |\psi \rangle as superposition of these new basis states |\psi \rangle = d_{0} |y_{+}\rangle + d_{1} |y_{-}\rangle. Your measurement would then be either the state |y_{+}\rangle with probability |d_{0}|^{2} or the state |y_{-}\rangle with probability |d_{1}|^{2}.

In the leadup to Codercise I.9.2, it tells you that to perform measurements in other bases, you need to rotate your states - this is what is shown in the Codebook in the case of rotating the Hadamard basis to the computational basis.

In the Codercise I.9.2, the y_basis rotation is performing the rotations needed to take the state |0 \rangle to the state |y_{+} \rangle as shown below:

y_basis_rotation_0_to_y+

and the rotations needed to take the state |1 \rangle to the state |y_{-} \rangle (I’ll let you draw the rotations for that one).

In Codercise I.9.3, you are taking the adjoint because you need to do the reverse rotation (take the state from the |y_{+} \rangle, |y_{-} \rangle basis states back to the |0 \rangle, |1\rangle states). I suggest you try to Exercise I.9.3 but for the |y_{+} \rangle, |y_{-} \rangle states instead of the Hadamard states and check that the numbers you get in Codercise I.9.3 match your calculations.

Hope that helps!

1 Like

Thank you @DanielNino27 for the great help.

You’re welcome - Glad I could help!

Thank you @DanielNino27.
What is Hadamard test? Somewhat it is related to expectation and mentioned at multiple places in pennylane documentation. Some small explanation on it will be great help.

Hi @Manu_Chaudhary,

Yes, the Hadamard test is a common subroutine that is used to estimate expectation values of unitary operators. There are a number of excellent online resources that give a detailed explanation of this. A resource that gives a good overview is section 6.2 of this pedagogical review article.

Often, the best way to understand these algorithms is to try to implement them yourself (in PennyLane for example :smiley: ), so I would encourage you to try it out for yourself with the review article linked above as a guide. The struggle of going through the details of these algorithms will pay off in the long run.

1 Like

Thank you @DanielNino27. I following all the techniques suggested by you.

1 Like

The logic makes sense. However, I am a bit puzzled on why the following does not work.
First we define
def y_basis_rotation():
qml.Hadamard(wires = 0)
qml.S(wires = 0)

Then, I was expecting the following to work
def measure_in_y_basis():
prepare_psi()
qml.adjoint(y_basis_rotation) # Same as adjoint of S, followed by adjoint of H
return qml.probs(wires = 0)

But it doesn’t!

Hi @ksuresh, Welcome to the forum!

You’re right that your method should work - I suspect the reason it doesn’t work for you is that you seem to have forgotten to specify that your y_basis_rotation function does not take an inputs when you use qml.adjoint.

You take a look at the documentation for qml.adjoint for an example of the format needed, but if you just add () after qml.adjoint(…), it should work.

Please let me know if that works!

As you explore PennyLane more @ksuresh, we have a PennyLane survey that you may be interested in if you would like to provide some feedback on your experience using PennyLane. We are always interested in collecting feedback from users on how we can keep improving PennyLane so that we can keep implementing great features.

You are absolutely correct! It worked with the inclusion of ().
Thanks for the quick response.

2 Likes

Hi, when turning z-basis into y-basis, I was thinking rotating respect to x-axis with -90 degrees. So intuitively, I tried qml.RX(-np.pi/2, wires=0) in I.9.2 codercise. I also understand the quickest way is to consider the unitary matrix SH=\frac{1}{\sqrt{2}}(|0\rangle+i|1\rangle)\langle0|+\frac{1}{\sqrt{2}}(|0\rangle-i|1\rangle)\langle1|.

However, in the explicit matrix form, SH\neq R_x(-\frac{\pi}{2})

I notice that R_x(-\frac{\pi}{2})|0\rangle=|y_+\rangle, but R_x(-\frac{\pi}{2})|1\rangle=i|y_-\rangle with an additional phase I. I feel like when thinking with Bloch sphere rotation, the additional phase is not sync, which makes me confusing which step I have missed.

So my first thought is it depends on how we choose to define states, if we have two orthonormal states |\alpha\rangle and |\beta\rangle. We can still redefine another set |\alpha\rangle and e^{i\phi}|\beta\rangle that are orthonormal.

Thanks in advance!

Hi @Yian_Chen ,

If I’ve understood your question correctly, it is true that the Bloch sphere picture can be misleading when it comes to global phases - they are not visible on the Bloch sphere which can lead to some confusion.

The problem you’re seeing might have to do with the fact that you are isolating the action of your rotation on each of the computational basis states |0 \rangle and |1 \rangle. This results in a global phase that wouldn’t matter for those states.

However, when you have a system in a superposition of |0 \rangle and |1 \rangle, what appeared as global phase for the case of isolating |0 \rangle and |1 \rangle now turns into a relative phase which might affect your measurement outcome as explained in the Codebook Node I.5.

Please let me know if that makes sense!

1 Like

Hi @DanielNino27 , thank you so much. Thanks for making the point out that the Bloch sphere picture can be misleading when it comes to global phases, now I understand the point I got stuck in. Merry Christmas!

2 Likes

I am having a misunderstanding on codexercise I.9.2. If I want to prepare the state |\psi> why can’t I use this function?
def prepare_psi():
qml.RX(-2*(np.pi)/3,wires=0)
return qml.state()

I have tried but it is not working.
And for the second function y_basis_rotation, I feel like the code is incomplete.
Doing,
def y_basis_rotation():
qml.Hadamard(wires=0)
qml.S(wires=0)
return qml.state()
just prepare the state |y_{+}>. What about |y_{-}> then? Why can’t we have another function to define it with qml.adjoint(qml.S(wires=0))?

Thanks in advance for the support.

Hi @baudoin, welcome to the forum!

Your method for preparing the state is correct, but the function prepare_psi() should not be returning anything. It is a subroutine that you will use in the next part of the Codercise to prepare your state. Similarly, for the y_basis_rotation function, you are just defining a subroutine that you will use in a complete circuit in the next part of the Codercise so it should not be returning anything.

The code for y_basis_rotation is complete as you give it. Keep in mind that y_basis rotation should take you to the state |y_{+}\rangle when you start from the |0\rangle state, and it should take you to the |y_{-}\rangle state when you start from the |1\rangle state - you can check that if you start from the |1\rangle state, your code does indeed take you to the |y_{-}\rangle state.

Hope that helps!

1 Like

Thank you @DanielNino27.

1 Like