Skip to content

Variational quantum algorithms

Variational algorithms on noisy devices and quantum machine learning (QML)1 in particular are one of the main target applications for Qadence. For this purpose, the library offers both flexible symbolic expressions for the quantum circuit parameters via sympy for more details and native automatic differentiation via integration with PyTorch deep learning framework.

Furthermore, Qadence-Model offers a wide range of utilities for helping building and researching quantum machine learning algorithms.

Some simple examples

Qadence-Model symbolic parameter interface allows to create arbitrary feature maps to encode classical data into quantum circuits with an arbitrary non-linear function embedding for the input values:

import qadence as qd
import qadence_model as qdm
from qadence.operations import *
import torch
from sympy import acos

n_qubits = 4

# Example feature map, also directly available with the `feature_map` function
fp = qd.FeatureParameter("phi")
fm = qd.kron(RX(i, acos(fp)) for i in range(n_qubits))

# the key in the dictionary must correspond to
# the name of the assigned to the feature parameter
inputs = {"phi": torch.rand(3)}
samples = qd.sample(fm, values=inputs)
samples = OrderedCounter({'0001': 14, '1000': 14, '0000': 13, '0101': 11, '0010': 7, '0100': 6, '1011': 5, '1100': 5, '1101': 5, '0011': 4, '0110': 4, '1010': 4, '1001': 3, '0111': 2, '1111': 2, '1110': 1})

The constructors.feature_map module provides convenience functions to build commonly used feature maps where the input parameter is encoded in the single-qubit gates rotation angle.

Furthermore, Qadence-Model is natively integrated with PyTorch automatic differentiation engine thus Qadence-Model quantum models can be used seamlessly in a PyTorch workflow.

Let's create a quantum neural network model using the feature map just defined, a digital-analog variational ansatz and a simple observable \(X(0) \otimes X(1)\). We use the convenience QNN quantum model abstraction.

ansatz = qd.hea(n_qubits, strategy="sDAQC")
circuit = qd.QuantumCircuit(n_qubits, fm, ansatz)
observable = qd.kron(X(0), X(1))

model = qdm.models.QNN(circuit, observable)

# NOTE: the `QNN` is a torch.nn.Module
assert isinstance(model, torch.nn.Module)
True

Differentiation works the same way as any other PyTorch module:

values = {"phi": torch.rand(10, requires_grad=True)}

# the forward pass of the quantum model returns the expectation
# value of the input observable
out = model(values)

# you can compute the gradient with respect to inputs using
# PyTorch autograd differentiation engine
dout = torch.autograd.grad(out, values["phi"], torch.ones_like(out), create_graph=True)[0]
print(f"First-order derivative w.r.t. the feature parameter: \n{dout}")

# you can also call directly a backward pass to compute derivatives with respect
# to the variational parameters and use it for implementing variational
# optimization
out.sum().backward()
Quantum model output: 
tensor([[0.1476],
        [0.0929],
        [0.1187],
        [0.1544],
        [0.1126],
        [0.1519],
        [0.1489],
        [0.1533],
        [0.0739],
        [0.1443]], grad_fn=<CatBackward0>)

First-order derivative w.r.t. the feature parameter: 
tensor([-0.1055,  0.1833, -0.2827,  0.0014,  0.1695,  0.0541,  0.0775,  0.0360,
        -0.5541, -0.1321], grad_fn=<MulBackward0>)

To run QML on real devices, Qadence-Model offers generalized parameter shift rules (GPSR) 2 for arbitrary quantum operations which can be selected when constructing the QNN model:

model = qdm.models.QNN(circuit, observable, diff_mode="gpsr")
out = model(values)

dout = torch.autograd.grad(out, values["phi"], torch.ones_like(out), create_graph=True)[0]
print(f"First-order derivative w.r.t. the feature parameter: \n{dout}")
First-order derivative w.r.t. the feature parameter: 
tensor([-0.1055,  0.1833, -0.2827,  0.0014,  0.1695,  0.0541,  0.0775,  0.0360,
        -0.5541, -0.1321], grad_fn=<MulBackward0>)

References


  1. Schuld, Petruccione, Machine learning on Quantum Computers, Springer Nature (2021) 

  2. Kyriienko et al., General quantum circuit differentiation rules