Skip to content

Release 0.11.0

Compare
Choose a tag to compare
@josh146 josh146 released this 18 Aug 05:09
· 2960 commits to master since this release
5cb0994

New features since last release

New and improved simulators

  • Added a new device, default.qubit.autograd, a pure-state qubit simulator written using Autograd. This device supports classical backpropagation (diff_method="backprop"); this can be faster than the parameter-shift rule for computing quantum gradients when the number of parameters to be optimized is large. (#721)

    >>> 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 device documentation for more details.

  • A new experimental C++ state-vector simulator device is now available, lightning.qubit. 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:

    $ pip install pennylane-lightning

    Once installed, it can be used as a PennyLane device:

    >>> dev = qml.device("lightning.qubit", wires=2)

    For more details, please see the lightning qubit documentation.

New algorithms and templates

  • Added built-in QAOA functionality via the new qml.qaoa module. (#712) (#718) (#741) (#720)

    This includes the following features:

    • New qml.qaoa.x_mixer and qml.qaoa.xy_mixer functions for defining Pauli-X and XY mixer Hamiltonians.

    • MaxCut: The qml.qaoa.maxcut function allows easy construction of the cost Hamiltonian and recommended mixer Hamiltonian for solving the MaxCut problem for a supplied graph.

    • Layers: qml.qaoa.cost_layer and qml.qaoa.mixer_layer take cost and mixer Hamiltonians, respectively, and apply the corresponding QAOA cost and mixer layers to the quantum circuit

    For example, using PennyLane 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[0], params[1])
    
    dev = qml.device('default.qubit', wires=len(wires))
    cost_function = qml.VQECost(ansatz, cost_h, dev)
  • Added an ApproxTimeEvolution template to the PennyLane templates module, which can be used to implement Trotterized time-evolution under a Hamiltonian. (#710)

  • Added a qml.layer template-constructing function, which takes a unitary, and repeatedly applies it on a set of wires to a given depth. (#723)

    def subroutine():
        qml.Hadamard(wires=[0])
        qml.CNOT(wires=[0, 1])
        qml.PauliX(wires=[1])
    
    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))]

    This creates the following circuit:

    >>> circuit()
    >>> print(circuit.draw())
    0: ──H──╭C──X──H──╭C──X──H──╭C──X──┤ ⟨Z⟩
    1: ─────╰X────────╰X────────╰X─────┤ ⟨Z⟩
  • Added the qml.utils.decompose_hamiltonian function. This function can be used to decompose a Hamiltonian into a linear combination of Pauli operators. (#671)

    >>> A = np.array(
    ... [[-2, -2+1j, -2, -2],
    ... [-2-1j,  0,  0, -1],
    ... [-2,  0, -2, -1],
    ... [-2, -1, -1,  0]])
    >>> coeffs, obs_list = decompose_hamiltonian(A)

New device features

  • It is now possible to specify custom wire labels, such as ['anc1', 'anc2', 0, 1, 3], where the labels can be strings or numbers. (#666)

    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)
  • An integrated device test suite has been added, which can be used to run basic integration tests on core or external devices. (#695) (#724) (#733)

    The test can be invoked against a particular device by calling the pl-device-test command line program:

    $ pl-device-test --device=default.qubit --shots=1234 --analytic=False

    If the tests are run on external devices, the device and its dependencies must be installed locally. For more details, please see the plugin test documentation.

Improvements

  • Added support for TensorFlow 2.3 and PyTorch 1.6. (#725)

  • Returning probabilities is now supported from photonic QNodes. As with qubit QNodes, photonic QNodes returning probabilities are end-to-end differentiable. (#699)

    >>> dev = qml.device("strawberryfields.fock", wires=2, cutoff_dim=5)
    >>> @qml.qnode(dev)
    ... def circuit(a):
    ...     qml.Displacement(a, 0, wires=0)
    ...     return qml.probs(wires=0)
    >>> print(circuit(0.5))
    [7.78800783e-01 1.94700196e-01 2.43375245e-02 2.02812704e-03 1.26757940e-04]

Breaking changes

  • The pennylane.plugins and pennylane.beta.plugins folders have been renamed to pennylane.devices and pennylane.beta.devices, to reflect their content better. (#726)

Bug fixes

  • The PennyLane interface conversion functions can now convert QNodes with pre-existing interfaces. (#707)

Documentation

  • The interfaces section of the documentation has been renamed to 'Interfaces and training', and updated with the latest variable handling details. (#753)

Contributors

This release contains contributions from (in alphabetical order):

Juan Miguel Arazzola, Thomas Bromley, Jack Ceroni, Alain Delgado Gran, Shadab Hussain, Theodor Isacsson, Josh Izaac, Nathan Killoran, Maria Schuld, Antal Száva, Nicola Vitucci.