def test_embed_graph(self, setup_eng, hbar): """Test that an embedded graph has the right total mean photon number. """ eng, prog = setup_eng(2) A = np.array([[0.0, 1.0], [1.0, 0.0]]) n_mean_per_mode = 1 with prog.context as q: ops.GraphEmbed(A, n_mean_per_mode) | (q[0], q[1]) state = eng.run(prog).state cov = state.cov() n_mean_tot = np.trace(cov / (hbar / 2) - np.identity(4)) / 4 expected = 2 * n_mean_per_mode assert np.allclose(n_mean_tot, expected)
def test_graph_embed(self, setup_eng, tol): """Test that embedding a traceless adjacency matrix A results in the property Amat/A = c J, where c is a real constant, and J is the all ones matrix""" N = 3 eng, prog = setup_eng(3) with prog.context as q: ops.GraphEmbed(A) | q state = eng.run(prog).state Amat = eng.backend.circuit.Amat() # check that the matrix Amat is constructed to be of the form # Amat = [[B^\dagger, 0], [0, B]] assert np.allclose(Amat[:N, :N], Amat[N:, N:].conj().T, atol=tol) assert np.allclose(Amat[:N, N:], np.zeros([N, N]), atol=tol) assert np.allclose(Amat[N:, :N], np.zeros([N, N]), atol=tol) ratio = np.real_if_close(Amat[N:, N:] / A) ratio /= ratio[0, 0] assert np.allclose(ratio, np.ones([N, N]), atol=tol)
def test_decomposition(self, hbar, tol): """Test that an graph is correctly decomposed""" n = 3 prog = sf.Program(n) A = np.random.random([n, n]) + 1j * np.random.random([n, n]) A += A.T A -= np.trace(A) * np.identity(n) / 3 sq, U = dec.graph_embed(A) G = ops.GraphEmbed(A) cmds = G.decompose(prog.register) assert np.all(sq == G.sq) assert np.all(U == G.U) S = np.identity(2 * n) # calculating the resulting decomposed symplectic for cmd in cmds: # all operations should be BSgates, Rgates, or Sgates assert isinstance( cmd.op, (ops.Interferometer, ops.BSgate, ops.Rgate, ops.Sgate)) # build up the symplectic transform modes = [i.ind for i in cmd.reg] if isinstance(cmd.op, ops.Sgate): S = _squeezing(cmd.op.p[0].x, cmd.op.p[1].x, modes, n) @ S if isinstance(cmd.op, ops.Rgate): S = _rotation(cmd.op.p[0].x, modes, n) @ S if isinstance(cmd.op, ops.BSgate): S = _beamsplitter(cmd.op.p[0].x, cmd.op.p[1].x, modes, n) @ S if isinstance(cmd.op, ops.Interferometer): U1 = cmd.op.p[0].x S_U = np.vstack([ np.hstack([U1.real, -U1.imag]), np.hstack([U1.imag, U1.real]) ]) S = S_U @ S # the resulting covariance state cov = S @ S.T # calculate Hamilton's A matrix: A = X.(I-Q^{-1})* I = np.identity(n) O = np.zeros_like(I) X = np.block([[O, I], [I, O]]) x = cov[:n, :n] xp = cov[:n, n:] p = cov[n:, n:] aidaj = (x + p + 1j * (xp - xp.T) - 2 * I) / 4 aiaj = (x - p + 1j * (xp + xp.T)) / 4 Q = np.block([[aidaj, aiaj.conj()], [aiaj, aidaj.conj()] ]) + np.identity(2 * n) A_res = X @ (np.identity(2 * n) - np.linalg.inv(Q)).conj() # The bottom right corner of A_res should be identical to A, # up to some constant scaling factor. Check if the ratio # of all elements is one ratio = np.real_if_close(A_res[n:, n:] / A) ratio /= ratio[0, 0] assert np.allclose(ratio, np.ones([n, n]), atol=tol, rtol=0)
def test_identity(self, tol): """Test that nothing is done if the adjacency matrix is the identity""" G = ops.GraphEmbed(np.identity(6)) assert G.identity