I am trying to implement a Continuous-Variable version of a Convolutional Neural Network. I couldn’t find any example of this on the website or Github. I am using the same ansatz as in the article Killoran, 2018, which is a periodic 1D convolution that can be represented by a circulant matrix but am encountering some issues.
My idea is this: every circulant matrix can be diagonalized with the Fourier matrix like so: C=1/n F diag(Fc) F*, where c is the first row of the circulant matrix. Therefore, I should be able to calculate the convolution with two interferometers, one for each Fourier matrix and a complex scaling using the squeezing and rotation gates as below (where x is the input vector, r=-log(abs(Fc)) and phi_rot is the argument of Fc):
dev = device("strawberryfields.fock",wires=M, cutoff_dim=10) @qnode(dev) def convolution(x=None, phi_x=None, FH=None, F=None, r=None, phi_r=None, phi_rot=None): M = len(x) wires = [wire for wire in range(M)] broadcast(unitary=Displacement, pattern="single", wires=wires, parameters=list(zip(x, phi_x))) Interferometer(U1, wires=wires) broadcast(unitary=Squeezing, pattern="single", wires=wires, parameters=list(zip(r, phi_r))) broadcast(unitary=Rotation, pattern="single", wires=wires, parameters=list(phi_rot)) Interferometer(U2, wires=wires) return (expval(X(0)),expval(X(1)),expval(X(2)),expval(X(3)),)
The problem with this method arises in the squeezing gate, when the real scaling with abs(Fc) are large and lead to what I think are numerical errors. Is there a way to minimize these errors in scaling or is there a more clever way to achieve this transformation?
Any help would be greatly appreciated!