The TF device

The strawberryfields.tf device gives access to Strawberry Field’s tf state simulator backend. This simulator device has the following features:

  • The simulator is written using TensorFlow, so supports classical backpropagation using PennyLane. Simply use interface="tf" when creating your QNode.

  • Quantum states are represented in the Fock basis \(\left| 0 \right>, \left| 1 \right>, \left| 2 \right>, \dots, \left| \mathrm{D -1} \right>\), where \(D\) is the user-given value for cutoff_dim that limits the dimension of the Hilbert space.

    The advantage of this representation is that any continuous-variable operation can be represented. However, the simulations are approximations, whose accuracy, the simulation time, and required memory increases with the cutoff dimension.

Warning

It is often useful to keep track of the normalization of a quantum state during optimization, to make sure the circuit does not “learn” to push its parameters into a regime where the simulation is vastly inaccurate.

Usage

You can instantiate the TF device in PennyLane as follows:

>>> import pennylane as qml
>>> import tensorflow as tf
>>> dev = qml.device('strawberryfields.tf', wires=2, cutoff_dim=10)

The device can then be used just like other devices for the definition and evaluation of QNodes within PennyLane.

For instance, the following simple example defines a QNode that first displaces the vacuum state, applies a beamsplitter, and then returns the marginal probability on the first wire. This function is then converted into a QNode which is placed on the strawberryfields.tf device:

@qml.qnode(dev, interface="tf")
def circuit(x, theta):
    qml.Displacement(x, 0, wires=0)
    qml.Beamsplitter(theta, 0, wires=[0, 1])
    return qml.probs(wires=0)

We can evaluate the QNode for arbitrary values of the circuit parameters:

>>> x = tf.Variable(1.0)
>>> theta = tf.Variable(0.543)
>>> with tf.GradientTape() as tape:
...     res = circuit(x, theta)
>>> print(res)
tf.Tensor(
[[4.8045865e-01+0.j 3.5218298e-01+0.j 1.2907754e-01+0.j 3.1538557e-02+0.j
  5.7795495e-03+0.j 8.4729097e-04+0.j 1.0349592e-04+0.j 1.0811385e-05+0.j
  9.6350857e-07+0.j 6.1937492e-08+0.j]], shape=(1, 10), dtype=complex64)

We can also evaluate the derivative with respect to any parameter(s):

>>> jac = tape.jacobian(res, x)
>>> print(jac)
<tf.Tensor: shape=(1, 10), dtype=float32, numpy=
array([[-7.0436597e-01,  1.8805575e-01,  3.2707882e-01,  1.4299491e-01,
         3.7763387e-02,  7.2306832e-03,  1.0900890e-03,  1.3535164e-04,
         1.3895189e-05,  9.9099987e-07]], dtype=float32)>

Note

The qml.state, qml.sample and qml.density_matrix measurements are not supported on the strawberryfields.tf device.

The continuous-variable QNodes available via Strawberry Fields can also be combined with qubit-based QNodes and classical nodes to build up a hybrid computational model. Such hybrid models can be optimized using the built-in optimizers provided by PennyLane.

PennyLane CV templates, such as Interferometer() and CVNeuralNetLayers(), can also be used:

dev = qml.device("strawberryfields.tf", wires=3, cutoff_dim=5)

@qml.qnode(dev, interface="tf")
def circuit(weights):
    for i in range(3):
        qml.Squeezing(0.1, 0, wires=i)

    qml.templates.Interferometer(
        theta=weights[0],
        phi=weights[1],
        varphi=weights[2],
        wires=[0, 1, 2],
        mesh="rectangular",
    )
    return qml.probs(wires=0)

Once defined, we can now use this QNode within any TensorFlow computation:

>>> weights = qml.init.interferometer_all(n_wires=3)
>>> weights = [tf.convert_to_tensor(w) for w in weights]
>>> with tf.GradientTape() as tape:
...     tape.watch(weights)
...     res = circuit(weights)
>>> grad = tape.gradient(res, weights)
[<tf.Tensor: shape=(3,), dtype=float64, numpy=array([-4.93799348e-07,  5.99637985e-07,  8.90550478e-09])>,
 <tf.Tensor: shape=(3,), dtype=float64, numpy=array([-2.09796852e-07,  1.01452002e-08, -4.34359642e-08])>,
 <tf.Tensor: shape=(3,), dtype=float64, numpy=array([ 8.36735126e-10, -1.21872290e-10, -1.81160686e-09])>]

Note

The strawberryfields.tf device does not support Autograph mode (tf.function).

Device options

The Strawberry Fields TF device accepts additional arguments beyond the PennyLane default device arguments.

cutoff_dim

the Fock basis truncation when applying quantum operations

hbar=2

The convention chosen in the canonical commutation relation \([x, p] = i \hbar\). Default value is \(\hbar=2\).

shots=None

The number of circuit evaluations/random samples used to estimate expectation values of observables. The default value of None means that the exact expectation value is returned.

Supported operations

The Strawberry Fields TF device supports all continuous-variable (CV) operations and observables provided by PennyLane, including both Gaussian and non-Gaussian operations.

Supported operations:

Beamsplitter

Beamsplitter interaction.

CoherentState

Prepares a coherent state.

ControlledAddition

Controlled addition operation.

ControlledPhase

Controlled phase operation.

CrossKerr

Cross-Kerr interaction.

CubicPhase

Cubic phase shift.

DisplacedSqueezedState

Prepares a displaced squeezed vacuum state.

Displacement

Phase space displacement.

FockDensityMatrix

Prepare subsystems using the given density matrix in the Fock basis.

FockState

Prepares a single Fock state.

FockStateVector

Prepare subsystems using the given ket vector in the Fock basis.

GaussianState

Prepare subsystems in a given Gaussian state.

InterferometerUnitary

A linear interferometer transforming the bosonic operators according to the unitary matrix \(U\).

Kerr

Kerr interaction.

QuadraticPhase

Quadratic phase shift.

Rotation

Phase space rotation.

SqueezedState

Prepares a squeezed vacuum state.

Squeezing

Phase space squeezing.

ThermalState

Prepares a thermal state.

TwoModeSqueezing

Phase space two-mode squeezing.

Supported observables:

Identity

The identity observable \(\I\).

NumberOperator

The photon number observable \(\langle \hat{n}\rangle\).

TensorN

The tensor product of the NumberOperator acting on different wires.

X

The position quadrature observable \(\hat{x}\).

P

The momentum quadrature observable \(\hat{p}\).

QuadOperator

The generalized quadrature observable \(\x_\phi = \x cos\phi+\p\sin\phi\).

PolyXP

An arbitrary second-order polynomial observable.