Wigner Calculation unstable for the Fock backend

Hi all,

I am experimenting with strawberry field and I wanted to look at the effect of cutoff dimension on the representation of very squeezed states.8

I have a circuit to generate the squeezed state :

def fun_squeeze(n,p,cutoff_dim=50):
    prog = sf.Program(1)
    eng = sf.Engine("fock", backend_options={"cutoff_dim": cutoff_dim})
    with prog.context as q:
        Fock(n) | q[0]
        Sgate(p) | q[0]
    results = eng.run(prog)
    state = results.state
    return state

A function to plot the wigner function (copy pasted from strawberry field documentation):

def fun_wigner(state,qmode=0,lims = 5):
    fig = plt.figure()
    X = np.linspace(-lims, lims, 100)
    P = np.linspace(-lims, lims, 100)
    Z = state.wigner(qmode, X, P)
    return Z

And a script to look at how it evolves for different cut-off dimension :

ds = [10,20,50,100,200,500]
fig, axs = plt.subplots(1,len(ds),figsize=(3*len(ds),3*1), subplot_kw = {"projection":"3d"})
Zs = []
states = []
for k,ax in enumerate(axs.flat):
    state = fun_squeeze(0,2,cutoff_dim=ds[k])
    states.append(state)
    Zs.append(plot_wigner(state,ax=ax))

As can be seen for the 200 and 500 cutoff dimension the Wigner function starts to show instability (the data in the state is fine). Is that expected ? I could not find any maximum for the cutoff dimension or the Wigner function of the Fock backend in the documentation of strawberry fields.

I am using the Fock backend because I will need to use it for the next steps in my project.

Hi @alicewithoutbob! Charlie here.

Your state is very squeezed! It will have support on high-lying Fock states and will look almost like a delta function in the q quadrature. Can you try reducing the squeezing value or increasing the size of your limits?

I’m not aware of any instabilities of the Wigner function calculation but it well might be that for such a high cutoff (500 is a very high cutoff!) and small q and p limits it doesn’t capture very well your state.

The code used to calculate the Wigner function is here.

Hi @Sebastian_Duque_Mesa! Eve is peeping :eyes: .

I am new and not familiar with this forum, and I hope I asked my question in the right chat.
Like @alicewithoutbob, I am experimenting with Strawberry Fields and have also noticed the same instability in the Wigner function calculation, even with a ‘reasonable’ amount of squeezing (around 6 dB).

I am using this definition for the squeezed state:

def Squeeze(r, cutoff):
    
    """This function aims to build a vacuum squeezed state in the Fock basis
    r      : Squeezing parameter
    """ 
    prog = sf.Program(1)
    eng = sf.Engine("fock", backend_options={"cutoff_dim": cutoff})
    with prog.context as q:
        S = Sgate(r)
        S | q[0]
    state = eng.run(prog).state
    print("State trace : {} ".format(state.trace()))
    return [state, format(state.trace())]

Compute a vacuum squeezed state with different cutoff, and calculate the Wigner function

ds = [150, 200, 250]

Ws = []
states = []
X = np.linspace(-15, 15, 401)
P = np.linspace(-15, 15, 401)

for i in ds:
    state = Squeeze(-0.7, i)
    states.append(state[0])
    Ws.append(state[0].wigner(mode=0, xvec=X, pvec=P))

The following plot is the wigner function I obtained :

The issue is that at around a cutoff of 200, the calculation of the Wigner function for squeezed vacuum states computed with the Fock backend seems unstable, even with a reasonable amount of squeezing.

I reviewed the code used to calculate the Wigner function and did not find what causes these instabilities.

I need to increase the cutoff with the Fock backend for further studies, and I wonder if there is a way to correct this.
I also thought that the more the cutoff is increased, the more accurate on the calculation you are but it is not the case here and I was wondering why.

Thank you for your attention and your time and have a good day.

Hi @deneb ,

Welcome to the Forum! You are indeed asking the question in the right chat.

I’m not sure why you’re getting that instability (I’m checking with the team) but in the meantime you can try using MrMustard instead.

The following code allows you to get the Wigner function for a squeezed state, and you can learn how to perform other operations in the docs.

First get the automatically-selected cutoff by running:

from mrmustard.lab import *
import mrmustard.math as math
math.change_backend("tensorflow")

sq  = SqueezedVacuum(r=-0.7)
sq

And in a different cell run the following code and see the difference.

sq._cutoffs = [250]  # force the cutoff
sq

I hope this helps!

Hi @deneb,

It’s still unclear why you get this instability in Strawberry Fields. It might be best to just use MrMustard in this case.

In MrMustard you can also use settings.DISCRETIZATION_METHOD=“clenshaw” to get better Wigner plots.

I hope this helps!