Hi everyone! We are pleased to announce the release of PennyLane version 0.12.
This release comes with a new mixed-state simulator and quantum noisy channels, a new module for minimizing the number of measurement settings for hardware, the ability to access the state vector from circuits, and a preview to the next-generation QNode.
New and improved simulators
A new mixed-state simulator called default.mixed
has been added to the set of default devices in PennyLane. This device is ideal for simulating and optimizing circuits that include noise and quantum channels.
Code example
The device can be initialized as
dev = qml.device("default.mixed", wires=1)
@qml.qnode(dev)
def circuit(params):
qml.RX(params[0], wires=0)
qml.RY(params[1], wires=0)
qml.AmplitudeDamping(0.5, wires=0)
return qml.expval(qml.PauliZ(0))
print(circuit([0.54, 0.12]))
0.9257702929524184
print(circuit([0, np.pi]))
0.0
New tools for optimizing measurements
The new grouping module provides functionality for grouping simultaneously measurable Pauli word observables.
Code example
As an example, you can use the new optimize_measurements
function to reduce the number of measurements needed on quantum hardware during optimization:
from pennylane.grouping import optimize_measurements
h, nr_qubits = qml.qchem.molecular_hamiltonian("h2", "h2.xyz")
rotations, grouped_ops, grouped_coeffs = optimize_measurements(h.ops, h.coeffs, grouping="qwc")
This depends on a lower level function called group_observables
which partitions a list of observables (Pauli operations and tensor products thereof) into groupings according to a binary relation:
from pennylane.grouping import group_observables
observables = [qml.PauliY(0), qml.PauliX(0) @ qml.PauliX(1), qml.PauliZ(1)]
obs_groupings = group_observables(observables)
print(obs_groupings)
[[Tensor(PauliX(wires=[0]), PauliX(wires=[1]))], [PauliY(wires=[0]), PauliZ(wires=[1])]]
Returning the quantum state from simulators
The quantum state of a QNode can now be returned using the qml.state()
return function. Differentiating the state is currently available when using the classical backpropagation differentiation method (diff_method="backprop"
) with a compatible device, and when using the new tape mode (qml.enable_tape
).
Code example
import pennylane as qml
dev = qml.device("default.qubit", wires=2)
qml.enable_tape()
@qml.qnode(dev)
def qfunc(x, y):
qml.RZ(x, wires=0)
qml.RY(y, wires=0)
qml.CNOT(wires=[0, 1])
return qml.state()
qfunc(0.56, 0.1)
tensor([0.95985437-0.27601028j, 0. +0.j ,
0. +0.j , 0.04803275-0.01381203j], requires_grad=True)
Additional features
Other new features include the addition of quantum channels (Amplitude-damping, Phase-damping, Depolarizing, and custom qubit channels) that can be used with default.mixed
, the tape
module which includes a new re-formulated QNode class (experimental). A couple of major advantages of tape mode include that it provides a way of working with less restrictive QNode signatures and it supports in-QNode classical processing.
The full release notes are available at Release notes โ PennyLane 0.27.0 documentation.
As always, this release would not have been possible without all the help from our contributors:
@AroosaIjaz, @jmarrazola, @Tom_Bromley, Jack Ceroni, @Alain_Delgado_Gran, @josh, @sjahangiri, @nathan, Robert Lang, Cedric Lin, @glassnotes, @Nicolas_Quesada, @Maria_Schuld, Antal Szรกva