I am trying to use the Interferometer gate in a qnode running on the strawberry fields.fock device but I’m getting an error “Gate Interferometer not supported on device strawberryfields.fock”

Interferometer is within the pennylane.ops.cv module and is supposed to be compatible. Any ideas why this will never work or is there a clever workaround. I’m really interested in implementing an arbitrary unitary with trainable elements and Interferometer seemed the most elegant way.

Hi @Benjamin_Gregory, I had a look through your code, and you’re right, qml.Interferometer is currently not working with strawberryfields.fock. I’ll make a pull request on GitHub to fix that.

However, to train an arbitrary interferometer, you probably don’t want this operation. Note that we have two similar operations:

qml.Interferometer(U, wires): accepts a numeric unitary matrix, determining a fixed interferometer.

qml.templates.layers.Interferometer(theta, phi, varphi, wires): accepts an array of parameters theta, phi, and varphi, and creates a mesh of beamsplitters and rotation gates for applying a parametrized unitary.

In this case, it is probably the latter function you want. Check out the documentation for more details on this function and its arguments.

Here is a quick example using the Interferometer layer template:

import numpy as np
import pennylane as qml
from pennylane.templates.layers import Interferometer
from pennylane.init import interferometer_uniform
import tensorflow as tf
import tensorflow.contrib.eager as tfe
tf.enable_eager_execution()
M = 5
GBS_dev = qml.device("strawberryfields.gaussian", wires=M)
@qml.qnode(GBS_dev, interface="tf")
def device(params, input_squeeze):
# get beamsplitter angles
theta = params[:M*(M-1)//2]
# get beamsplitter phases
phi = params[M*(M-1)//2:2*M*(M-1)//2]
# get local rotations
varphi = params[-M:]
for w in range(M):
qml.Squeezing(1, input_squeeze, wires=w)
Interferometer(theta, phi, varphi, wires=range(M))
return [qml.expval(qml.NumberOperator(i)) for i in range(M)]
input_squeeze = 0.4*np.pi
params = tfe.Variable(np.concatenate(interferometer_uniform(M)))
print(device(params, input_squeeze))

Still not able to get NumberOperator to run with strawberry fields.gaussian or strawberry fields.fock devices. I have tried using other related functions MeanPhoton, mean_photon, NumberState etc.

I can only get NumberOperator to work with the default.gaussian device

NumberOperator not supported with sf.gaussian or sf.fock device

Ah, that’s good to know! We will release a bugfix version of PennyLane-SF at the end of this week, so it will include that fix (and allow NumberOperator to work on both the Fock and Gaussian devices).

tf.Variable object is not iterable

Unfortunately I can’t recreate this error. Can I ask what version of PennyLane and TensorFlow you are using?

We have been working internally on updating PennyLane to work with TensorFlow 2.0. This will be coming out at the end of this week (at the same time as the new plugin releases), and perhaps might solve the issue.

also is there a reason you switched to sf.gaussian over sf.fock device?

Simply due to speed Since the NumberOperator is a Gaussian observable (it is only second-order in the \hat{x} and \hat{p} operators), it is supported on both the Gaussian and Fock backends. If you were instead looking to train your optimizer using the probability (as opposed to the mean photon number), you can use the FockStateProjector observable, which is non-Gaussian.

In the latest GitHub version of PennyLane we have changed the interface name to 'tf' alongside supporting TF 2.0. This version will be released at the end of this week.

However, on PennyLane 0.5 (which you are using), it is still 'tfe' for now!