Hi @sophchoe, are you looking for the Fock representation of the squeezing operation?
Unfortunately, the Fock representation is not as simple as the Kerr gate, since the squeezing operation is not diagonal in the Fock basis. In the Fock basis, the creation and annihilation operators are given by:
\hat{a}^\dagger = \begin{bmatrix}
0 & 0 & 0 & 0 & \cdots & 0 & \cdots \\
\sqrt{1} & 0 & 0 & 0 & \cdots & 0 & \cdots \\
0 & \sqrt{2} & 0 & 0 & \cdots & 0 & \cdots \\
0 & 0 & \sqrt{3} & 0 & \cdots & 0 & \cdots \\
\vdots & \vdots & \vdots & \ddots & \ddots & \cdots & \cdots \\
0 & 0 & 0 & \cdots & \sqrt{n} & 0 & \cdots & \\
\vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \ddots \end{bmatrix}
and
a =\begin{bmatrix}
0 & \sqrt{1} & 0 & 0 & \cdots & 0 & \cdots \\
0 & 0 & \sqrt{2} & 0 & \cdots & 0 & \cdots \\
0 & 0 & 0 & \sqrt{3} & \cdots & 0 & \cdots \\
0 & 0 & 0 & 0 & \ddots & \vdots & \cdots \\
\vdots & \vdots & \vdots & \vdots & \ddots & \sqrt{n} & \cdots \\
0 & 0 & 0 & 0 & \cdots & 0 & \ddots \\
\vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots \end{bmatrix}
We can create this in NumPy, up to a certain Fock cutoff or truncation, using np.diag
:
>>> cutoff = 8
>>> a = np.diag(np.sqrt(np.arange(1, cutoff)), k=1)
>>> adag = np.diag(np.sqrt(np.arange(1, cutoff)), k=-1)
We can then use scipy.linalg.expm
to compute the matrix exponential:
>>> z = 0.76
>>> sp.linalg.expm(0.5 * (np.conj(z) * a @ a - z * adag @ adag))
However, this is quite inefficient, and the matrix exponential can introduce numerical errors for large Fock basis states.
Instead, we can use The Walrus to compute the Fock representation of the squeezing operation:
>>> from thewalrus.fock_gradients import squeezing
>>> squeezing(r=z, theta=0, cutoff=cutoff)