diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md
index 0f0fd98ff7e..bf20be9d3b4 100644
--- a/.github/CHANGELOG.md
+++ b/.github/CHANGELOG.md
@@ -1,135 +1,99 @@
-# Release 0.9.0-dev (development release)
+# Release 0.9.0 (current release)
New features since last release
-* PennyLane now provides `DiagonalQubitUnitary` for diagonal gates, that are e.g.,
- encountered in IQP circuits. These kinds of gates can be evaluated much faster on
- a simulator device.
- [(#567)](https://github.com/XanaduAI/pennylane/pull/567)
-
- The gate can for example be used to efficiently simulate oracles:
-
- ```python
- dev = qml.device('default.qubit', wires=3)
+New machine learning integrations
- # Function as a bitstring
- f = np.array([1, 0, 0, 1, 1, 0, 1, 0])
-
- @qml.qnode(dev)
- def circuit(weights1, weights2):
- qml.templates.StronglyEntanglingLayers(weights1, wires=[0, 1, 2])
-
- # Implements the function as a phase-kickback oracle
- qml.DiagonalQubitUnitary((-1)**f, wires=[0, 1, 2])
-
- qml.templates.StronglyEntanglingLayers(weights2, wires=[0, 1, 2])
- return [qml.expval(qml.PauliZ(w)) for w in range(3)]
- ```
-
-* Added the templates `ArbitraryUnitary` and `ArbitraryStatePreparation` that use
- `PauliRot` gates to perform an arbitrary unitary and prepare an arbitrary basis
- state with the minimal number of parameters.
- [(#590)](https://github.com/XanaduAI/pennylane/pull/590)
+* PennyLane QNodes can now be converted into Keras layers, allowing for creation of quantum and
+ hybrid models using the Keras API.
+ [(#529)](https://github.com/XanaduAI/pennylane/pull/529)
- The templates could be used as follows:
+ A PennyLane QNode can be converted into a Keras layer using the `KerasLayer` class:
```python
- dev = qml.device('default.qubit', wires=3)
-
- @qml.qnode(dev)
- def circuit(weights1, weights2, x):
- qml.templates.ArbitraryStatePreparation(weights1, wires=[0, 1, 2])
- qml.templates.IQPEmbedding(features=x, wires=[0, 1, 2])
- qml.templates.ArbitraryUnitary(weights2, wires=[0, 1, 2])
- return qml.probs(wires=[0, 1, 2])
- ```
-
-* Added `metric_tensor` function to the `VQECost` class and
- `metric_tensor_fn` to `QNGOptimizer.step`, allowing users to optimize
- VQE-like cost functions with quantum natural gradient.
- [(#618)](https://github.com/XanaduAI/pennylane/pull/618)
+ from pennylane.qnn import KerasLayer
-* Added the `IQPEmbeddings` template, which encodes inputs into the diagonal gates of an
- IQP circuit.
- [(#605)](https://github.com/XanaduAI/pennylane/pull/605)
+ @qml.qnode(dev)
+ def circuit(inputs, weights_0, weight_1):
+ # define the circuit
+ # ...
-
+ weight_shapes = {"weights_0": 3, "weight_1": 1}
+ qlayer = qml.qnn.KerasLayer(circuit, weight_shapes, output_dim=2)
+ ```
- A typical usage example of the template is the following:
+ A hybrid model can then be easily constructed:
```python
- dev = qml.device('default.qubit', wires=3)
-
- @qml.qnode(dev)
- def circuit(features=None):
- qml.templates.IQPEmbedding(features=features, wires=range(3))
- return [qml.expval(qml.PauliZ(w)) for w in range(3)]
-
- circuit(features=[1., 2., 3.])
+ model = tf.keras.models.Sequential([qlayer, tf.keras.layers.Dense(2)])
```
-* PennyLane's benchmarking tool now supports the comparison of different git revisions.
- [(#568)](https://github.com/XanaduAI/pennylane/pull/568)
+* Added a new type of QNode, `qml.qnodes.PassthruQNode`. For simulators which are coded in an
+ external library which supports automatic differentiation, PennyLane will treat a PassthruQNode as
+ a "white box", and rely on the external library to directly provide gradients via backpropagation.
+ This can be more efficient than the using parameter-shift rule for a large number of parameters.
+ [(#488)](https://github.com/XanaduAI/pennylane/pull/488)
-* The `templates.broadcast` function can now take custom patterns.
- A custom pattern specifies the wires to which `unitary` is applied.
- [(#603)](https://github.com/XanaduAI/pennylane/pull/603)
+ Currently this behaviour is supported by PennyLane's `default.tensor.tf` device backend,
+ compatible with the `'tf'` interface using TensorFlow 2:
```python
- dev = qml.device('default.qubit', wires=5)
-
- pattern = [[0, 1], [3, 4]]
-
- @qml.qnode(dev)
- def circuit():
- broadcast(unitary=qml.CNOT, pattern=pattern, wires=range(5))
- return qml.expval(qml.PauliZ(0))
+ dev = qml.device('default.tensor.tf', wires=2)
- circuit()
- ```
+ @qml.qnode(dev, diff_method="backprop")
+ def circuit(params):
+ qml.RX(params[0], wires=0)
+ qml.RX(params[1], wires=1)
+ qml.CNOT(wires=[0, 1])
+ return qml.expval(qml.PauliZ(0))
-* PennyLane QNodes can now be converted into Keras layers, allowing for creation of quantum and
- hybrid models using the Keras API.
- [(#529)](https://github.com/XanaduAI/pennylane/pull/529)
+ qnode = PassthruQNode(circuit, dev)
+ params = tf.Variable([0.3, 0.1])
- ```python
- n_qubits = 2
- dev = qml.device("default.qubit", wires=n_qubits)
+ with tf.GradientTape() as tape:
+ tape.watch(params)
+ res = qnode(params)
- @qml.qnode(dev)
- def qnode(inputs, weights_0, weight_1):
- qml.RX(inputs[0], wires=0)
- qml.RX(inputs[1], wires=1)
- qml.Rot(*weights_0, wires=0)
- qml.RY(weight_1, wires=1)
- qml.CNOT(wires=[0, 1])
- return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
+ grad = tape.gradient(res, params)
```
- The above QNode can be converted into a Keras layer using the `KerasLayer` class:
-
- ```python
- from pennylane.qnn import KerasLayer
-
- weight_shapes = {"weights_0": 3, "weight_1": 1}
- qlayer = qml.qnn.KerasLayer(qnode, weight_shapes, output_dim=2)
+New optimizers
+
+* Added the `qml.RotosolveOptimizer`, a gradient-free optimizer
+ that minimizes the quantum function by updating each parameter,
+ one-by-one, via a closed-form expression while keeping other parameters
+ fixed.
+ [(#636)](https://github.com/XanaduAI/pennylane/pull/636)
+ [(#539)](https://github.com/XanaduAI/pennylane/pull/539)
+
+* Added the `qml.RotoselectOptimizer`, which uses Rotosolve to
+ minimizes a quantum function with respect to both the
+ rotation operations applied and the rotation parameters.
+ [(#636)](https://github.com/XanaduAI/pennylane/pull/636)
+ [(#539)](https://github.com/XanaduAI/pennylane/pull/539)
+
+ For example, given a quantum function `f` that accepts parameters `x`
+ and a list of corresponding rotation operations `generators`,
+ the Rotoselect optimizer will, at each step, update both the parameter
+ values and the list of rotation gates to minimize the loss:
+
+ ```pycon
+ >>> opt = qml.optimize.RotoselectOptimizer()
+ >>> x = [0.3, 0.7]
+ >>> generators = [qml.RX, qml.RY]
+ >>> for _ in range(100):
+ ... x, generators = opt.step(f, x, generators)
```
- A hybrid model can then be easily constructed:
- ```python
- model = tf.keras.models.Sequential([qlayer, tf.keras.layers.Dense(2)])
- ```
+New operations
-* Added the gate `PauliRot(angle, pauli_word)` that performs an arbitrary
- Pauli rotation specified by the Pauli word in string form and the gate
- `MultiRZ(angle)` that performs a rotation generated by a tensor product
+* Added the `PauliRot` gate, which performs an arbitrary
+ Pauli rotation on multiple qubits, and the `MultiRZ` gate,
+ which performs a rotation generated by a tensor product
of Pauli Z operators.
[(#559)](https://github.com/XanaduAI/pennylane/pull/559)
- Consider as an example the following circuit:
-
```python
dev = qml.device('default.qubit', wires=4)
@@ -139,9 +103,7 @@
return [qml.expval(qml.PauliZ(wire)) for wire in [0, 1, 2, 3]]
```
- We can run this circuit and look at the corresponding circuit drawing
-
- ```python
+ ```pycon
>>> circuit(0.4)
[1. 0.92106099 0.92106099 1. ]
>>> print(circuit.draw())
@@ -155,7 +117,7 @@
be decomposed into `Hadamard`, `RX` and `MultiRZ` gates. Note that
identity gates in the Pauli word result in untouched wires:
- ```python
+ ```pycon
>>> print(circuit.draw())
0: ───────────────────────────────────┤ ⟨Z⟩
1: ──H──────────╭RZ(0.4)──H───────────┤ ⟨Z⟩
@@ -166,7 +128,7 @@
If the `MultiRZ` gate is not supported, it will be decomposed into
`CNOT` and `RZ` gates:
- ```python
+ ```pycon
>>> print(circuit.draw())
0: ──────────────────────────────────────────────────┤ ⟨Z⟩
1: ──H──────────────╭X──RZ(0.4)──╭X──────H───────────┤ ⟨Z⟩
@@ -174,6 +136,58 @@
3: ─────────────╰C───────────────────╰C──────────────┤ ⟨Z⟩
```
+* PennyLane now provides `DiagonalQubitUnitary` for diagonal gates, that are e.g.,
+ encountered in IQP circuits. These kinds of gates can be evaluated much faster on
+ a simulator device.
+ [(#567)](https://github.com/XanaduAI/pennylane/pull/567)
+
+ The gate can be used, for example, to efficiently simulate oracles:
+
+ ```python
+ dev = qml.device('default.qubit', wires=3)
+
+ # Function as a bitstring
+ f = np.array([1, 0, 0, 1, 1, 0, 1, 0])
+
+ @qml.qnode(dev)
+ def circuit(weights1, weights2):
+ qml.templates.StronglyEntanglingLayers(weights1, wires=[0, 1, 2])
+
+ # Implements the function as a phase-kickback oracle
+ qml.DiagonalQubitUnitary((-1)**f, wires=[0, 1, 2])
+
+ qml.templates.StronglyEntanglingLayers(weights2, wires=[0, 1, 2])
+ return [qml.expval(qml.PauliZ(w)) for w in range(3)]
+ ```
+
+* Added the `TensorN` CVObservable that can represent the tensor product of the
+ `NumberOperator` on photonic backends.
+ [(#608)](https://github.com/XanaduAI/pennylane/pull/608)
+
+New templates
+
+* Added the `ArbitraryUnitary` and `ArbitraryStatePreparation` templates, which use
+ `PauliRot` gates to perform an arbitrary unitary and prepare an arbitrary basis
+ state with the minimal number of parameters.
+ [(#590)](https://github.com/XanaduAI/pennylane/pull/590)
+
+ ```python
+ dev = qml.device('default.qubit', wires=3)
+
+ @qml.qnode(dev)
+ def circuit(weights1, weights2):
+ qml.templates.ArbitraryStatePreparation(weights1, wires=[0, 1, 2])
+ qml.templates.ArbitraryUnitary(weights2, wires=[0, 1, 2])
+ return qml.probs(wires=[0, 1, 2])
+ ```
+
+* Added the `IQPEmbedding` template, which encodes inputs into the diagonal gates of an
+ IQP circuit.
+ [(#605)](https://github.com/XanaduAI/pennylane/pull/605)
+
+
+
* Added the ``SimplifiedTwoDesign`` template, which implements the circuit
design of [Cerezo et al. (2020)]().
[(#556)](https://github.com/XanaduAI/pennylane/pull/556)
@@ -194,6 +208,7 @@
[(#515)](https://github.com/XanaduAI/pennylane/pull/515)
[(#522)](https://github.com/XanaduAI/pennylane/pull/522)
[(#526)](https://github.com/XanaduAI/pennylane/pull/526)
+ [(#603)](https://github.com/XanaduAI/pennylane/pull/603)
For example, we can use broadcast to repeat a custom template
across multiple wires:
@@ -214,9 +229,7 @@
return qml.expval(qml.PauliZ(0))
```
- Executing this circuit:
-
- ```python
+ ```pycon
>>> circuit([1, 1, 0.1])
-0.841470984807896
>>> print(circuit.draw())
@@ -228,143 +241,73 @@
For other available patterns, see the
[broadcast function documentation](https://pennylane.readthedocs.io/en/latest/code/api/pennylane.broadcast.html).
-* Added the `qml.qnodes.PassthruQNode` class for simulated QNodes that appear as white boxes
- to an external autodifferentiation (AD) framework, and hence can be directly differentiated
- by it. Note that the simulator device executing the PassthruQNode has to be compatible with
- the external AD framework.
- [(#488)](https://github.com/XanaduAI/pennylane/pull/488)
+Breaking changes
- Currently the only such device supported by PennyLane is `default.tensor.tf`,
- compatible with the `'tf'` interface using TensorFlow 2:
+* The `QAOAEmbedding` now uses the new `MultiRZ` gate as a `ZZ` entangler,
+ which changes the convention. While
+ previously, the `ZZ` gate in the embedding was implemented as
```python
- from pennylane.qnodes import PassthruQNode
-
- dev = qml.device('default.tensor.tf', wires=2)
-
- def circuit(params):
- qml.RX(params[0], wires=0)
- qml.RX(params[1], wires=1)
- qml.CNOT(wires=[0, 1])
- return qml.expval(qml.PauliZ(0))
-
- qnode = PassthruQNode(circuit, dev)
- params = tf.Variable([0.3, 0.1])
+ CNOT(wires=[wires[0], wires[1]])
+ RZ(2 * parameter, wires=wires[0])
+ CNOT(wires=[wires[0], wires[1]])
+ ```
- with tf.GradientTape() as tape:
- tape.watch(params)
- res = qnode(params)
+ the `MultiRZ` corresponds to
- grad = tape.gradient(res, params)
+ ```python
+ CNOT(wires=[wires[1], wires[0]])
+ RZ(parameter, wires=wires[0])
+ CNOT(wires=[wires[1], wires[0]])
```
-* Added the `TensorN` CVObservable that can represent the tensor product of the
- `NumberOperator`.
- [(#608)](https://github.com/XanaduAI/pennylane/pull/608)
-
-Breaking changes
+ which differs in the factor of `2`, and fixes a bug in the
+ wires that the `CNOT` was applied to.
+ [(#609)](https://github.com/XanaduAI/pennylane/pull/609)
-* The internal variables `All` and `Any` to mark an `Operation` as acting on all or any
- wires have been renamed to `AllWires` and `AnyWires` and their class to
- `ActsOn`.
- [(#614)](https://github.com/XanaduAI/pennylane/pull/614)
- >
* Probability methods are handled by `QubitDevice` and device method
requirements are modified to simplify plugin development.
[(#573)](https://github.com/XanaduAI/pennylane/pull/573)
-
-* The `QAOAEmbedding` now uses the new `MultiRZ` gate as a `ZZ` entangler,
- which changes the convention: While
- previously, the `ZZ` gate in the embedding was implemented as
-
- .. code-block:: python
-
- CNOT(wires=[wires[0], wires[1]])
- RZ(2 * parameter, wires=wires[0])
- CNOT(wires=[wires[0], wires[1]])
-
- the `MultiRZ` corresponds to
-
- .. code-block:: python
-
- CNOT(wires=[wires[1], wires[0]])
- RZ(parameter, wires=wires[0])
- CNOT(wires=[wires[1], wires[0]])
-
- which differs in the factor of `2`, and fixes a bug in the
- wires that the `CNOT` was applied to.
- [(#609)](https://github.com/XanaduAI/pennylane/pull/609)
+
+* The internal variables `All` and `Any` to mark an `Operation` as acting on all or any
+ wires have been renamed to `AllWires` and `AnyWires`.
+ [(#614)](https://github.com/XanaduAI/pennylane/pull/614)
Improvements
* Improvements to the speed/performance of the `default.qubit` device.
[(#567)](https://github.com/XanaduAI/pennylane/pull/567)
+ [(#559)](https://github.com/XanaduAI/pennylane/pull/559)
-* Added the `"classical"` and `"device"` differentiation methods to the `qnode`
+* Added the `"backprop"` and `"device"` differentiation methods to the `qnode`
decorator.
[(#552)](https://github.com/XanaduAI/pennylane/pull/552)
- Using the `"classical"` differentiation method with the `default.tensor.tf`
- device, the created QNode is a 'white-box', and is tightly integrated with
- your TensorFlow computation:
+ - `"backprop"`: Use classical backpropagation. Default on simulator
+ devices that are classically end-to-end differentiable.
+ The returned QNode can only be used with the same machine learning
+ framework (e.g., ``default.tensor.tf`` simulator with the ``tensorflow`` interface).
- ```python
- >>> dev = qml.device("default.tensor.tf", wires=1)
- >>> @qml.qnode(dev, interface="tf", diff_method="classical")
- >>> 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))
- >>> vars = tf.Variable([0.2, 0.5, 0.1])
- >>> with tf.GradientTape() as tape:
- ... res = circuit(vars)
- >>> tape.gradient(res, vars)
-
- ```
-
- In this mode, you must use the ``"tf"`` interface, as TensorFlow
- is used as the device backend.
+ - `"device"`: Queries the device directly for the gradient.
- Using the `"device"` differentiation method with the `default.tensor.tf` the
- created QNode is a 'black-box' to your classical computation. PennyLane will
- automatically accept classical tensors from any supported interface, and
- query the device directly for the quantum gradient when required.
+ Using the `"backprop"` differentiation method with the `default.tensor.tf`
+ device, the created QNode is a 'white-box', and is tightly integrated with
+ the overall TensorFlow computation:
```python
- >>> dev = qml.device("default.tensor.tf", wires=1)
- >>> @qml.qnode(dev, interface="autograd", diff_method="device")
- >>> 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))
- >>> grad_fn = qml.grad(circuit, argnum=[0])
- >>> print(grad_fn([0.2, 0.5, 0.1]))
- ([array(-0.22526717), array(-1.00864546), array(6.9388939e-18)],)
+ >>> dev = qml.device("default.tensor.tf", wires=1)
+ >>> @qml.qnode(dev, interface="tf", 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))
+ >>> vars = tf.Variable([0.2, 0.5, 0.1])
+ >>> with tf.GradientTape() as tape:
+ ... res = circuit(vars)
+ >>> tape.gradient(res, vars)
+
```
- In this mode, even though TensorFlow is used as the device backend, it
- is independent of the chosen QNode interface. In the example above, we combine
- ``default.tensor.tf`` with the ``autograd`` interface.
- It can also be used with the ``torch`` and the ``tf`` interface.
-
-* The input check functions in `pennylane.templates.utils` are now public
- and visible in the API documentation.
- [(#566)](https://github.com/XanaduAI/pennylane/pull/566)
-
-* Improved the performance of diagonal gates in the `default.qubit` plugin.
- [(#559)](https://github.com/XanaduAI/pennylane/pull/559)
-
-* Added keyword arguments for step size and order to the `qnode` decorator, `QNode` and
- `JacobianQNode` classes to enable setting the step size and order when using finite
- difference methods. Exposed these options in `map` and `VQECost` for users creating collections
- of QNodes.
- [(#530)](https://github.com/XanaduAI/pennylane/pull/530)
- [(#585)](https://github.com/XanaduAI/pennylane/pull/585)
- [(#587)](https://github.com/XanaduAI/pennylane/pull/587)
-
-* The decomposition for the `CRY` gate now uses the simpler form `RY @ CNOT @ RY @ CNOT`
- [(#547)](https://github.com/XanaduAI/pennylane/pull/547)
-
* The circuit drawer now displays inverted operations, as well as wires
where probabilities are returned from the device:
[(#540)](https://github.com/XanaduAI/pennylane/pull/540)
@@ -383,12 +326,37 @@
1: ───────────╰X──S⁻¹──╰┤ Probs
```
+* You can now evaluate the metric tensor of a VQE Hamiltonian via the new
+ `VQECost.metric_tensor` method. This allows `VQECost` objects to be directly
+ optimized by the quantum natural gradient optimizer (`qml.QNGOptimizer`).
+ [(#618)](https://github.com/XanaduAI/pennylane/pull/618)
+
+* The input check functions in `pennylane.templates.utils` are now public
+ and visible in the API documentation.
+ [(#566)](https://github.com/XanaduAI/pennylane/pull/566)
+
+* Added keyword arguments for step size and order to the `qnode` decorator, as well as
+ the `QNode` and `JacobianQNode` classes. This enables the user to set the step size
+ and order when using finite difference methods. These options are also exposed when
+ creating QNode collections.
+ [(#530)](https://github.com/XanaduAI/pennylane/pull/530)
+ [(#585)](https://github.com/XanaduAI/pennylane/pull/585)
+ [(#587)](https://github.com/XanaduAI/pennylane/pull/587)
+
+* The decomposition for the `CRY` gate now uses the simpler form `RY @ CNOT @ RY @ CNOT`
+ [(#547)](https://github.com/XanaduAI/pennylane/pull/547)
+
* The underlying queuing system was refactored, removing the `qml._current_context`
property that held the currently active `QNode` or `OperationRecorder`. Now, all
objects that expose a queue for operations inherit from `QueuingContext` and
register their queue globally.
[(#548)](https://github.com/XanaduAI/pennylane/pull/548)
+* The PennyLane repository has a new benchmarking tool which supports the comparison of different git revisions.
+ [(#568)](https://github.com/XanaduAI/pennylane/pull/568)
+ [(#560)](https://github.com/XanaduAI/pennylane/pull/560)
+ [(#516)](https://github.com/XanaduAI/pennylane/pull/516)
+
Documentation
* Updated the development section by creating a landing page with links to sub-pages
@@ -426,10 +394,10 @@
This release contains contributions from (in alphabetical order):
-Ville Bergholm, Lana Bozanic, Thomas Bromley, Theodor Isacsson, Josh Izaac, Nathan Killoran,
+Ville Bergholm, Lana Bozanic, Thomas Bromley, Theodor Isacsson, Josh Izaac, Nathan Killoran,
Maggie Li, Johannes Jakob Meyer, Maria Schuld, Sukin Sim, Antal Száva.
-# Release 0.8.1 (current release)
+# Release 0.8.1
Improvements
diff --git a/doc/conf.py b/doc/conf.py
index 575c65b929b..5b059b200e7 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -12,7 +12,7 @@
#
# All configuration values have a default; values that are commented out
# serve to show the default.
-
+import pyscf
import sys, os, re
# If extensions (or modules to document with autodoc) are in another directory,
diff --git a/pennylane/_version.py b/pennylane/_version.py
index 6b81f9217f4..df3e1aeb1c6 100644
--- a/pennylane/_version.py
+++ b/pennylane/_version.py
@@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""
-__version__ = "0.9.0-dev"
+__version__ = "0.9.0"
diff --git a/setup.py b/setup.py
index 279817441e2..45c61cc65b7 100644
--- a/setup.py
+++ b/setup.py
@@ -31,7 +31,7 @@
'name': 'PennyLane',
'version': version,
'maintainer': 'Xanadu Inc.',
- 'maintainer_email': 'nathan@xanadu.ai',
+ 'maintainer_email': 'software@xanadu.ai',
'url': 'https://github.com/XanaduAI/pennylane',
'license': 'Apache License 2.0',
'packages': find_packages(where="."),