In the above, the single mode squeeze states all apply identical squeezing :math:`z=r`, the parameters of the beamsplitters and the rotation gates determine the unitary :math:`U`, and finally the detectors perform Fock state measurements on the output modes. As with boson sampling, for :math:`N` input modes, we must have a minimum of :math:`N+1` columns in the beamsplitter array [[4]_]. Simulating this circuit using Strawberry Fields is easy; we can simply read off the gates from left to right, and convert it into the Blackbird circuit language. To begin, we create the boson sampling quantum program using Strawberry Fields: """ import numpy as np # set the random seed np.random.seed(42) # import Strawberry Fields import strawberryfields as sf from strawberryfields.ops import * ###################################################################### # Unlike the :doc:`run_boson_sampling`, we will directly apply a Gaussian unitary # to the circuit using the :class:`~strawberryfields.ops.Interferometer` operation. # First, we must define the unitary matrix we would like to embed in the circuit: # define the linear interferometer U = np.array([ [ 0.219546940711-0.256534554457j, 0.611076853957+0.524178937791j, -0.102700187435+0.474478834685j,-0.027250232925+0.03729094623j], [ 0.451281863394+0.602582912475j, 0.456952590016+0.01230749109j, 0.131625867435-0.450417744715j, 0.035283194078-0.053244267184j], [ 0.038710094355+0.492715562066j,-0.019212744068-0.321842852355j, -0.240776471286+0.524432833034j,-0.458388143039+0.329633367819j], [-0.156619083736+0.224568570065j, 0.109992223305-0.163750223027j, -0.421179844245+0.183644837982j, 0.818769184612+0.068015658737j] ]) ###################################################################### # We can use this to now construct the circuit: # create the 4 mode Strawberry Fields program gbs = sf.Program(4) with gbs.context as q: # prepare the input squeezed states S = Sgate(1) S | q[0] S | q[1] S | q[2] S | q[3] # linear interferometer Interferometer(U) | q ###################################################################### # A couple of things to note in this particular example: # # .. # # 1. To prepare the input single mode squeezed vacuum state :math:`\ket{z}` where :math:`z = 1`, we # apply a squeezing gate :class:`~strawberryfields.ops.Sgate` to each of the modes (initially in # the vacuum state). # # .. # # 2. Next we apply the linear interferometer to all four modes, using the decomposition operator # :class:`~strawberryfields.ops.Interferometer`, and the unitary matrix ``U``. This operator # decomposes the unitary matrix representing the linear interferometer into single mode # rotation gates :class:`~strawberryfields.ops.Rgate`, and two-mode beamsplitters # :class:`~strawberryfields.ops.BSgate`. After applying the interferometer, we will denote the # output state by :math:`\ket{\psi'}`. # # .. note:: # # You can view the decomposed beamsplitters and rotation gates which correspond to the linear # interferometer ``U`` by calling :meth:`eng.print_applied() #