-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Add Hadamard Test #158
base: main
Are you sure you want to change the base?
Conversation
======= | ||
The Hadamard test is a quantum circuit that allows estimation of the real and imaginary parts of the expected value of a unitary operator. It is a fundamental subroutine used in many quantum algorithms, including quantum phase estimation where it helps extract eigenvalue information through controlled operations. The test works by applying a controlled-unitary operation between an auxiliary qubit and the system of interest, with the measurement statistics of the auxiliary qubit encoding information about the unitary's expectation value. | ||
>>>>>>> Stashed changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noticed that these were not merged, miss by myself. Can update this in a following revision, pending comments from reviewers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, please address this also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was really excellent! Thanks for adding this functionality.
"source": [ | ||
"## Run on a local simulator\n", | ||
"\n", | ||
"Braket provides a method, `hadamard_test_circuit`, for estimating both the expected values of both the real and imaginary parts of a given unitary operator. Furthermore, methods for the extended Hadamard test are also provided (TODO: write the extended Hadamard test). We will first go through an example of the basic Hadamard test." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you address or remove this TODO ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch. I decided it made sense to address this in a follow-up issue, so I will remove the TODO.
"0 & -1\n", | ||
"\\end{bmatrix}\n", | ||
"$$\n", | ||
"Though braket has built-in support for the Pauli-Z gate, we will use the `unitary` method to apply the gate to the qubit. Consider playing around with different matrices to test your understanding of the algorithm." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Though braket has built-in support for the Pauli-Z gate, we will use the `unitary` method to apply the gate to the qubit. Consider playing around with different matrices to test your understanding of the algorithm." | |
"Though Braket has built-in support for the Pauli-Z gate, we will use the `unitary` method to apply the gate to the qubit. Consider playing around with different matrices to test your understanding of the algorithm." |
"$$\n", | ||
"\\dfrac{|0\\rangle |\\psi\\rangle + |1\\rangle U |\\psi\\rangle}{\\sqrt{2}} .\n", | ||
"$$ \n", | ||
"Then, a Hadamard gate is applied to the first qubit once more, giving state,\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Then, a Hadamard gate is applied to the first qubit once more, giving state,\n", | |
"Then, a Hadamard gate is applied to the first qubit once more, giving the state,\n", |
"source": [ | ||
"## Description\n", | ||
"\n", | ||
"Given a unitary operator $U$ and qubits $|0\\rangle|\\psi\\rangle$, the Hadamard test is used to estimate the expected value of $U$ on $|\\psi\\rangle$, i.e. $\\langle \\psi | U |\\psi \\rangle$. The algorithm is relatively straightforward, so we will walk through it step by step. First, we apply a Hadamard gate to $|0\\rangle$, putting the system into the state,\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Given a unitary operator $U$ and qubits $|0\\rangle|\\psi\\rangle$, the Hadamard test is used to estimate the expected value of $U$ on $|\\psi\\rangle$, i.e. $\\langle \\psi | U |\\psi \\rangle$. The algorithm is relatively straightforward, so we will walk through it step by step. First, we apply a Hadamard gate to $|0\\rangle$, putting the system into the state,\n", | |
"Given a unitary operator $U$ and qubits $|0\\rangle|\\psi\\rangle$, the Hadamard test is used to estimate the expected value of $U$ on $|\\psi\\rangle$, i.e. $\\langle \\psi | U |\\psi \\rangle$. We will walk through the algorithm step by step. First, we apply a Hadamard gate to $|0\\rangle$, putting the system into the state,\n", |
"controlled_unitary = Circuit().unitary([0], np.array([[1, 0], [0, -1]]), \"U\")\n", | ||
"print(controlled_unitary)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend defining the matrix in the line above for readability:
pauli_z = np.array([[1, 0], [0, -1]])
controlled_unitary = Circuit().unitary([0], pauli_z, "U")
print(controlled_unitary)
"counts = task.result().measurement_counts\n", | ||
"p_zero = counts.get('0', 0) / 1000\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, we could use measurement_probabilities
instead
"# controlled_unitary = Circuit().z(0)\n", | ||
"# ht_circuit = hadamard_test_circuit(controlled_unitary)\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can uncomment this and run on Garnet before we merge the PR if you want.
======= | ||
The Hadamard test is a quantum circuit that allows estimation of the real and imaginary parts of the expected value of a unitary operator. It is a fundamental subroutine used in many quantum algorithms, including quantum phase estimation where it helps extract eigenvalue information through controlled operations. The test works by applying a controlled-unitary operation between an auxiliary qubit and the system of interest, with the measurement statistics of the auxiliary qubit encoding information about the unitary's expectation value. | ||
>>>>>>> Stashed changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, please address this also
circ.h(0) | ||
if component == 'imaginary': | ||
circ.s(0).adjoint() | ||
|
||
# Add control qubit to the unitary circuit | ||
for inst in controlled_unitary.instructions: | ||
targets = [q + 1 for q in inst.target] | ||
controlled_inst = Instruction( | ||
operator=inst.operator, | ||
target=targets, | ||
control=0 | ||
) | ||
circ.add_instruction(controlled_inst) | ||
|
||
circ.h(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we generalize this to work on an ancilla qubit(s) q0
instead of hard-coded 0
?
device = LocalSimulator() | ||
task = device.run(test_circuit, shots=10000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could mock the results rather than running a true simulation during unit tests. Especially since the probabilistic nature of shots=10_000
and atol=0.1
.
This PR addresses issue #72.
Description of changes: This PR adds the Hadamard test to the library's implemented algorithms, with an optional flag that can be toggled for estimating either the real or imaginary part of the controlled unitary. An extension could be implementing the modified hadamard test, which could possibly make use of Amplitude amplification (Issue #100).
Testing done: Unit tests and notebook created.
Merge Checklist
Put an
x
in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your pull request.General
Tests
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.