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 default.qubit.autograd qubit simulator for use with the PassthruQNode #721

Merged
merged 30 commits into from Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3634948
Adds default.qubit.autograd qubit simulator for use with the Passthru…
josh146 Jul 27, 2020
b1d7e29
update changelog
josh146 Jul 27, 2020
2e151a2
update changelog
josh146 Jul 27, 2020
caddf4e
fix docstring
josh146 Jul 27, 2020
14dc588
Apply suggestions from code review
josh146 Jul 28, 2020
e96bf75
suggested changes
josh146 Jul 28, 2020
d0878c4
Merge branch 'passthru-qubit' of github.com:XanaduAI/pennylane into p…
josh146 Jul 28, 2020
4debac4
suggested changes
josh146 Jul 28, 2020
a056726
fix tests
josh146 Jul 28, 2020
1a2a9e6
merge master
josh146 Jul 29, 2020
6c05260
add flaky
josh146 Jul 29, 2020
e97ab7e
redundancy
josh146 Jul 29, 2020
fbe5d5a
redundancy
josh146 Jul 29, 2020
b696e4c
update changelog:
josh146 Jul 29, 2020
f73bf70
increase coverage
josh146 Jul 29, 2020
73ada6e
increase coverage
josh146 Jul 29, 2020
456934c
remove print statement
josh146 Jul 29, 2020
1b5b0ba
upgrade
josh146 Jul 29, 2020
e1f33cb
Merge branch 'master' into passthru-qubit
josh146 Jul 29, 2020
b3e1dd5
Merge branch 'master' into passthru-qubit
josh146 Jul 29, 2020
71ad705
upgrade
josh146 Jul 29, 2020
f4ef519
Merge branch 'passthru-qubit' of github.com:PennyLaneAI/pennylane int…
josh146 Jul 29, 2020
5246446
upgrade
josh146 Jul 29, 2020
484b1ad
fix
josh146 Jul 30, 2020
f52dca4
Merge branch 'master' into passthru-qubit
josh146 Jul 30, 2020
f241256
fix
josh146 Jul 30, 2020
d353dbf
increase coverage
josh146 Jul 30, 2020
6f4f2ea
fix test
josh146 Jul 30, 2020
dc70cac
remove device tests
josh146 Jul 30, 2020
a2ff021
more
josh146 Jul 30, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 26 additions & 1 deletion .github/CHANGELOG.md
Expand Up @@ -24,6 +24,31 @@
If the tests are run on external devices, the device and its dependencies must be
installed locally.

* Added a new device, `default.qubit.autograd`, a pure-state qubit simulator written using Autograd.
As a result, it supports classical backpropagation as a means to compute the Jacobian. This can
be faster than the parameter-shift rule for computing quantum gradients
when the number of parameters to be optimized is large.
[(#721)](https://github.com/XanaduAI/pennylane/pull/721)

`default.qubit.autograd` is designed to be used with end-to-end classical backpropagation
(`diff_method="backprop"`) with the Autograd interface. This is the default method
of differentiation when creating a QNode with this device.

```pycon
>>> dev = qml.device("default.qubit.autograd", wires=1)
>>> @qml.qnode(dev, diff_method="backprop")
... def circuit(x):
... qml.RX(x[1], wires=0)
... qml.Rot(x[0], x[1], x[2], wires=0)
... return qml.expval(qml.PauliZ(0))
>>> weights = np.array([0.2, 0.5, 0.1])
>>> grad_fn = qml.grad(circuit)
>>> print(grad_fn(weights))
array([-2.25267173e-01, -1.00864546e+00, 6.93889390e-18])
```

See the `default.qubit.autograd` documentation for more details.

* Added the `decompose_hamiltonian` method to the `utils` module. The method can be used to
decompose a Hamiltonian into a linear combination of Pauli operators.
[(#671)](https://github.com/XanaduAI/pennylane/pull/671)
Expand Down Expand Up @@ -59,7 +84,7 @@

This release contains contributions from (in alphabetical order):

Josh Izaac, Antal Száva, Nicola Vitucci
Josh Izaac, Maria Schuld, Antal Száva, Nicola Vitucci

# Release 0.10.0 (current release)

Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -37,7 +37,7 @@ env:
- LOGGING=info
install:
- pip install -r requirements.txt
- pip install wheel pytest pytest-cov pytest-mock absl-py --upgrade
- pip install wheel pytest pytest-cov pytest-mock flaky absl-py --upgrade
- if [ "$TF" = "2" ]; then pip install tensorflow==2.2; fi
- if [ "$TF" = "1" ]; then pip install tensorflow==1.15; fi
- if [ "$TORCH" = "1" ]; then pip install torch==1.5.0+cpu torchvision==0.6.0+cpu -f https://download.pytorch.org/whl/torch_stable.html; fi
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Expand Up @@ -2,7 +2,8 @@ PYTHON3 := $(shell which python3 2>/dev/null)

PYTHON := python3
COVERAGE := --cov=pennylane --cov-report term-missing --cov-report=html:coverage_html_report
TESTRUNNER := -m pytest tests --tb=native
TESTRUNNER := -m pytest tests --tb=native --no-flaky-report
PLUGIN_TESTRUNNER := -m pytest pennylane/plugins/tests --tb=native --no-flaky-report

.PHONY: help
help:
Expand Down Expand Up @@ -56,7 +57,9 @@ clean-docs:

test:
$(PYTHON) $(TESTRUNNER)
$(PYTHON) $(PLUGIN_TESTRUNNER) --device=default.qubit.autograd

coverage:
@echo "Generating coverage report..."
$(PYTHON) $(TESTRUNNER) $(COVERAGE)
$(PYTHON) $(PLUGIN_TESTRUNNER) --device=default.qubit.autograd $(COVERAGE) --cov-append
Copy link
Member Author

Choose a reason for hiding this comment

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

❤️
We should begin deleting all the repeated device integration tests, and just add lines to the makefile here

2 changes: 2 additions & 0 deletions pennylane/plugins/__init__.py
Expand Up @@ -23,8 +23,10 @@

default_qubit
default_qubit_tf
default_qubit_autograd
default_gaussian
tf_ops
autograd_ops
"""
from .default_qubit import DefaultQubit
from .default_gaussian import DefaultGaussian
157 changes: 157 additions & 0 deletions pennylane/plugins/autograd_ops.py
@@ -0,0 +1,157 @@
# Copyright 2018-2020 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
r"""
Utility functions and numerical implementations of quantum operations for Autograd-based devices.
"""
from autograd import numpy as np
from numpy import kron
co9olguy marked this conversation as resolved.
Show resolved Hide resolved

C_DTYPE = np.complex128
R_DTYPE = np.float64

I = np.array([[1, 0], [0, 1]], dtype=C_DTYPE)
X = np.array([[0, 1], [1, 0]], dtype=C_DTYPE)
Y = np.array([[0j, -1j], [1j, 0j]], dtype=C_DTYPE)
Z = np.array([[1, 0], [0, -1]], dtype=C_DTYPE)

II = np.eye(4, dtype=C_DTYPE)
ZZ = np.array(kron(Z, Z), dtype=C_DTYPE)

IX = np.array(kron(I, X), dtype=C_DTYPE)
IY = np.array(kron(I, Y), dtype=C_DTYPE)
IZ = np.array(kron(I, Z), dtype=C_DTYPE)

ZI = np.array(kron(Z, I), dtype=C_DTYPE)
ZX = np.array(kron(Z, X), dtype=C_DTYPE)
ZY = np.array(kron(Z, Y), dtype=C_DTYPE)


def PhaseShift(phi):
r"""One-qubit phase shift.

Args:
phi (float): phase shift angle

Returns:
array[complex]: diagonal part of the phase shift matrix
"""
return np.array([1.0, np.exp(1j * phi)])


def RX(theta):
r"""One-qubit rotation about the x axis.

Args:
theta (float): rotation angle

Returns:
array[complex]: unitary 2x2 rotation matrix :math:`e^{-i \sigma_x \theta/2}`
"""
return np.cos(theta / 2) * I + 1j * np.sin(-theta / 2) * X


def RY(theta):
r"""One-qubit rotation about the y axis.

Args:
theta (float): rotation angle

Returns:
array[complex]: unitary 2x2 rotation matrix :math:`e^{-i \sigma_y \theta/2}`
"""
return np.cos(theta / 2) * I + 1j * np.sin(-theta / 2) * Y


def RZ(theta):
r"""One-qubit rotation about the z axis.

Args:
theta (float): rotation angle

Returns:
array[complex]: the diagonal part of the rotation matrix :math:`e^{-i \sigma_z \theta/2}`
"""
p = np.exp(-0.5j * theta)
return np.array([p, np.conj(p)])


def Rot(a, b, c):
r"""Arbitrary one-qubit rotation using three Euler angles.

Args:
a,b,c (float): rotation angles

Returns:
array[complex]: unitary 2x2 rotation matrix ``rz(c) @ ry(b) @ rz(a)``
"""
return np.diag(RZ(c)) @ RY(b) @ np.diag(RZ(a))


def CRX(theta):
r"""Two-qubit controlled rotation about the x axis.

Args:
theta (float): rotation angle

Returns:
array[complex]: unitary 4x4 rotation matrix
:math:`|0\rangle\langle 0|\otimes \mathbb{I}+|1\rangle\langle 1|\otimes R_x(\theta)`
"""
return (
np.cos(theta / 4) ** 2 * II
- 1j * np.sin(theta / 2) / 2 * IX
+ np.sin(theta / 4) ** 2 * ZI
+ 1j * np.sin(theta / 2) / 2 * ZX
)


def CRY(theta):
r"""Two-qubit controlled rotation about the y axis.

Args:
theta (float): rotation angle
Returns:
array[complex]: unitary 4x4 rotation matrix :math:`|0\rangle\langle 0|\otimes \mathbb{I}+|1\rangle\langle 1|\otimes R_y(\theta)`
"""
return (
np.cos(theta / 4) ** 2 * II
- 1j * np.sin(theta / 2) / 2 * IY
+ np.sin(theta / 4) ** 2 * ZI
+ 1j * np.sin(theta / 2) / 2 * ZY
)


def CRZ(theta):
r"""Two-qubit controlled rotation about the z axis.

Args:
theta (float): rotation angle
Returns:
array[complex]: diagonal part of the 4x4 rotation matrix
:math:`|0\rangle\langle 0|\otimes \mathbb{I}+|1\rangle\langle 1|\otimes R_z(\theta)`
"""
p = np.exp(-0.5j * theta)
return np.array([1.0, 1.0, p, np.conj(p)])


def CRot(a, b, c):
r"""Arbitrary two-qubit controlled rotation using three Euler angles.

Args:
a,b,c (float): rotation angles
Returns:
array[complex]: unitary 4x4 rotation matrix
:math:`|0\rangle\langle 0|\otimes \mathbb{I}+|1\rangle\langle 1|\otimes R(a,b,c)`
"""
return np.diag(CRZ(c)) @ (CRY(b) @ np.diag(CRZ(a)))