Skip to content
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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

blolt
Copy link

@blolt blolt commented Jan 11, 2025

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

  • I have added tests that prove my fix is effective or that my feature works (if appropriate)
  • I have checked that my tests are not configured for a specific region or account (if appropriate)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@blolt blolt requested a review from a team as a code owner January 11, 2025 19:03
@blolt blolt mentioned this pull request Jan 11, 2025
5 tasks
Comment on lines +3 to +5
=======
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
Copy link
Author

@blolt blolt Jan 12, 2025

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.

Copy link
Contributor

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

@peterkomar-aws peterkomar-aws self-requested a review January 15, 2025 15:52
Copy link
Contributor

@mbeach-aws mbeach-aws left a 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."
Copy link
Contributor

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 ?

Copy link
Author

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."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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",

Comment on lines +122 to +123
"controlled_unitary = Circuit().unitary([0], np.array([[1, 0], [0, -1]]), \"U\")\n",
"print(controlled_unitary)"
Copy link
Contributor

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)

Comment on lines +281 to +282
"counts = task.result().measurement_counts\n",
"p_zero = counts.get('0', 0) / 1000\n",
Copy link
Contributor

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

Comment on lines +304 to +305
"# controlled_unitary = Circuit().z(0)\n",
"# ht_circuit = hadamard_test_circuit(controlled_unitary)\n",
Copy link
Contributor

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.

Comment on lines +3 to +5
=======
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
Copy link
Contributor

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

Comment on lines +34 to +48
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)
Copy link
Contributor

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?

Comment on lines +31 to +32
device = LocalSimulator()
task = device.run(test_circuit, shots=10000)
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants