When is Strawberry Fields switching from Ket Vector to Density Matrix representation?

My interrogation stems from the following piece of code. I have a circuit that just starts in the ground state for a number n of modes, does nothing else and returns the state (always a pure state) :

def circuit(num_modes,cutoff_dim = 15):
    prog = sf.Program(num_modes)
    eng = sf.Engine("fock", backend_options={"cutoff_dim": cutoff_dim})
    with prog.context as q:
        Fock(0) | q[0]
    results = eng.run(prog)
    state = results.state
    return state

With just a single mode the data remains stored as a vector :

state = circuit(1)
print(state.data.shape)
print(state.is_pure)
>>> (15,)
>>> True

With just two modes it seems it switches to a density matrix representation :

state = circuit(2)
print(state.data.shape)
print(state.is_pure)
>>> (15, 15, 15, 15)
>>> False

I have tried to look in the documentation, did not find anything and turned the source code (here) to find why SF behaved like that but I could not find an answer.

Is there a good place to look for where this is explained ?

Hi @alicewithoutbob,

If you check this tutorial you will notice that by default, all qumode subsystems are assumed initialised in the vacuum state.

So if you do

def circuit(num_modes,cutoff_dim = 15):
    prog = sf.Program(num_modes)
    eng = sf.Engine("fock", backend_options={"cutoff_dim": cutoff_dim})
    results = eng.run(prog)
    state = results.state
    return state

state = circuit(2)
print(state.data.shape)
print(state.is_pure)

You will notice that the result is True.

When you add

with prog.context as q:
        Fock(0) | q[0]

You’re basically preparing a 0-photon state in qumode q[0].

You may find our tutorial on quantum teleportation useful to understand Strawberry Fields better.

Please let me know if this helps!

1 Like

Hi @alicewithoutbob
To compliment my answer:

When you prepare a Fock state on a specific mode (see for instance prepare_fock_state) the requested mode is traced out and replaced with the Fock state ∣𝑛⟩. As a result the state may have to be described using a density matrix.

It is true that in this case this should be a pure state if you think about it, but when you apply Fock(0) | q[0] the program doesn’t know that the state before was the vacuum, thus the mode is traced out and you get a density matrix as a result. If you want to start in the vacuum state you don’t need to do anything, or you can use the reset function and specify whether to initialize the circuit in a pure state representation or use a mixed state representation.

I hope this helps!

1 Like

Thank you @CatalinaAlbornoz for your answer. As switching from pure state to density matrix considerably increases the memory requirement and the execution time, I think it would be useful to have somewhere in the documentation an explanation of this. Or maybe at least a summary of the strawberryfields.ops tagging those which induce a switch from pure to mixed representation (maybe here ?). Maybe it is already available somewhere but I could not find it.

Hi @alicewithoutbob, thank you very much for this suggestion! I have forwarded it to the Strawberry Fields team.