Skip to content

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.

Comment on lines +304 to +307
"# 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.

Copy link
Author

Choose a reason for hiding this comment

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

This would be great!

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
"# controlled_unitary = Circuit().z(0)\n",
"# ht_circuit = hadamard_test_circuit(controlled_unitary)\n",
"# controlled_unitary = Circuit().z(0)\n",
"# ht_circuit = hadamard_test_circuit(Qubit(0), controlled_unitary)\n",

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?

Copy link
Author

Choose a reason for hiding this comment

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

Yep, great call-out

Comment on lines +31 to +34
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.

Copy link
Author

Choose a reason for hiding this comment

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

It looks like standard in this package is not to mock but use .isclose(). Happy to do the mocking, or I can run some further tests / loosen the bounds to ensure we are probabilistically safe "enough".

@blolt blolt force-pushed the add-hadamard-test branch from 813a05d to 181aa75 Compare February 1, 2025 15:54
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.

The notebook doesn't seem to use the updated hadamard_test_circuit with an ancilla qubit. It only shows a control unitary as the argument.

@blolt blolt force-pushed the add-hadamard-test branch from 181aa75 to 910819d Compare February 21, 2025 03:54
"source": [
"## Run on a QPU \n",
"\n",
"To run the Hadamard test on a QPU, we replace the LocalSimulator with an AwsDevice. The cost to run this experiment is $0.3 per task and $0.00145 per shot on the IQM Garnet device, that totals $1.75 USD. Because Garnet does not support arbitrary unitary operators, we will directly apply the Pauli-Z gate in this example."
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
"To run the Hadamard test on a QPU, we replace the LocalSimulator with an AwsDevice. The cost to run this experiment is $0.3 per task and $0.00145 per shot on the IQM Garnet device, that totals $1.75 USD. Because Garnet does not support arbitrary unitary operators, we will directly apply the Pauli-Z gate in this example."
"To run the Hadamard test on a QPU, we replace the LocalSimulator with an AwsDevice. The cost to run this experiment is \\\\$0.3 per task and \\\\$0.00145 per shot on the IQM Garnet device, which totals \\\\$1.75 USD. Because Garnet does not support arbitrary unitary operators, we will directly apply the Pauli-Z gate in this example."

@licedric
Copy link
Contributor

Unfortunately the cell to run on hardware doesn't work; it gives the error

ValidationException: An error occurred (ValidationException) when calling the CreateQuantumTask operation: [line 5] device arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet does not support GateModifer 'ctrl'

Hardware devices don't currently support the ctrl gate modifier (because the Braket SDK currently treats them as arbitrary unitaries). Is there something else we can do here?

"from notebook_plotting import plot_bitstrings_formatted\n",
"import numpy as np\n",
"\n",
"%matplotlib inline\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
"%matplotlib inline\n",

This shouldn't be needed for modern Jupyter versions.

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.

3 participants