Measurements in Strawberry Fields

Hello here is my circuit:

import strawberryfields as sf
import tensorflow as tf
from strawberryfields.ops import Ket, BSgate, Rgate
import numpy as np

cutoff_dim = 5
paths = 2
modes = 2 * paths

initial_state = np.zeros([cutoff_dim] * modes, dtype=np.complex)
initial_state[0, 1, 0, 1] = 1

prog = sf.Program(modes)
with prog.context as q:
    Ket(initial_state) | q  # Initial state preparation
    
    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])
    
    BSgate() | (q[1], q[2])
    
    Rgate((np.pi)/(8)) | q[0]
    Rgate((np.pi)/(8)) | q[2]
    
    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])
    
    Rgate(0) | q[0]
    Rgate((np.pi)/2) | q[2]
    
    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])

Now I want to measure my qubits. Actually when I designed my circuit in cirq, I have just 2 qubits and I was measuring my two qubits in computational basis and program was returning to me [0,1] or [1,0] or [1,1] or [0,0 ] However now, I have 2 qubits and each qubits have 2 modes. So how can I measure my qubits or states or modes? I mean what should I do for getting my measurements ??

Ok for my situation(we use single photon source), the measurement should be MeasureFock
However when I add measureFock to my circuit like that:

    cutoff_dim = 5
paths = 2
modes = 2 * paths
eng = sf.Engine("fock", backend_options={"cutoff_dim": 5})
initial_state = np.zeros([cutoff_dim] * modes, dtype=np.complex)
initial_state[0, 1, 0, 1] = 1

prog = sf.Program(modes)
with prog.context as q:
    Ket(initial_state) | q  # Initial state preparation
    
    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])
    
    #BSgate() | (q[1], q[2])
    
    Rgate((np.pi)/(8)) | q[0]
    Rgate((np.pi)/(8)) | q[2]
    
    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])
    
    Rgate(0) | q[0]
    Rgate((np.pi)/2) | q[2]
    
    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])
    #MeasureFock() | q[0]
    #MeasureFock() | q[2]
    MeasureFock() | q

results = eng.run(prog)


print(results.samples[0][0])

I get just 1 or 0. I should get two result like [0 1] or [11] or [00]or [1 0]since I have 2 qubits. How can I do that?

Ok I added this lines but this time second qubit is never changed. It always came as 0 while the first qubit changes: why is this the case?

prog = sf.Program(modes)
with prog.context as q:
    Ket(initial_state) | q  # Initial state preparation

    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])

    #BSgate() | (q[1], q[2])

    Rgate((np.pi)/(8)) | q[0]   
    Rgate((5*np.pi)/(8)) | q[2]

    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])

    Rgate(0) | q[0]
    Rgate((np.pi)/2) | q[2]

    BSgate() | (q[0], q[1])
    BSgate() | (q[2], q[3])
    MeasureFock() | q[0]
    MeasureFock() | q[2]
    #MeasureFock() | q

results = eng.run(prog)


print(results.samples)

Dear @nisq : Keep mind that you are assuming the dual rail encoding here. That means that you encode a single qubit in a single photon “shared” between two modes. Thus for example a computation basis measurement of the first qubit is equivalent to photon number measurement in the first two modes. Similarly, a computational basis measurement in the second qubit is equivalent to two photon number measurements in the last two modes.

Before diving into coding I’d suggest you review the fundamentals of optical quantum computation. A nice reference to start is e.g. https://arxiv.org/pdf/1103.6071.pdf

Nicolas

Dear @Nicolas_Quesada
Thank you very much! Exactly!
And when I wrote:

        MeasureFock() | q[0]
        MeasureFock() | q[1]
        MeasureFock() | q[2]
        MeasureFock() | q[4]
results = eng.run(prog)
measurements = results.samples[0]

1)I can measure my all modes with this code scripts.(If I am not wrong?)And in this case I expect one of these results:
[0,1,0,1] or [1,0,1,0]. However (probably I am confused with single photon sources and click probabilities)I could not understand [1,1,1,1] and [0,0,0,0] because how can I have 1 for both first qubit modes?? I thought my qubit should be either in the first modes or in the second modes(we cannot click for both at the same time)
2) Suppose that the result is [1,0,0,1] here the first two digits (1,0) means the two modes are my first qubit and second two digits (0,1) means two modes are my second qubit right? Or what is the order for this list?

Bests

Hi @nisq ---- I think it is impossible to get the outcomes [1,1,1,1] and [0,0,0,0]. If you inject two photons into a four mode interferometer you must get two photons out.
You are also getting to an important point, which is that linear optics operations between dual-rail encoded qubits can take out of the computational space. Thus for example you can start with one photon in the first two modes and one photon in the last two modes, but there is still a chance you end up with 2 photons in one of the modes and zero elsewhere; this corresponds to an error.

Dear @Nicolas_Quesada

think it is impossible to get the outcomes [1,1,1,1] and [0,0,0,0]. If you inject two photons into a four mode interferometer you must get two photons out.

Now I am ok and I feel comfortable. Thanks. I run the other code(not related to photonic) for same computations and in that I had these result and I thought I was running the strawberry code for a moment but no. For strawberry code I dont have 1111 or 0000. Sorry I have lots of code with dofferent libararies and I was confused for a moment. Thank a lot

Thus for example you can start with one photon in the first two modes and one photon in the last two modes, but there is still a chance you end up with 2 photons in one of the modes and zero elsewhere; this corresponds to an error.

Is this possible with strawberry fields :astonished: I hope it is not and you gave me a physical example

Now I have very small question regarding coding:

Injecting two photon starts with this code scripts Right?

initial_state[0, 1, 0, 1] = 1

and I can also write this one:
initial_state[1 0, 1, 0] = 1

or combinations. And same for 4 photons
initial_state[1, 1, 1, 1] = 1
This means I have 4 photons right?

Thanks for your patience
Best regards

Hi @nisq:

Is this possible with strawberry fields :astonished: I hope it is not and you gave me a physical example

It is of course possible in SF since, it is what happens in the experiments. If for example you check what is the amplitude ket[0,0,0,0,0,2,1,1] in the polarization tutorial you will find that it is non-zero.

As for your question, you are correct initial_state[0, 1, 0, 1] = 1 means a single photon in modes 1 and 3 while initial_state[1, 1, 1, 1] = 1 means four photons, one in every mode.

1 Like

perfect thanks a lot

Thanks @nisq, no problem!

1 Like