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
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
M = 5
GBS_dev = qml.device("strawberryfields.gaussian", wires=M)
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)))