Note

You can download this notebook here.

Piquasso program organizationΒΆ

With Piquasso, one could easily separate programs into multiple with statements:

[18]:
import piquasso as pq
import numpy as np


with pq.Program() as preparation:
    pq.Q(0, 1) | pq.Squeezing2(r=1, phi=np.pi / 4)
    pq.Q(2, 3) | pq.Squeezing2(r=2, phi=np.pi / 3)

with pq.Program() as interferometer:
    pq.Q(0, 1) | pq.Beamsplitter(theta=np.pi / 4, phi=np.pi / 3)
    pq.Q(1) | pq.Phaseshifter(phi=np.pi / 2)
    pq.Q(1, 2) | pq.Beamsplitter(theta=np.pi / 5, phi=np.pi / 6)

with pq.Program() as executable_program:
    pq.Q(all) | preparation

    pq.Q(0, 1, 2) | interferometer
    pq.Q(2, 3, 4) | interferometer

    pq.Q(3) | pq.HeterodyneMeasurement()


simulator = pq.GaussianSimulator(d=5)
result = simulator.execute(executable_program)
result
[18]:
Result(samples=[(-8.201970710129283, 6.806985248163985)], state=GaussianState(d=5, config=Config(), connector=NumpyConnector()))

Using this syntax, one could embed subprograms on different modes. In this example, the interferometer subprogram is embedded twice for two different sets of modes. Note, that the subprogram is registered to the specified only via pq.Q.

One can use this syntax to define custom gates as follows:

[19]:
def MyBeamsplitter(theta, phi):
    my_beamsplitter = pq.Program(
        instructions=[
            pq.Phaseshifter(phi=phi).on_modes(0),
            pq.Beamsplitter(theta=theta, phi=0.0).on_modes(0, 1),
        ]
    )

    return my_beamsplitter


with pq.Program() as preparation:
    pq.Q(0, 1) | pq.Squeezing2(r=1, phi=np.pi / 4)
    pq.Q(2, 3) | pq.Squeezing2(r=2, phi=np.pi / 3)

with pq.Program() as program:
    pq.Q(all) | preparation

    pq.Q(0, 1) | MyBeamsplitter(theta=np.pi / 4, phi=np.pi / 3)
    pq.Q(1, 2) | MyBeamsplitter(theta=np.pi / 5, phi=np.pi / 6)

    pq.Q(3) | pq.ParticleNumberMeasurement()


print("Instructions:")
for instruction in program.instructions:
    print("\t", instruction)
Instructions:
         Squeezing2(r=1, phi=0.7853981633974483, modes=(0, 1))
         Squeezing2(r=2, phi=1.0471975511965976, modes=(2, 3))
         Phaseshifter(phi=1.0471975511965976, modes=(0,))
         Beamsplitter(theta=0.7853981633974483, phi=0.0, modes=(0, 1))
         Phaseshifter(phi=0.5235987755982988, modes=(1,))
         Beamsplitter(theta=0.6283185307179586, phi=0.0, modes=(1, 2))
         ParticleNumberMeasurement(modes=(3,))