Exemple #1
0
def test_truncations(states, truncations=[10, 15, 20]):
    batch_size = states.shape[0]

    x = tf.placeholder(tf.complex64, shape=[batch_size, 3])

    eng, q = sf.Engine(1)
    with eng:
        Sgate(x[:, 0]) | q[0]
        Dgate(x[:, 1]) | q[0]
        Vgate(x[:, 2]) | q[0]

    sess = tf.Session()
    sess.run(tf.global_variables_initializer())

    traces = np.zeros([batch_size, len(truncations)])
    for n in range(len(truncations)):
        state = eng.run('tf',
                        eval=False,
                        batch_size=batch_size,
                        cutoff_dim=truncations[n])
        trace = tf.real(state.trace())

        traces[:, n] = sess.run(trace, feed_dict={x: states})
        print("Evaluated T={}".format(truncations[n]))

    import matplotlib.pyplot as plt
    for n in range(len(truncations)):
        plt.subplot(len(truncations), 1, n + 1)
        plt.hist(traces[:, n], bins=25)
        plt.xlabel("Trace")
        plt.ylabel("Frequency")
        plt.ylim([0, batch_size])
    plt.show()
def ClosestClassicalState(r, K, eta, U, t):
    M = len(U)
    ap = eta * np.exp(2 * r) + 1 - eta
    an = eta * np.exp(-2 * r) + 1 - eta
    ss = 0.25 * np.log(ap / an)
    ns = 0.5 * (np.sqrt(ap * an) - 1)
    sc = 0.5 * np.log(2 * ns + 1)
    nt = 0.5 - 0.5 * np.sqrt(1 + 2 * t * np.sinh(2 * sc) * np.exp(2 * ss))
    s0 = 0.5 * np.log((2 * nt + 1) / t)
    if ss < s0:
        st = ss
        nt = ns
    else:
        s0 = 0.5 * np.log((2 * nt + 1) / t)
        st = s0

    # build the state
    prog = sf.Program(M)
    with prog.context as q:
        for i in range(K):
            Thermal(nt) | q[i]
            Sgate(st) | q[i]

        Interferometer(U) | q

    eng = sf.Engine('gaussian')
    result = eng.run(prog)
    cov = result.state.cov()
    return cov
    def test_rotation(self, hbar):
        """Test rotation gives correct means and cov"""
        prog = sf.Program(1)
        eng = sf.Engine("gaussian")

        x = 0.2
        p = 0.3
        phi = 0.123
        H, t = rotation(phi, hbar=hbar)

        with prog.context as q:
            Xgate(x) | q[0]
            Zgate(p) | q[0]
            Sgate(2) | q[0]
            GaussianPropagation(H, t) | q[0]

        state = eng.run(prog).state

        # test the covariance matrix
        res = state.cov()
        V = np.diag([np.exp(-4), np.exp(4)]) * hbar / 2
        expected = rot(phi) @ V @ rot(phi).T
        assert np.allclose(res, expected)

        # test the vector of means
        res = state.means()
        exp = rot(phi) @ np.diag(np.exp([-2, 2])) @ np.array([x, p])
        assert np.allclose(res, exp)
Exemple #4
0
 def test_is_unitary_with_channel(self, prog):
     """test that the is_unitary function returns False if channels are present"""
     with prog.context as q:
         Sgate(0.4) | q[0]
         LossChannel(0.4) | q[0]
         BSgate(0.4) | q
     assert not utils.is_unitary(prog)
    def test_displaced_squeezed_mean_photon_gradient(self, setup_eng, cutoff,
                                                     tol, batch_size):
        """Test whether the gradient of the mean photon number of a displaced squeezed
        state is correct.
        """
        if batch_size is not None:
            pytest.skip(
                "Cannot calculate gradient in batch mode, as tape.gradient "
                "cannot differentiate non-scalar output.")

        eng, prog = setup_eng(1)

        with prog.context as q:
            Sgate(prog.params("r"), prog.params("phi")) | q
            Dgate(prog.params("a")) | q

        a = tf.Variable(ALPHA)
        r = tf.Variable(0.105)
        phi = tf.Variable(0.123)

        with tf.GradientTape() as tape:
            state = eng.run(prog, args={"a": a, "r": r, "phi": phi}).state
            mean, _ = state.mean_photon(0)

        # test the mean and variance of the photon number is correct
        mean_ex = a**2 + tf.sinh(r)**2
        assert np.allclose(mean, mean_ex, atol=tol, rtol=0)

        # test the gradient of the mean is correct
        grad = tape.gradient(mean, [a, r, phi])
        grad_ex = [2 * a, 2 * tf.sinh(r) * tf.cosh(r), 0]
        assert np.allclose(grad, grad_ex, atol=tol, rtol=0)
Exemple #6
0
    def test_rotation(self):
        """Test rotation gives correct means and cov"""
        self.eng.reset()
        q = self.eng.register

        x = 0.2
        p = 0.3
        phi = 0.123
        H, t = rotation(phi, hbar=self.hbar)

        with self.eng:
            Xgate(x) | q[0]
            Zgate(p) | q[0]
            Sgate(2) | q[0]
            GaussianPropagation(H, t) | q[0]

        state = self.eng.run('gaussian')

        # test the covariance matrix
        res = state.cov()
        V = np.diag([np.exp(-4), np.exp(4)]) * self.hbar / 2
        expected = rot(phi) @ V @ rot(phi).T
        self.assertTrue(np.allclose(res, expected))

        # test the vector of means
        res = state.means()
        exp = rot(phi) @ np.diag(np.exp([-2, 2])) @ np.array([x, p])
        self.assertTrue(np.allclose(res, exp))
Exemple #7
0
def qnn_layer(layer_number):
    with tf.name_scope('layer_{}'.format(layer_number)):
        BSgate(bs_variables[layer_number, 0, 0, 0], bs_variables[layer_number, 0, 0, 1]) \
        | (q[0], q[1])

        for i in range(mode_number):
            Rgate(phase_variables[layer_number, i, 0]) | q[i]

        for i in range(mode_number):
            Sgate(
                tf.clip_by_value(sq_magnitude_variables[layer_number, i],
                                 -sq_clip, sq_clip),
                sq_phase_variables[layer_number, i]) | q[i]

        BSgate(bs_variables[layer_number, 0, 1, 0], bs_variables[layer_number, 0, 1, 1]) \
        | (q[0], q[1])

        for i in range(mode_number):
            Rgate(phase_variables[layer_number, i, 1]) | q[i]

        for i in range(mode_number):
            Dgate(
                tf.clip_by_value(disp_magnitude_variables[layer_number, i],
                                 -disp_clip, disp_clip),
                disp_phase_variables[layer_number, i]) | q[i]

        for i in range(mode_number):
            Kgate(
                tf.clip_by_value(kerr_variables[layer_number, i], -kerr_clip,
                                 kerr_clip)) | q[i]
Exemple #8
0
 def test_is_unitary_no_channel(self, prog):
     """test that the is_unitary function returns True if no channels are present"""
     assert utils.is_unitary(prog)
     with prog.context as q:
         Sgate(0.4) | q[0]
         BSgate(0.4) | q
     assert utils.is_unitary(prog)
Exemple #9
0
 def test_is_channel_preparation(self, prog):
     """is_channel() returns False if preparations are present"""
     with prog.context as q:
         Sgate(0.4) | q[0]
         BSgate() | q
         Squeezed(0.4) | q[1]
     assert not utils.is_channel(prog)
def test_cov_is_pure():
    """Tests space unrolling when going into the Gaussian backend"""
    delays = [1, 6, 36]
    modes = 216
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])
    net = modes + sum(delays)
    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])
    vac_modes = sum(delays)

    with prog.context(*angles) as (p, q):
        Sgate(0.8) | q[n[0]]
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    prog.space_unroll()

    eng = sf.Engine(backend="gaussian")
    results = eng.run(prog)
    cov = results.state.cov()
    mu = np.zeros(len(cov))
    mu_vac, cov_vac = reduced_state(mu, cov, list(range(vac_modes)))
    mu_comp, cov_comp = reduced_state(mu, cov, list(range(vac_modes, net)))
    assert np.allclose(cov_vac, 0.5 * (sf.hbar) * np.identity(2 * vac_modes))
    assert is_pure_cov(cov_comp, hbar=sf.hbar)
Exemple #11
0
    def layer(i, size):
        Rgate(rtheta_1[i, 0]) | (q[0])
        BSgate(phi_1[i, 0], 0) | (q[0], q[1])
        Rgate(rtheta_1[i, 2]) | (q[1])

        for j in range(size):
            Sgate(r[i, j]) | q[j]

        Rgate(rtheta_2[i, 0]) | (q[0])
        BSgate(phi_2[i, 0], 0) | (q[0], q[1])
        Rgate(rtheta_2[i, 2]) | (q[2])
        BSgate(phi_2[i, 2], theta_2[i, 3]) | (q[2], q[3])
        Rgate(rtheta_2[i, 1]) | (q[1])
        BSgate(phi_2[i, 1], 0) | (q[1], q[2])
        Rgate(rtheta_2[i, 0]) | (q[0])
        BSgate(phi_2[i, 0], 0) | (q[0], q[1])
        Rgate(rtheta_2[i, 0]) | (q[0])
        Rgate(rtheta_2[i, 1]) | (q[1])
        Rgate(rtheta_2[i, 2]) | (q[2])
        Rgate(rtheta_2[i, 3]) | (q[3])
        BSgate(phi_2[i, 2], 0) | (q[2], q[3])
        Rgate(rtheta_2[i, 2]) | (q[2])
        BSgate(phi_2[i, 1], 0) | (q[1], q[2])
        Rgate(rtheta_2[i, 1]) | (q[1])

        for j in range(size):
            Kgate(kappa[i, j]) | q[j]
 def test_is_channel_no_measurement(self, prog):
     """test that the is_channel function returns True if no measurements are present"""
     assert utils.is_channel(prog)
     with prog.context as q:
         Sgate(0.4) | q[0]
         LossChannel(0.4) | q[0]
         BSgate(0.4) | q
     assert utils.is_channel(prog)
def input_qnn_layer():
    with tf.name_scope('inputlayer'):
        Sgate(tf.clip_by_value(output_layer[:, 0], -sq_clip, sq_clip), output_layer[:, 1]) | q[0]
        Sgate(tf.clip_by_value(output_layer[:, 2], -sq_clip, sq_clip), output_layer[:, 3]) | q[1]

        BSgate(output_layer[:, 4], output_layer[:, 5]) | (q[0], q[1])

        Rgate(output_layer[:, 6]) | q[0]
        Rgate(output_layer[:, 7]) | q[1]

        Dgate(tf.clip_by_value(output_layer[:, 8], -disp_clip, disp_clip), output_layer[:, 9]) \
        | q[0]
        Dgate(tf.clip_by_value(output_layer[:, 10], -disp_clip, disp_clip), output_layer[:, 11]) \
        | q[0]

        Kgate(tf.clip_by_value(output_layer[:, 12], -kerr_clip, kerr_clip)) | q[0]
        Kgate(tf.clip_by_value(output_layer[:, 13], -kerr_clip, kerr_clip)) | q[0]
Exemple #14
0
    def test_is_channel_no_measurement(self):
        """test that the is_channel function returns True if no measurements are present"""
        eng, q = sf.Engine(2)

        assert utils.is_channel(eng)

        with eng:
            Sgate(0.4) | q[0]
            BSgate(0.4) | q

        assert utils.is_channel(eng)

        with eng:
            Sgate(0.4) | q[0]
            LossChannel(0.4) | q[0]
            BSgate(0.4) | q

        assert utils.is_channel(eng)
Exemple #15
0
    def test_is_unitary_with_channel(self):
        """test that the is_unitary function returns False if channels are present"""
        eng, q = sf.Engine(2)

        with eng:
            Sgate(0.4) | q[0]
            LossChannel(0.4) | q[0]
            BSgate(0.4) | q

        assert not utils.is_unitary(eng)
def circuit(A, n_qmodes, params):
    I = np.eye(2 * n_qmodes)

    X_top = np.hstack((np.zeros((n_qmodes, n_qmodes)), np.eye(n_qmodes)))
    X_bot = np.hstack((np.eye(n_qmodes), np.zeros((n_qmodes, n_qmodes))))

    X = np.vstack((X_top, X_bot))

    # c = 0
    # A = np.array([[c,-2,-10,1],
    #               [-2,c,1,5],
    #               [-10,1,c,-2],
    #               [1,5,-2,c]])
    zeros_4 = np.zeros((n_qmodes, n_qmodes))
    c_prim = 1
    A_prim = np.vstack((np.hstack((zeros_4, A)), np.hstack(
        (A, zeros_4)))) + np.eye(2 * n_qmodes) * c_prim

    d = 0.05
    # Cov = np.linalg.inv(I - X@(d*A)) - I/2
    Cov = np.linalg.inv(I - X @ (d * A_prim)) - I / 2

    eng, q = sf.Engine(n_qmodes)

    with eng:
        # beamsplitter array
        Gaussian(Cov) | q

        Sgate(params[0]) | q[0]
        Sgate(params[1]) | q[1]
        Sgate(params[2]) | q[2]
        Sgate(params[3]) | q[3]

        Dgate(params[4]) | q[0]
        Dgate(params[5]) | q[1]
        Dgate(params[6]) | q[2]
        Dgate(params[7]) | q[3]

        BSgate(params[8], params[9]) | (q[0], q[1])
        BSgate(params[10], params[11]) | (q[2], q[3])
        BSgate(params[12], params[13]) | (q[1], q[2])

    return eng, q
Exemple #17
0
    def test_is_unitary_no_channel(self):
        """test that the is_unitary function returns True if no channels are present"""
        eng, q = sf.Engine(2)

        assert utils.is_unitary(eng)

        with eng:
            Sgate(0.4) | q[0]
            BSgate(0.4) | q

        assert utils.is_unitary(eng)
Exemple #18
0
    def test_is_channel_measurement(self):
        """test that the is_channel function returns False if measurements
        or preparations are present"""
        eng, q = sf.Engine(2)

        with eng:
            Sgate(0.4) | q[0]
            BSgate() | q
            MeasureX | q[0]
            Sgate(0.4) | q[1]

        assert not utils.is_channel(eng)

        eng.reset()

        with eng:
            Sgate(0.4) | q[0]
            BSgate() | q
            Squeezed(0.4) | q[1]

        assert not utils.is_channel(eng)
Exemple #19
0
    def H_circuit(self, H, t):
        """Test circuit for Gaussian Hamiltonian"""
        self.eng.reset()
        q = self.eng.register
        with self.eng:
            # pylint: disable=pointless-statement
            q = init_layer(q)
            Xgate(0.1) | q[2]
            Sgate(0.1) | q[2]
            GaussianPropagation(H, t, mode='global') | q

        state = self.eng.run('gaussian')
        return state.means(), state.cov()
Exemple #20
0
    def ref_circuit(self, gate, qm):
        """Reference circuit for Gaussian gate"""
        self.eng.reset()
        q = self.eng.register
        with self.eng:
            # pylint: disable=pointless-statement
            q = init_layer(q)
            Xgate(0.1) | q[2]
            Sgate(0.1) | q[2]
            gate | qm

        state = self.eng.run('gaussian')
        return state.means(), state.cov()
    def H_circuit(self, H, t):
        """Test circuit for Gaussian Hamiltonian"""
        prog = sf.Program(3)
        eng = sf.Engine("gaussian")

        with prog.context as q:
            # pylint: disable=pointless-statement
            q = init_layer(q)
            Xgate(0.1) | q[2]
            Sgate(0.1) | q[2]
            GaussianPropagation(H, t, mode='global') | q

        state = eng.run(prog).state
        return state.means(), state.cov()
    def ref_circuit(self, gate, qm):
        """Reference circuit for Gaussian gate"""
        prog = sf.Program(3)
        eng = sf.Engine("gaussian")

        with prog.context as q:
            # pylint: disable=pointless-statement
            q = init_layer(q)
            Xgate(0.1) | q[2]
            Sgate(0.1) | q[2]
            gate | qm

        state = eng.run(prog).state
        return state.means(), state.cov()
    def test_raises_gaussian_no_cutoff(self, monkeypatch):
        """Test that an error is raised if not cutoff value is specified for a
        Gaussian state."""
        prog = sf.Program(1)
        eng = sf.Engine("gaussian")

        with prog.context as q:
            Sgate(2) | q[0]

        state = eng.run(prog).state
        modes = [0]

        with monkeypatch.context() as m:
            # Avoid plotting even if the test failed
            m.setattr(pio, "show", lambda x: None)
            with pytest.raises(ValueError, match="No cutoff specified for"):
                sf.plot_fock(state, modes, renderer="browser")
    def test_global(self, eng, tol):
        """Test a 1x2 lattice Bose-Hubbard model in global mode"""
        prog = sf.Program(3)

        with prog.context as q:
            Sgate(0.1) | q[2]
            Fock(2) | q[0]
            BoseHubbardPropagation(self.H, self.t, self.k, mode='global') | q

        state = eng.run(prog, run_options={"modes": [0, 1]}).state

        Hm = -self.J*np.sqrt(2)*np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]]) \
            + self.U*np.diag([1, 0, 1])
        init_state = np.array([1, 0, 0])
        exp = np.abs(np.dot(expm(-1j * self.t * Hm), init_state))**2

        assert np.allclose(state.fock_prob([2, 0]), exp[0], rtol=tol)
        assert np.allclose(state.fock_prob([1, 1]), exp[1], rtol=tol)
        assert np.allclose(state.fock_prob([0, 2]), exp[2], rtol=tol)
    def test_displaced_squeezed_mean_photon_gradient(self, setup_eng, cutoff, tol, batch_size):
        """Test whether the gradient of the mean photon number of a displaced squeezed
        state is correct.

        .. note::

            As this test contains multiple gates being applied to the program,
            this test will fail in TensorFlow 2.1 due to the bug discussed in
            https://github.com/tensorflow/tensorflow/issues/37307, if `tf.einsum` is being used
            in ``tfbackend/ops.py`` rather than _einsum_v1.
        """
        if batch_size is not None:
            pytest.skip(
                "Cannot calculate gradient in batch mode, as tape.gradient "
                "cannot differentiate non-scalar output."
            )

        eng, prog = setup_eng(1)

        with prog.context as q:
            Sgate(prog.params("r"), prog.params("phi")) | q
            Dgate(prog.params("a")) | q

        a = tf.Variable(ALPHA)
        r = tf.Variable(0.105)
        phi = tf.Variable(0.123)

        with tf.GradientTape() as tape:
            state = eng.run(prog, args={"a": a, "r": r, "phi": phi}).state
            mean, _ = state.mean_photon(0)

        # test the mean and variance of the photon number is correct
        mean_ex = a ** 2 + tf.sinh(r) ** 2
        assert np.allclose(mean, mean_ex, atol=tol, rtol=0)

        # test the gradient of the mean is correct
        grad = tape.gradient(mean, [a, r, phi])
        grad_ex = [2 * a, 2 * tf.sinh(r) * tf.cosh(r), 0]
        assert np.allclose(grad, grad_ex, atol=tol, rtol=0)
def test_space_unrolling():
    """Tests that space-unrolling works and that it can be done twice"""
    delays = [1, 6, 36]
    modes = 216
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])

    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])

    with prog.context(*angles) as (p, q):
        Sgate(0.8) | q[n[0]]
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    assert prog.is_unrolled == False

    prog.space_unroll()

    assert prog.timebins == 259
    vac_modes = prog.concurr_modes - 1
    assert prog.num_subsystems == prog.timebins + vac_modes

    # check that the number of gates are correct.
    assert [isinstance(cmd.op, Sgate)
            for cmd in prog.circuit].count(True) == prog.timebins
    assert [isinstance(cmd.op, Rgate)
            for cmd in prog.circuit].count(True) == 259 * len(delays)
    assert [isinstance(cmd.op, BSgate)
            for cmd in prog.circuit].count(True) == 259 * len(delays)

    prog.space_unroll()

    # space-unroll the program twice to check that it works
    assert prog.is_unrolled == True
def test_rolling_space_unrolled():
    """Tests that rolling a space-unrolled circuit works"""
    delays = [1, 6, 36]
    modes = 216
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])

    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])

    with prog.context(*angles) as (p, q):
        Sgate(0.8) | q[n[0]]
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    rolled_circuit = prog.circuit.copy()
    num_subsystems_pre_roll = prog.num_subsystems
    init_num_subsystems_pre_roll = prog.init_num_subsystems

    assert prog.is_unrolled == False

    # space-unroll the program
    prog.space_unroll()

    assert prog.is_unrolled == True

    # roll the program back up
    prog.roll()

    assert prog.is_unrolled == False
    assert prog.num_subsystems == num_subsystems_pre_roll
    assert prog.init_num_subsystems == init_num_subsystems_pre_roll

    assert len(prog.circuit) == len(rolled_circuit)
    assert prog.circuit == rolled_circuit
Exemple #28
0
    def test_local(self):
        """Test a 1x2 lattice Bose-Hubbard model in local mode"""
        self.eng.reset()
        q = self.eng.register

        with self.eng:
            Sgate(0.1) | q[1]
            Fock(2) | q[0]
            BoseHubbardPropagation(self.H, self.t, self.k) | (q[0], q[2])

        state = self.eng.run('fock', cutoff_dim=7, modes=[0, 2])

        Hm = -self.J*np.sqrt(2)*np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]]) \
            + self.U*np.diag([1, 0, 1])
        init_state = np.array([1, 0, 0])
        exp = np.abs(np.dot(expm(-1j * self.t * Hm), init_state))**2

        self.assertTrue(
            np.allclose(state.fock_prob([2, 0]), exp[0], rtol=self.tol))
        self.assertTrue(
            np.allclose(state.fock_prob([1, 1]), exp[1], rtol=self.tol))
        self.assertTrue(
            np.allclose(state.fock_prob([0, 2]), exp[2], rtol=self.tol))
 def dummy_func(r, theta, phi, q):
     Sgate(r) | q[0]
     BSgate(theta, phi) | (q[0], q[1])
 def dummy_func(q):
     Sgate(rval) | q[0]