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

Adds the quantum fourier transform and controlled phase operations #1064

Merged
merged 25 commits into from
Feb 5, 2021

Conversation

trbromley
Copy link
Contributor

@trbromley trbromley commented Feb 3, 2021

Context:

Adds two new gates:

  • QFT
  • ControlledPhaseShift (which is required in the decomposition of QFT)

Description of the Change:

These two gates have been added as operations in pennylane/ops/qubit.py. Both have a defined decomposition and matrix representation. Also added these gates to the supported operations in default.* devices.

Possible Drawbacks:

We use the ControlledPhaseShift which looks similar to the CV gate ControlledPhase. However, the first sentence of the ControlledPhaseShift docstring reads "A qubit controlled phase shift." to hopefully remove some confusion.

@trbromley trbromley self-assigned this Feb 3, 2021
@codecov
Copy link

codecov bot commented Feb 3, 2021

Codecov Report

Merging #1064 (e8afca8) into master (ac85314) will decrease coverage by 0.00%.
The diff coverage is 97.01%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1064      +/-   ##
==========================================
- Coverage   97.75%   97.74%   -0.01%     
==========================================
  Files         153      153              
  Lines       11517    11579      +62     
==========================================
+ Hits        11258    11318      +60     
- Misses        259      261       +2     
Impacted Files Coverage Δ
pennylane/devices/default_mixed.py 100.00% <ø> (ø)
pennylane/devices/default_qubit.py 100.00% <ø> (ø)
pennylane/devices/default_qubit_autograd.py 100.00% <ø> (ø)
pennylane/devices/default_qubit_jax.py 93.75% <ø> (ø)
pennylane/devices/default_qubit_tf.py 90.14% <ø> (ø)
pennylane/devices/autograd_ops.py 97.61% <50.00%> (-2.39%) ⬇️
pennylane/devices/jax_ops.py 95.12% <50.00%> (-2.32%) ⬇️
pennylane/devices/tf_ops.py 100.00% <100.00%> (ø)
pennylane/ops/qubit.py 97.35% <100.00%> (+0.26%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ac85314...2566d52. Read the comment docs.

Comment on lines 26 to 31
from pennylane.operation import (AnyWires, DiagonalOperation, Observable,
Operation)
from pennylane.templates import template
from pennylane.templates.state_preparations import (BasisStatePreparation,
MottonenStatePreparation)
from pennylane.utils import expand, pauli_eigs
Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I ran isort)

@trbromley trbromley changed the title Adds the quantum fourier transform operation Adds the quantum fourier transform and controlled phase operations Feb 4, 2021
@trbromley trbromley marked this pull request as ready for review February 4, 2021 14:30
@trbromley
Copy link
Contributor Author

trbromley commented Feb 4, 2021

image
^ Not sure why the tests are failing 😕 It shows it passing in the last commit.

@trbromley trbromley added the review-ready 👌 PRs which are ready for review by someone from the core team. label Feb 4, 2021
.github/CHANGELOG.md Outdated Show resolved Hide resolved
pennylane/ops/qubit.py Show resolved Hide resolved
Comment on lines +1687 to +1688
def decomposition(wires):
num_wires = len(wires)
Copy link
Contributor

Choose a reason for hiding this comment

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

When running the QFT, is there a way to make it print out the full decomposition when using draw? Currently it draws this:

 0: ──╭QFT──╭┤ State 
 1: ──├QFT──├┤ State 
 2: ──╰QFT──╰┤ State 

but for the sake of testing it'd be convenient to see the innards.

Copy link
Member

@josh146 josh146 Feb 4, 2021

Choose a reason for hiding this comment

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

This could be the moment that our new qml.draw() shines!

Since it is not dependent on the QNode state (unlike qnode.draw()), we can add some logic to qml.draw() to always decompose the QFT operation (or maybe any operation that has a draw_decomp flag or something).

Copy link
Contributor

@glassnotes glassnotes Feb 4, 2021

Choose a reason for hiding this comment

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

It'd be great to have it at the level of the draw function itself -

qml.draw(circuit, draw_decomp=True)

Copy link
Member

Choose a reason for hiding this comment

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

Or even

qml.draw(qnode, decompose=[“QFT”, “Rot”])(params)

pennylane/ops/qubit.py Show resolved Hide resolved
trbromley and others added 2 commits February 4, 2021 13:27
Co-authored-by: Olivia Di Matteo <2068515+glassnotes@users.noreply.github.com>

* Number of wires: 2
* Number of parameters: 1
* Gradient recipe: :math:`\frac{d}{d\phi}f(CR_\phi(\phi)) = \frac{1}{2}\left[f(CR_\phi(\phi+\pi/2)) - f(CR_\phi(\phi-\pi/2))\right]`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did check this and can confirm that it's unlike the other CRX, CRY, CRZ gates because the 2-parameter shift works:

import pennylane as qml
from pennylane import numpy as np

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

w1 = np.random.random((4, 2, 3))
w2 = np.random.random((4, 2, 3))

@qml.qnode(dev)
def f(x):
    qml.templates.StronglyEntanglingLayers(w1, wires=range(wires))
#     qml.CRX(x, wires=[0, 1])
    qml.ControlledPhaseShift(x, wires=[0, 1])
    qml.templates.StronglyEntanglingLayers(w2, wires=range(wires))
    return qml.expval(qml.PauliZ(0))

x = 0.3
g1 = qml.grad(f)(x)
g2 = (f(x + np.pi / 2) - f(x - np.pi / 2)) / 2

np.allclose(g1, g2)

Copy link
Member

@josh146 josh146 left a comment

Choose a reason for hiding this comment

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

👍 for remembering to update the JAX, Autograd, and TF devices!

With qml.math, we should be able to merge jax_ops, autograd_ops, tf_ops, etc.

pennylane/ops/qubit.py Show resolved Hide resolved
Copy link
Contributor

@glassnotes glassnotes left a comment

Choose a reason for hiding this comment

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

Thanks @trbromley, really excited to have QFT available 😁

@trbromley
Copy link
Contributor Author

This should be good to merge, I did a local coverage run and coverage looks good - the only bit I'm unsure about is incomplete coverage on pennylane/devices/jax_ops.py and autograd_ops.py. I'm not seeing these covered locally, but my understanding is that coverage would come from the device test suite (?) - where there are tests for ControlledPhaseShift.

@josh146 josh146 merged commit 75fe544 into master Feb 5, 2021
@josh146 josh146 deleted the add_qft branch February 5, 2021 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review-ready 👌 PRs which are ready for review by someone from the core team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants