HI! I have a circuit which I would like to run several times, each time with slightly different parameters. Is there some easy\elegant way to do so?
Hi @segev. The easiest way is to call the circuit in a loop. I will be happy to take a look at your code if you give me a working example. Thanks.
import strawberryfields as sf
from strawberryfields import ops
import numpy as np
eng = sf.Engine("fock", backend_options={"cutoff_dim": 2})
down50=np.array([[1,1],[1,-1]])*(1/np.sqrt(2))
down30=np.array([[1/np.sqrt(3),np.sqrt(2)/np.sqrt(3)],
[np.sqrt(2)/np.sqrt(3),-1/np.sqrt(3)]])
up30=np.array([[-1/np.sqrt(3),np.sqrt(2)/np.sqrt(3)],
[np.sqrt(2)/np.sqrt(3),1/np.sqrt(3)]])
Ht=np.array([[1j,1j],[1j,-1j]])*(1/np.sqrt(2))#H'
states = [[0.,0.,0.,0.]]*4
prog = sf.Program(6)
phase=[1.5708582431532068, 1.6284157332273947,
-1.5707280700719355, -1.0887547385694465,
-0.0576375381598552, 0.5956784337483751,
-0.4820424972232051, -0.019512793550738525]
x1=0
x2=0
for i in range(4):
x2=i%2
if (i==2):
x1=1
with prog.context as q:
tet1x=x1*np.pi/4
tet2x=x2*np.pi/4
phi1x=x1*np.pi/2
phi2x=x2*np.pi/2
ops.Fock(0) | q[0]
ops.Fock(0) | q[1]
ops.Fock(0) | q[2]
ops.Fock(1) | q[3]
ops.Fock(0) | q[4]
ops.Fock(1) | q[5]
ops.BSgate() | (q[2], q[3])
ops.BSgate() | (q[4], q[5])
ops.Rgate(phase[0]) | q[2]
ops.Rgate(phase[2]) | q[4]
ops.BSgate() | (q[2], q[3])
ops.BSgate() | (q[4], q[5])
ops.Rgate(phase[1]) | q[2]
ops.Rgate(phase[3]) | q[4]
ops.Interferometer(down50) | (q[4], q[5])#B3
ops.Interferometer(up30) | (q[0], q[2])#B1
ops.Interferometer(up30) | (q[3], q[4])#B2
ops.Interferometer(down30) | (q[5], q[1])#B5
ops.Interferometer(down50) | (q[4], q[5])#B4
ops.Rgate(phase[4]) | q[2]
ops.Rgate(phase[6]) | q[4]
ops.BSgate() | (q[2], q[3])
ops.BSgate() | (q[4], q[5])
ops.Rgate(phase[5]) | q[2]
ops.Rgate(phase[7]) | q[4]
ops.BSgate() | (q[2], q[3])
ops.BSgate() | (q[4], q[5])
ops.MeasureFock(select=(0)) | q[0]
ops.MeasureFock(select=(0)) | q[1]
ops.BSgate(tet1x,phi1x) | (q[2], q[3])
ops.BSgate(tet2x,phi2x) | (q[4], q[5])
result = eng.run(prog)
state = result.state
probs = state.all_fock_probs()
probs=np.array(probs)
states[i][0]=probs[0,0,1,0,1,0]
states[i][1]=probs[0,0,1,0,0,1]
states[i][2]=probs[0,0,0,1,1,0]
states[i][3]=probs[0,0,0,1,0,1]
This is a part of my program, i’m trying to run the circuit 4 times in this loop but it keep saying" the program is locked"
Hi @segev. You get this error because the program gets locked when it is run once and no more operations can be performed when the loop restarts. Please see more information here. To fix the problem, you can simply create a function that runs the program and than call it many times with different parameters. I provide a simple example for generating samples with different displacement parameters:
import numpy as np
import strawberryfields as sf
np.random.seed(8)
def sample(param):
prog = sf.Program(2)
eng = sf.Engine("fock", backend_options={"cutoff_dim": 6})
with prog.context as q:
sf.ops.Dgate(param) | q[0]
sf.ops.BSgate() | (q[0], q[1])
sf.ops.MeasureFock() | q
return eng.run(prog).samples[0]
print([sample(param) for param in [0.1, 0.5, 1.0]])
# output: [array([0, 0]), array([1, 0]), array([1, 1])]
I could not reproduce the same error you reported with your code because part of the code is not formatted properly. However, following the logic of the example I provided above should resolve the issue. I will be more than happy to test your code if you please format all of the lines similarly.
It worked! Thank you so much!