Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Semiclassical Fourier Transform #688

Closed
wants to merge 38 commits into from

Conversation

gillenhaalb
Copy link

Summary

Added option to make Quantum Fourier Transform "semiclassical" when it directly precedes measurement. This replaces two-qubit control gates with measurement and classical control, greatly reducing noise (see notebook attached for noise reduction demo).

Details and comments

  • Creates own measurement register.
  • Default arg is False, users must opt in manually.
  • Currently only for not inverse, not do_swaps, and approximation_degree = 0.

SemiclassFTdemo.zip

* only when opted in by user; when directly precedes measurement
* currently only for not inverse, not do_swaps, and no approximation
@CLAassistant
Copy link

CLAassistant commented Sep 23, 2019

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@woodsp-ibm
Copy link
Member

First apologies for delay in response. Would you have any reference material or paper that explains this? If not can you supply any additional documentation within the code that explains this technique further?
It would be nice to have a unit test that ensures this is functioning as expected. Also the notebook you have in the zip that would be great to have that in the aqua section of community tutorials to showcase this capability here https://github.com/Qiskit/qiskit-community-tutorials/tree/master/aqua

@gillenhaalb
Copy link
Author

@woodsp-ibm No worries whatsoever! I completely forgot to link to the papers in the initial PR message:

Additionally, I found time to work out the inverse, and just committed that (along with a similar demo notebook, attached below). This should be just as useful because a good number of classic algorithms end with inverse QFT + measurement (e.g. phase estimation).

I absolutely agree, both a unit test and a showcase tutorial would be very beneficial. Unfortunately I'm extremely pressed for time at the moment, so it might be a little while before I can get them together.

InverseSemiclassFTdemo.zip

Copy link
Contributor

@Cryoris Cryoris left a comment

Choose a reason for hiding this comment

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

Hi @gillenhaalb, very nice addition to the Fourier transform!
It would be great to have at least one (ideally a few) tests for your modification, to check that it doesn't break anything. E.g. you could test an algorithm that uses Fourier transformation preceding measurements (such as AmplitudeEstimation), or compare the transform to the "usual" Fourier transform before a measurement.
Let me know if you need help with these tests!

circuit.u1(lam, j + (k + 1)).c_if(circuit.cregs[j], 1)
return circuit
else:
inv_qubit_range = range(len(qubits) - 1, -1, -1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is inv_qubit_range necessary? It's equal to qubit_range, which is defined above (in line 94).

else:
inv_qubit_range = range(len(qubits) - 1, -1, -1)
for _ in inv_qubit_range:
circuit.add_register(ClassicalRegister(1))
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't need a for loop, just write circuit.add_register(ClassicalRegister(len(qubits))).

if precedes_measurement and not do_swaps and approximation_degree == 0:
if not inverse:
for j in qubit_range:
circuit.add_register(ClassicalRegister(1))
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider taking this outside the for loop for simplicity. Since this register is both needed for the inverse and normal QFT, you can also take this outside the if statement, i.e. before if not inverse you could put circuit.add_register(ClassicalRegister(len(qubits))).

circuit.measure(j, j)
for qubit in neighbor_range:
k = j - qubit
lam = - np.pi / float(2 ** (k))
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need a conversion to float here (and also no extra-brackets around k)

circuit.h(j)
circuit.measure(j, j)
for k in neighbor_range:
lam = 1.0 * np.pi / float(2 ** (k + 1))
Copy link
Contributor

@Cryoris Cryoris Jan 28, 2020

Choose a reason for hiding this comment

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

You don't need to multiply with 1.0, nor a conversion to float here. Python 3 works does float arithmetics anyways (and on top you already use the float number np.pi).

@gillenhaalb
Copy link
Author

@Cryoris Thanks for the review and comments! I totally agree, more unit tests (and some code tidying) are absolutely necessary before merging. Unfortunately we're in the middle of exam season at the moment, so I won't be able to put in more work on those for a while. However, I was thinking I would ultimately do phase estimation for the "algorithm test". In the meantime, you can check out the two zip files in my above comments (if you didn't already see them), which contain Jupyter Notebook demos comparing the semiclassical to the "usual" QFT.

@Cryoris
Copy link
Contributor

Cryoris commented Mar 24, 2020

Maybe this could also be added as transpiler pass, that checks whether a QFT directly precedes a measurement and then uses this version instead of the normal one. However this would probably require the "abstract" QFT block to be present up to transpilation such that it is easily identified.
@kdk What do you think?

@woodsp-ibm
Copy link
Member

@Cryoris Given that QFT circuit has been moved over to circuit library in Terra this PR no longer really applies to Aqua in its current form. Can we give some thought to progress this PR one way or another.

@Cryoris
Copy link
Contributor

Cryoris commented May 27, 2020

Yes, this should go to Terra. I think this would fit well into the circuit library, from there the transpiler could also grab it and replace the usual QFT with this one if applied before a measurement (once we start to implement this feature)

@woodsp-ibm
Copy link
Member

woodsp-ibm commented Sep 25, 2020

@Cryoris Is there some aspect of this that should be raised as a issue on Terra such that this functionality can be added there? Since QFTs are now part of circuit library in Terra this seems no longer relevant here and we should close it?

@woodsp-ibm
Copy link
Member

As the QFTs have been moved and refactored in Terra this is no longer valid here, so as such I am closing it.

@woodsp-ibm woodsp-ibm closed this Jan 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants