def two_mode_squeeze(r, theta, trunc): r"""The two-mode squeezing operator :math:`S_2(re^{i\theta})`. Args: r (float): two-mode squeezing magnitude theta (float): two-mode squeezing phase trunc (int): Fock ladder cutoff """ ret = two_mode_squeezing_tw(r, theta, cutoff=trunc) # Transpose needed because of different conventions in SF and The Walrus. ret = np.transpose(ret, [0, 2, 1, 3]) return ret
def single_two_mode_squeezing_matrix(theta, phi, cutoff, dtype=def_type.as_numpy_dtype): """creates a single mode two-mode squeezing matrix""" theta = theta.numpy() phi = phi.numpy() gate = two_mode_squeezing_tw(theta, phi, cutoff, dtype) gate = np.transpose(gate, [0, 2, 1, 3]) def grad(dy): Dr, Dphi = grad_two_mode_squeezing_tw(np.transpose(gate, [0, 2, 1, 3]), theta, phi) Dr = np.transpose(Dr, [0, 2, 1, 3]) Dphi = np.transpose(Dphi, [0, 2, 1, 3]) grad_r = tf.math.real(tf.reduce_sum(dy * tf.math.conj(Dr))) grad_phi = tf.math.real(tf.reduce_sum(dy * tf.math.conj(Dphi))) return grad_r, grad_phi, None return gate, grad