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

Fix bug in single-qubit decomposition edge case. #1643

Merged
merged 11 commits into from
Sep 14, 2021

Conversation

glassnotes
Copy link
Contributor

Context: Development of #1552 uncovered an edge case in the zyz_decomposition function when the unitary being decomposed contains only off-diagonal elements.

Description of the Change: Fixes the bug, and adds new test cases. I also cleaned up a few parts of the tests so that fewer warnings are spit out by JAX.

Benefits: Fixes bug

Possible Drawbacks: None

Related GitHub Issues: None

@github-actions
Copy link
Contributor

Hello. You may have forgotten to update the changelog!
Please edit .github/CHANGELOG.md with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

assert qml.math.allclose(
[x.detach() for x in obtained_gates[0].parameters], expected_params
)
assert qml.math.allclose(qml.math.unwrap(obtained_gates[0].parameters), expected_params)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The original version caused errors when running locally, so I just tidied up a few things here.


@pytest.mark.parametrize("U,expected_gate,expected_params", single_qubit_decomps)
def test_zyz_decomposition_jax(self, U, expected_gate, expected_params):
"""Test that a one-qubit operation in JAX is correctly decomposed."""
jax = pytest.importorskip("jax")

# Enable float64 support
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Avoids warnings from JAX about precision.

@codecov
Copy link

codecov bot commented Sep 10, 2021

Codecov Report

❗ No coverage uploaded for pull request base (v0.18.0-rc0@c3d59e4). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@              Coverage Diff               @@
##             v0.18.0-rc0    #1643   +/-   ##
==============================================
  Coverage               ?   99.14%           
==============================================
  Files                  ?      196           
  Lines                  ?    14264           
  Branches               ?        0           
==============================================
  Hits                   ?    14142           
  Misses                 ?      122           
  Partials               ?        0           

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 c3d59e4...b541563. Read the comment docs.

antalszava and others added 2 commits September 11, 2021 22:33
…x` (#1629)

* deprecate qml.sample and shots=None for default.qubit.jax

* changelog

* formatting
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.

Thanks @glassnotes, nice catch!

@@ -16,6 +16,7 @@
"""
import pennylane as qml
from pennylane import math
from pennylane import numpy as np
Copy link
Member

Choose a reason for hiding this comment

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

Best to use standard NumPy here, since it is just being used for pi?

# If not diagonal, compute the angle of the RY
# Check if the matrix is off-diagonal. This means we can express it in terms
# of a single Z rotation and a Y rotation of -pi.
if math.allclose(U[0, 0], [0.0]):
Copy link
Member

Choose a reason for hiding this comment

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

Does this also imply that U[1, 1] = 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, since you can always write a unitary like this:

image

where a, b are complex numbers, so if a = 0 it must be that its real part is zero (since there's no way to set e^ix = 0), therefore U[1, 1] is 0 as well.

Copy link
Member

Choose a reason for hiding this comment

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

thanks @glassnotes!

Comment on lines 97 to 99
# Otherwise, we need to find the angle of the RZ. Note that we use -pi
# as the rotation angle for RY. This ensures the matrices constructed in
# PennyLane will match the original.
Copy link
Member

Choose a reason for hiding this comment

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

Oh, was the lack of this negative sign the cause of the bug?

# PennyLane will match the original.
theta = -np.pi
phi = 2 * math.angle(U[0, 1])
return [qml.Rot(phi, theta, 0.0, wires=wire)]
Copy link
Member

Choose a reason for hiding this comment

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

It strikes me that this is an if statement we wouldn't be able to get rid of for tracing, since it is required to avoid a bug

# Next set of gates are non-diagonal and decomposed as Rots
(H, qml.Rot, [np.pi, np.pi / 2, 0.0]),
(X, qml.Rot, [0.0, np.pi, np.pi]),
(X, qml.Rot, [0.0, -np.pi, -np.pi]),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a result of the new implementation.

assert isinstance(obtained_gates[0], expected_gate)
assert obtained_gates[0].wires == Wires("a")
assert qml.math.allclose(obtained_gates[0].parameters, expected_params)

if obtained_gates[0].num_params == 1:
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've added matrix equivalence checks to all the tests now... these should have been there from the start 🤦

@glassnotes
Copy link
Contributor Author

@josh146 I was trying to respond to your question about the negative sign, and found a way to streamline the implementation while looking into it. Once the CI runs do you mind taking a second look please?

@glassnotes
Copy link
Contributor Author

[ch8964]

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.

wow wasn't expecting such a simplification in logic!

Comment on lines +94 to +96
phi = 0.0
theta = -np.pi
omega = 1j * math.log(U[0, 1] / U[1, 0]) - np.pi
Copy link
Member

Choose a reason for hiding this comment

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

oh this is a massive improvement!

(H, qml.Rot, [np.pi, np.pi / 2, 0]),
(X, qml.Rot, [0.0, np.pi, np.pi]),
(X, qml.Rot, [0.0, -np.pi, -np.pi]),
Copy link
Member

Choose a reason for hiding this comment

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

Was this because the matrix equivalences were not being checked?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope this is just because now for the off-diagonal-only case, theta is by default set to -np.pi.

@glassnotes glassnotes changed the base branch from master to v0.18.0-rc0 September 14, 2021 11:53
@glassnotes glassnotes merged commit 0138960 into v0.18.0-rc0 Sep 14, 2021
@glassnotes glassnotes deleted the fix_zyz_decomposition branch September 14, 2021 12:18
josh146 added a commit that referenced this pull request Sep 14, 2021
* Fix bug in zyz decomposition and tidy tests.

* Update CHANGELOG.

* Tweak comments.

* Raise an error for `qml.sample` and `shots=None` in `default.qubit.jax` (#1629)

* deprecate qml.sample and shots=None for default.qubit.jax

* changelog

* formatting

* move shot adaptive test

* Streamline implementation and add matrix equivalence checks to tests.

* Update single qubit op tests.

Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
glassnotes added a commit that referenced this pull request Sep 14, 2021
* Fix bug in zyz decomposition and tidy tests.

* Update CHANGELOG.

* Tweak comments.

* Raise an error for `qml.sample` and `shots=None` in `default.qubit.jax` (#1629)

* deprecate qml.sample and shots=None for default.qubit.jax

* changelog

* formatting

* move shot adaptive test

* Streamline implementation and add matrix equivalence checks to tests.

* Update single qubit op tests.

Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>

Co-authored-by: Olivia Di Matteo <2068515+glassnotes@users.noreply.github.com>
Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
antalszava added a commit that referenced this pull request Sep 15, 2021
* remove newlines in docstring (#1647)

* Use numpy.

* Fix bug in single-qubit decomposition edge case. (#1643)

* Fix bug in zyz decomposition and tidy tests.

* Update CHANGELOG.

* Tweak comments.

* Raise an error for `qml.sample` and `shots=None` in `default.qubit.jax` (#1629)

* deprecate qml.sample and shots=None for default.qubit.jax

* changelog

* formatting

* move shot adaptive test

* Streamline implementation and add matrix equivalence checks to tests.

* Update single qubit op tests.

Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>

* Separate torch case.

* Update pennylane/devices/default_qubit.py

* Fix bug when using Jax jit and `QubitStateVector` (#1649)

* Use numpy.

* Separate torch case.

* Update pennylane/devices/default_qubit.py

Co-authored-by: antalszava <antalszava@gmail.com>

Co-authored-by: Theodor <theodor@xanadu.ai>
Co-authored-by: Romain Moyard <rmoyard@gmail.com>
Co-authored-by: Olivia Di Matteo <2068515+glassnotes@users.noreply.github.com>
Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
josh146 added a commit that referenced this pull request Sep 20, 2021
* remove newlines in docstring (#1647)

* Fix bug in single-qubit decomposition edge case. (#1643)

* Fix bug in zyz decomposition and tidy tests.

* Update CHANGELOG.

* Tweak comments.

* Raise an error for `qml.sample` and `shots=None` in `default.qubit.jax` (#1629)

* deprecate qml.sample and shots=None for default.qubit.jax

* changelog

* formatting

* move shot adaptive test

* Streamline implementation and add matrix equivalence checks to tests.

* Update single qubit op tests.

Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>

* Fix bug when using Jax jit and `QubitStateVector` (#1649)

* Use numpy.

* Separate torch case.

* Update pennylane/devices/default_qubit.py

Co-authored-by: antalszava <antalszava@gmail.com>

* Matplotlib circuit drawing (#1484)

* Raise a `UserWarning` for a list of shots in `Device.execute` (#1659)

* add warning for shot list in pure Device based devices; test for default.gaussian

* changelog

* PR number

* formatting

* comment

* Update pennylane/_device.py

Co-authored-by: Theodor <theodor@xanadu.ai>

* test message

Co-authored-by: Theodor <theodor@xanadu.ai>

* bugfix: raise mpl import error inside class initialization (#1667)

* mpldrawer when mpl not installed

* black

* bugfix for device shot list processing (#1666)

* fix process shots bug

* add tests and changelog

* docstrings and black

* add frob to list (#1664)

* Small change example. (#1669)

* Adds PennyLane-Lightning as a dependency (#1663)

* Add pl-lightning to requirements.txt and setup.py

* Add to requirements-ci.txt

* Temporarily add pybind11

* Update setup.py

* Add setup.py

* Add to changelog

* update changelog

* Update changelog

* Remove from requirements

* Does this fix?

* Revert

* New version

* Add diff method

* Add pennylane lightning pypi dep

* Update changelog

* Add simple test

* Remove adjoint

* Pin minimum version of lightning

* Emphasize as lightning.qubit

* Link to PL-Lightning release notes

* Update .github/CHANGELOG.md

* Update changelog

Co-authored-by: Lee J. O'Riordan <loriordan@gmail.com>

* tests/transforms/test_optimization/utils.py from rc

* tests/transforms/test_decompositions.py from rc

* Add shorter drawer example for the notes

* Add Hamiltonian expval(H) plot

* transforms test files

* updated example image

Co-authored-by: Theodor <theodor@xanadu.ai>
Co-authored-by: Olivia Di Matteo <2068515+glassnotes@users.noreply.github.com>
Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Romain <rmoyard@gmail.com>
Co-authored-by: Christina Lee <christina@xanadu.ai>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Lee J. O'Riordan <loriordan@gmail.com>
antalszava added a commit that referenced this pull request Sep 21, 2021
* remove newlines in docstring (#1647)

* Fix bug in single-qubit decomposition edge case. (#1643)

* Fix bug in zyz decomposition and tidy tests.

* Update CHANGELOG.

* Tweak comments.

* Raise an error for `qml.sample` and `shots=None` in `default.qubit.jax` (#1629)

* deprecate qml.sample and shots=None for default.qubit.jax

* changelog

* formatting

* move shot adaptive test

* Streamline implementation and add matrix equivalence checks to tests.

* Update single qubit op tests.

Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>

* Fix bug when using Jax jit and `QubitStateVector` (#1649)

* Use numpy.

* Separate torch case.

* Update pennylane/devices/default_qubit.py

Co-authored-by: antalszava <antalszava@gmail.com>

* Matplotlib circuit drawing (#1484)

* Raise a `UserWarning` for a list of shots in `Device.execute` (#1659)

* add warning for shot list in pure Device based devices; test for default.gaussian

* changelog

* PR number

* formatting

* comment

* Update pennylane/_device.py

Co-authored-by: Theodor <theodor@xanadu.ai>

* test message

Co-authored-by: Theodor <theodor@xanadu.ai>

* bugfix: raise mpl import error inside class initialization (#1667)

* mpldrawer when mpl not installed

* black

* bugfix for device shot list processing (#1666)

* fix process shots bug

* add tests and changelog

* docstrings and black

* add frob to list (#1664)

* Small change example. (#1669)

* Adds PennyLane-Lightning as a dependency (#1663)

* Add pl-lightning to requirements.txt and setup.py

* Add to requirements-ci.txt

* Temporarily add pybind11

* Update setup.py

* Add setup.py

* Add to changelog

* update changelog

* Update changelog

* Remove from requirements

* Does this fix?

* Revert

* New version

* Add diff method

* Add pennylane lightning pypi dep

* Update changelog

* Add simple test

* Remove adjoint

* Pin minimum version of lightning

* Emphasize as lightning.qubit

* Link to PL-Lightning release notes

* Update .github/CHANGELOG.md

* Update changelog

Co-authored-by: Lee J. O'Riordan <loriordan@gmail.com>

* Adjust Torch and TF backprop docstrings (#1662)

* error

* adjust TF docstring

* Diff option backprop check rc (#1658)

* update the condition for backprop diff

* add test and readjust the other test

* formatting

* diff_method='parameter-shift' for default.tensor.tf

* format tests

* Update pennylane/qnode.py

Co-authored-by: Romain <rmoyard@gmail.com>

Co-authored-by: Romain <rmoyard@gmail.com>

* V0.18.0 release notes (#1656)

* version bump

* group entries

* update the descriptions

* torch example

* contributors

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update .github/CHANGELOG.md

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* format lines

* num

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* move q transforms

* trainable coeffs

* SISWAP adjust

* Add link to changelog

* Fix merge

* SISWAP move to improvements

* drawer example

* remove item on separate requirements file

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* QFT move

* further suggestions

* NumPy

* draw example

* no grad call for finite_diff qml.gradients

* no grad call for param_shift

* lightning

* Update .github/CHANGELOG.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Hamiltonian + its plot

* Hamiltonian param shift move

* bug fix phrasing

* contributors list

* Lightning adjoint plot & description

* Hamiltonian plot width

* align mid

* Revert "align mid"

This reverts commit 9b8d354.

Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

Co-authored-by: Theodor <theodor@xanadu.ai>
Co-authored-by: Olivia Di Matteo <2068515+glassnotes@users.noreply.github.com>
Co-authored-by: Olivia Di Matteo <dimatteo.olivia@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Romain <rmoyard@gmail.com>
Co-authored-by: Christina Lee <christina@xanadu.ai>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Lee J. O'Riordan <loriordan@gmail.com>
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.

None yet

3 participants