How to postselect on a "range" of MeasureHomodyne() outcomes?

What is the proper use of the “select” option inside the MeasureHomodyne() function?

Hey @saurabh-shringarpure! Welcome to the forum :rocket:!

The select argument is optional — its default value is None, meaning that it’s completely bypassed and not used by default. However, if you specify a value here, it means that when you perform a homodyne measurement you are asking for a post-selection of specific measurement results. I.e., you’re filtering out values from random sampling — no selection — that you don’t want except for one.

Here is an example that you can play around with!

import strawberryfields as sf
from strawberryfields.ops import *

prog = sf.Program(2)
eng = sf.Engine("gaussian")

with prog.context as q:
    S2gate(1) | (q[0], q[1])
    # interchange the following lines to see behaviour of select
    #MeasureHomodyne(0, select=3) | q[0]
    MeasureHomodyne(0) | q[0]

samples = eng.run(prog).samples
print(samples)

Hope this helps!

1 Like

Can it select a range of values instead of just one?

I don’t think so, unfortunately! Is this detrimental to your code / research?

Oh, I see. Thank you. Yes, I would like that feature for my research.

1 Like

It might be best for us to seek an alternate approach. Are you able to share your research endeavours and/or code? We might be able to show you a way around this!

import strawberryfields as sf
from strawberryfields.ops import *
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import cm

prog = sf.Program(2)
eng = sf.Engine("bosonic")

theta = np.arccos(np.sqrt(0.5)) # arccos of the transmittivity of the beamsplitter

# Options for the postselection window
start = 0.1
stop = 0.2

with prog.context as q:
    sf.ops.Catstate(2) | q[0]
    sf.ops.Vacuum() | q[1]
    sf.ops.BSgate(theta,0) | (q[0], q[1])
    MeasureHomodyne(0, select = [start, stop]) | q[1] #Need to use a postselection window here. Accept all values between start and stop.

state = eng.run(prog).state

# We now plot it
xvec = np.linspace(-8, 8, 201)
W = state.wigner(mode = 0, xvec = xvec, pvec = xvec)
Wp = np.round(W.real, 4)
scale = np.max(Wp.real)
nrm = mpl.colors.Normalize(-scale, scale)
plt.axes().set_aspect("equal")
plt.contourf(xvec, xvec, Wp, 60, cmap=cm.RdBu, norm=nrm)
plt.xlabel(r"q (units of $\sqrt{\hbar}$)", fontsize=15)
plt.ylabel(r"p (units of $\sqrt{\hbar}$)", fontsize=15)
plt.show()

Thank you @isaacdevlugt I am looking for an application similar to the one shown here. This code doesn’t work as the ‘select’ option in MeasureHomodyne() takes a single value input.

Hey @saurabh-shringarpure!

I’m not sure that I see an alternative besides just running your circuit twice as follows :confused: :

import strawberryfields as sf
from strawberryfields.ops import *
import numpy as np

prog1 = sf.Program(2)
prog2 = sf.Program(2)
eng = sf.Engine("bosonic")

theta = np.arccos(np.sqrt(0.5)) # arccos of the transmittivity of the beamsplitter

# Options for the postselection window
start = 0.1
stop = 0.2

with prog1.context as q:
    sf.ops.Catstate(2) | q[0]
    sf.ops.Vacuum() | q[1]
    sf.ops.BSgate(theta,0) | (q[0], q[1])
    MeasureHomodyne(0, select = start) | q[1] #Need to use a postselection window here. Accept all values between start and stop.

state1 = eng.run(prog).state

with prog2.context as q:
    sf.ops.Catstate(2) | q[0]
    sf.ops.Vacuum() | q[1]
    sf.ops.BSgate(theta,0) | (q[0], q[1])
    MeasureHomodyne(0, select = stop) | q[1] #Need to use a postselection window here. Accept all values between start and stop.

state2 = eng.run(prog).state

print(state1, state2)

I’ll tag @Sebastian_Duque_Mesa here just in case I’m missing something.

Yep — just confirmed with Sebastián. Looks like this is the way to do it (two separate programs).

Thank you @isaacdevlugt @Sebastian_Duque_Mesa for your answer. However, I would like to accept all the values in between ‘start’ and ‘stop’ as well. The measurement operator needs to be \propto \int_{\text{start}}^{\text{stop}}{dx|x\rangle\langle x|}. The result should be just one quantum state in the unmeasured mode. Can this be done?

Unfortunately no :confused:. This would entail giving multiple select values to MeasureHomodyne, which isn’t a feature.

1 Like