def test_even_validation(self): """Test raises exception if not even number of rows""" A = np.random.random([5, 5]) + 1j * np.random.random([5, 5]) A += A.T with pytest.raises(ValueError, match="must have an even number of rows/columns"): dec.bloch_messiah(A)
def test_williamson_BM_random_circuit_pure(self): self.logTestName() for k in range(nsamples): n = 3 U2 = haar_measure(n) state = gaussiancircuit.GaussianModes(n, hbar=2) for i in range(n): state.squeeze(np.log(0.2 * i + 2), 0, i) state.apply_u(U2) V = state.scovmatxp() D, S = dec.williamson(V) omega = dec.sympmat(n) self.assertAlmostEqual(np.linalg.norm(S @ omega @ S.T - omega), 0) self.assertAlmostEqual(np.linalg.norm(S @ D @ S.T - V), 0) O, s, Oo = dec.bloch_messiah(S) self.assertAlmostEqual( np.linalg.norm(np.transpose(O) @ omega @ O - omega), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(O) @ O - np.identity(2 * n)), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(Oo) @ omega @ Oo - omega), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(Oo) @ Oo - np.identity(2 * n)), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(s) @ omega @ s - omega), 0) self.assertAlmostEqual(np.linalg.norm(O @ s @ Oo - S), 0)
def test_decomposition_active(self, hbar, tol): """Test that an active symplectic is correctly decomposed into two interferometers and squeezing""" n = 3 S = random_symplectic(n, passive=False) O1, Sq, O2 = dec.bloch_messiah(S) X1 = O1[:n, :n] P1 = O1[n:, :n] X2 = O2[:n, :n] P2 = O2[n:, :n] U1 = X1 + 1j * P1 U2 = X2 + 1j * P2 prog = sf.Program(n, hbar=hbar) with eng: G = ops.GaussianTransform(S) cmds = G.decompose(q) assert np.all(U1 == G.U1) assert np.all(U2 == G.U2) assert np.all(np.diag(Sq)[:n] == G.Sq) S = np.identity(2 * n) # command queue should have 2 interferometers, 3 squeezers assert len(cmds) == 5 # calculating the resulting decomposed symplectic for cmd in cmds: # all operations should be BSgates, Rgates, or Sgates assert isinstance(cmd.op, (ops.Interferometer, 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.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 assert np.allclose(cov, S @ S.T * hbar / 2, atol=tol, rtol=0)
def test_active_on_vacuum(self, hbar, tol): """Test that an active symplectic applied to a vacuum is correctly decomposed into just squeezing and one interferometer""" n = 3 S = random_symplectic(n, passive=False) O1, Sq, O2 = dec.bloch_messiah(S) X1 = O1[:n, :n] P1 = O1[n:, :n] X2 = O2[:n, :n] P2 = O2[n:, :n] U1 = X1 + 1j * P1 U2 = X2 + 1j * P2 prog = sf.Program(n) G = ops.GaussianTransform(S, vacuum=True) cmds = G.decompose(prog.register) S = np.identity(2 * n) # command queue should have 3 Sgates, 1 interferometer assert len(cmds) == 4 # calculating the resulting decomposed symplectic for cmd in cmds: # all operations should be Interferometers or Sgates assert isinstance(cmd.op, (ops.Interferometer, 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.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 assert np.allclose(cov, S @ S.T, atol=tol, rtol=0)
def test_identity(self, tol): """Test identity""" n = 2 S_in = np.identity(2 * n) O1, S, O2 = dec.bloch_messiah(S_in) assert np.allclose(O1 @ O2, np.identity(2 * n), atol=tol, rtol=0) assert np.allclose(S, np.identity(2 * n), atol=tol, rtol=0) # test orthogonality assert np.allclose(O1.T, O1, atol=tol, rtol=0) assert np.allclose(O2.T, O2, atol=tol, rtol=0) # test symplectic O = omega(n) assert np.allclose(O1 @ O @ O1.T, O, atol=tol, rtol=0) assert np.allclose(O2 @ O @ O2.T, O, atol=tol, rtol=0)
def test_active_transform(self, create_transform, tol): """Test passive transform with squeezing""" n = 3 S_in = create_transform(3, passive=False) O1, S, O2 = dec.bloch_messiah(S_in) # test decomposition assert np.allclose(O1 @ S @ O2, S_in, atol=tol, rtol=0) # test orthogonality assert np.allclose(O1.T @ O1, np.identity(2 * n), atol=tol, rtol=0) assert np.allclose(O2.T @ O2, np.identity(2 * n), atol=tol, rtol=0) # test symplectic O = omega(n) assert np.allclose(O1.T @ O @ O1, O, atol=tol, rtol=0) assert np.allclose(O2.T @ O @ O2, O, atol=tol, rtol=0) assert np.allclose(S @ O @ S.T, O, atol=tol, rtol=0)
def test_BM_random_degen_symplectic(self): self.logTestName() for k in range(nsamples): n = 20 S = random_degen_symplectic(n) O, s, Oo = dec.bloch_messiah(S) omega = dec.sympmat(n) self.assertAlmostEqual(np.linalg.norm(S @ omega @ S.T - omega), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(O) @ omega @ O - omega), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(O) @ O - np.identity(2 * n)), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(Oo) @ omega @ Oo - omega), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(Oo) @ Oo - np.identity(2 * n)), 0) self.assertAlmostEqual( np.linalg.norm(np.transpose(s) @ omega @ s - omega), 0) self.assertAlmostEqual(np.linalg.norm(O @ s @ Oo - S), 0)
def test_passive_transform(self, create_transform, tol): """Test passive transform has no squeezing. Note: this test also tests the case with degenerate symplectic values""" n = 3 S_in = create_transform(3, passive=True) O1, S, O2 = dec.bloch_messiah(S_in) # test decomposition assert np.allclose(O1 @ S @ O2, S_in, atol=tol, rtol=0) # test no squeezing assert np.allclose(O1 @ O2, S_in, atol=tol, rtol=0) assert np.allclose(S, np.identity(2 * n), atol=tol, rtol=0) # test orthogonality assert np.allclose(O1.T @ O1, np.identity(2 * n), atol=tol, rtol=0) assert np.allclose(O2.T @ O2, np.identity(2 * n), atol=tol, rtol=0) # test symplectic O = omega(n) # TODO: BUG: # assert np.allclose(O1.T @ O @ O1, O, atol=tol, rtol=0) # assert np.allclose(O2.T @ O @ O2, O, atol=tol, rtol=0) assert np.allclose(S @ O @ S.T, O, atol=tol, rtol=0)
def test_symmplectic(self): """Test raises exception if not symmetric""" A = np.random.random([6, 6]) + 1j * np.random.random([6, 6]) A += A.T with pytest.raises(ValueError, match="matrix is not symplectic"): dec.bloch_messiah(A)
def test_square_validation(self): """Test raises exception if not square""" A = np.random.random([4, 5]) + 1j * np.random.random([4, 5]) with pytest.raises(ValueError, match="matrix is not square"): dec.bloch_messiah(A)