Hi everyone! Today we’re very glad to announce the release of PennyLane version 0.11.0.
This release comes with two brand new devices, a new QAOA module, as well as an exciting overhaul of the wires system, among other things.
New and improved simulators
There are two brand new devices added to the set of default devices in PennyLane:
default.qubit.autograd, a pure-state qubit simulator written using Autograd, supporting fast gradient calculations using automatic differentiation.
lightning.qubit, a new experimental C++ state-vector simulator device. It uses the C++ Eigen library to perform fast linear algebra calculations for simulating quantum state-vector evolution.
lightning.qubit is currently in beta; it can be installed via
$ pip install pennylane-lightning
For more details, please see the lightning qubit documentation.
New algorithms and templates
There’s a new Quantum Approximate Optimization Algorithm (QAOA) module providing many new and exciting features for solving optimization problems on quantum devices.
As an example, you can use it to construct and solve a MaxCut problem with QAOA!
wires = range(3) graph = Graph([(0, 1), (1, 2), (2, 0)]) cost_h, mixer_h = qaoa.maxcut(graph) def qaoa_layer(gamma, alpha): qaoa.cost_layer(gamma, cost_h) qaoa.mixer_layer(alpha, mixer_h) def antatz(params, **kwargs): for w in wires: qml.Hadamard(wires=w) # repeat the QAOA layer two times qml.layer(qaoa_layer, 2, params, params) dev = qml.device('default.qubit', wires=len(wires)) cost_function = qml.VQECost(ansatz, cost_h, dev)
There is also a new
ApproxTimeEvolution template added to the PennyLane templates module, which can be used to implement Trotterized time-evolution under a Hamiltonian, as well as a
qml.layer template-constructing function, which takes a unitary, and repeatedly applies it on a set of wires to a given depth.
def subroutine(): qml.Hadamard(wires=) qml.CNOT(wires=[0, 1]) qml.PauliX(wires=) dev = qml.device('default.qubit', wires=3) @qml.qnode(dev) def circuit(): qml.layer(subroutine, 3) return [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))]
which creates the following circuit:
>>> circuit() >>> print(circuit.draw()) 0: ──H──╭C──X──H──╭C──X──H──╭C──X──┤ ⟨Z⟩ 1: ─────╰X────────╰X────────╰X─────┤ ⟨Z⟩
The wires system has been overhauled to become more powerful and user friendly. You can now specify custom wire labels, such as
['anc1', 'anc2', 0, 1, 3], where the labels can be strings or numbers, instead of simply using consecutive numbers, as was the case before.
Custom wire labels are defined by passing a list to the wires argument when creating the device:
>>> dev = qml.device("default.qubit", wires=['anc1', 'anc2', 0, 1, 3])
Quantum operations should then be invoked with these custom wire labels:
>>> @qml.qnode(dev) >>> def circuit(): … qml.Hadamard(wires='anc2') … qml.CNOT(wires=['anc1', 3]) … ...
The existing behaviour, in which the number of wires is specified on device initialization, continues to work as usual. This gives a default behaviour where wires are labelled by consecutive integers.
>>> dev = qml.device("default.qubit", wires=5)
Other new features include a
qml.utils.decompose_hamiltonian function that can be used to decompose a Hamiltonian into a linear combination of Pauli operators, an integrated device test suite, which can be used to run basic integration tests on core or external devices, and support for returning probabilities from photonic QNodes.
The full release notes are available at https://pennylane.readthedocs.io/en/stable/development/release_notes.html.
As always, this release would not have been possible without all the help from our contributors: