Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_eval_true_state_fock_prob(self, setup_eng, cutoff, tol):
"""Tests whether the probability of a Fock measurement outcome on the state returns
the correct value when eval=True is passed to the fock_prob method of a state."""
n1 = cutoff // 2
n2 = cutoff // 3
eng, prog = setup_eng(2)
with prog.context as q:
Dgate(ALPHA) | q[0]
Dgate(-ALPHA) | q[1]
state = eng.run(prog).state
prob = state.fock_prob([n1, n2], eval=True)
ref_prob = np.abs(
np.outer(coherent_state(ALPHA, cutoff), coherent_state(-ALPHA, cutoff)) ** 2
)[n1, n2]
assert np.allclose(prob, ref_prob, atol=tol, rtol=0.0)
def test_non_primitive_gates():
"""Tests that the compiler is able to compile a number of non-primitive Gaussian gates"""
width = 6
eng = sf.LocalEngine(backend="gaussian")
eng1 = sf.LocalEngine(backend="gaussian")
circuit = sf.Program(width)
A = np.random.rand(width, width) + 1j * np.random.rand(width, width)
A = A + A.T
valsA = np.linalg.svd(A, compute_uv=False)
A = A / 2 * np.max(valsA)
B = np.random.rand(width // 2, width // 2) + 1j * np.random.rand(width // 2, width // 2)
valsB = np.linalg.svd(B, compute_uv=False)
B = B / 2 * valsB
B = np.block([[0 * B, B], [B.T, 0 * B]])
with circuit.context as q:
ops.GraphEmbed(A) | q
ops.BipartiteGraphEmbed(B) | q
ops.Pgate(0.1) | q[1]
ops.CXgate(0.2) | (q[0], q[1])
ops.MZgate(0.4, 0.5) | (q[2], q[3])
A = np.random.rand(width, width) + 1j * np.random.rand(width, width)
A = A + A.T
valsA = np.linalg.svd(A, compute_uv=False)
A = A / 2 * np.max(valsA)
B = np.random.rand(width // 2, width // 2) + 1j * np.random.rand(width // 2, width // 2)
valsB = np.linalg.svd(B, compute_uv=False)
B = B / 2 * valsB
B = np.block([[0 * B, B], [B.T, 0 * B]])
with circuit.context as q:
ops.GraphEmbed(A) | q
ops.BipartiteGraphEmbed(B) | q
ops.Pgate(0.1) | q[1]
ops.CXgate(0.2) | (q[0], q[1])
ops.MZgate(0.4, 0.5) | (q[2], q[3])
ops.Fourier | q[0]
ops.Xgate(0.4) | q[1]
ops.Zgate(0.5) | q[3]
compiled_circuit = circuit.compile("gaussian_unitary")
cv = eng.run(circuit).state.cov()
mean = eng.run(circuit).state.means()
cv1 = eng1.run(compiled_circuit).state.cov()
mean1 = eng1.run(compiled_circuit).state.means()
assert np.allclose(cv, cv1)
assert np.allclose(mean, mean1)
A = A + A.T
valsA = np.linalg.svd(A, compute_uv=False)
A = A / 2 * np.max(valsA)
B = np.random.rand(width // 2, width // 2) + 1j * np.random.rand(width // 2, width // 2)
valsB = np.linalg.svd(B, compute_uv=False)
B = B / 2 * valsB
B = np.block([[0 * B, B], [B.T, 0 * B]])
with circuit.context as q:
ops.GraphEmbed(A) | q
ops.BipartiteGraphEmbed(B) | q
ops.Pgate(0.1) | q[1]
ops.CXgate(0.2) | (q[0], q[1])
ops.MZgate(0.4, 0.5) | (q[2], q[3])
ops.Fourier | q[0]
ops.Xgate(0.4) | q[1]
ops.Zgate(0.5) | q[3]
compiled_circuit = circuit.compile("gaussian_unitary")
cv = eng.run(circuit).state.cov()
mean = eng.run(circuit).state.means()
cv1 = eng1.run(compiled_circuit).state.cov()
mean1 = eng1.run(compiled_circuit).state.means()
assert np.allclose(cv, cv1)
assert np.allclose(mean, mean1)
# first do general GBS compilation to make sure
# Fock measurements are correct
# ---------------------------------------------
seq = GBSSpecs().compile(seq, registers)
A, B, C = group_operations(seq, lambda x: isinstance(x, ops.MeasureFock))
if len(B[0].reg) != self.modes:
raise CircuitError("All modes must be measured.")
# Check circuit begins with two mode squeezers
# --------------------------------------------
A, B, C = group_operations(seq, lambda x: isinstance(x, ops.S2gate))
if A:
raise CircuitError("Circuits must start with two S2gates.")
# get circuit registers
regrefs = {q for cmd in B for q in cmd.reg}
if len(regrefs) != self.modes:
raise CircuitError("S2gates do not appear on the correct modes.")
# Compile the unitary: combine and then decompose all unitaries
# -------------------------------------------------------------
A, B, C = group_operations(seq, lambda x: isinstance(x, (ops.Rgate, ops.BSgate)))
# begin unitary lists for mode [0, 1] and modes [2, 3] with
# two identity matrices. This is because multi_dot requires
# at least two matrices in the list.
U_list01 = [np.identity(self.modes // 2, dtype=np.complex128)] * 2
U_list23 = [np.identity(self.modes // 2, dtype=np.complex128)] * 2
self.ns = S.shape[0] // 2
self.vacuum = vacuum #: bool: if True, ignore the first unitary matrix when applying the gate
N = self.ns # shorthand
# check if input symplectic is passive (orthogonal)
diffn = np.linalg.norm(S @ S.T - np.identity(2*N))
self.active = (np.abs(diffn) > _decomposition_tol) #: bool: S is an active symplectic transformation
if not self.active:
# The transformation is passive, do Clements
X1 = S[:N, :N]
P1 = S[N:, :N]
self.U1 = X1+1j*P1
else:
# transformation is active, do Bloch-Messiah
O1, smat, O2 = dec.bloch_messiah(S, tol=tol)
X1 = O1[:N, :N]
P1 = O1[N:, :N]
X2 = O2[:N, :N]
P2 = O2[N:, :N]
self.U1 = X1+1j*P1 #: array[complex]: unitary matrix corresponding to O_1
self.U2 = X2+1j*P2 #: array[complex]: unitary matrix corresponding to O_2
self.Sq = np.diagonal(smat)[:N] #: array[complex]: diagonal vector of the squeezing matrix R
def test_not_drawable(self, tmpdir):
prog = sf.Program(3)
with prog.context as q:
ops.BSgate(0, 2) | (q[0], q[2])
with pytest.raises(NotDrawableException):
prog.draw_circuit(tex_dir=tmpdir)
def setup_two_mode_circuit(self, setup_eng, cutoff):
"""Create the circuit for following tests"""
eng_ref, p0 = setup_eng(2)
S = ops.Sgate(2)
B = ops.BSgate(2.234, -1.165)
initial_state = np.complex64(
np.random.rand(*[cutoff] * 4) + 1j * np.random.rand(*[cutoff] * 4)
)
with p0.context as q:
ops.DensityMatrix(initial_state) | q
prog = sf.Program(p0)
with prog.context as q:
S | q[0]
B | q
S | q[1]
B | q
rho = eng_ref.run([p0, prog]).state.dm()
def single_input_circuit(x):
eng.reset()
with eng:
Dgate(x[0], 0.) | q[0]
Dgate(x[1], 0.) | q[1]
BSgate(phi=params[0]) | (q[0], q[1])
BSgate() | (q[0], q[1])
state = eng.run('fock', cutoff_dim=10, eval=True)
p0 = state.fock_prob([0, 2])
p1 = state.fock_prob([2, 0])
normalisation = p0 + p1 + 1e-10
outp = p1 / normalisation
return outp
def setup_one_mode_circuit(self, setup_eng, cutoff):
"""Create the circuit for following tests"""
eng_ref, p0 = setup_eng(1)
S = ops.Sgate(1.1, -1.4)
L = ops.LossChannel(0.45)
initial_state = np.random.rand(cutoff, cutoff)
with p0.context as q:
ops.DensityMatrix(initial_state) | q
prog = sf.Program(p0)
with prog.context as q:
S | q
L | q
rho = eng_ref.run([p0, prog]).state.dm()
return prog, rho, initial_state