예제 #1
0
    def measure_fock(self, modes, shots=1, select=None, **kwargs):
        if select is not None:
            raise NotImplementedError(
                "Gaussian backend currently does not support "
                "postselection")
        if shots != 1:
            warnings.warn(
                "Cannot simulate non-Gaussian states. "
                "Conditional state after Fock measurement has not been updated."
            )

        mu = self.circuit.mean
        mean = self.circuit.smeanxp()
        cov = self.circuit.scovmatxp()

        x_idxs = array(modes)
        p_idxs = x_idxs + len(mu)
        modes_idxs = concatenate([x_idxs, p_idxs])
        reduced_cov = cov[ix_(modes_idxs, modes_idxs)]
        reduced_mean = mean[modes_idxs]

        # check we are sampling from a gaussian state with zero mean
        if allclose(mu, zeros_like(mu)):
            samples = hafnian_sample_state(reduced_cov, shots)
        else:
            samples = hafnian_sample_state(reduced_cov,
                                           shots,
                                           mean=reduced_mean)

        return samples
예제 #2
0
    def measure_fock(self, modes, shots=1, select=None):
        if shots != 1:
            if select is not None:
                raise NotImplementedError(
                    "Gaussian backend currently does not support "
                    "postselection")
            warnings.warn(
                "Cannot simulate non-Gaussian states. "
                "Conditional state after Fock measurement has not been updated."
            )

        mu = self.circuit.mean
        mean = self.circuit.smeanxp()
        cov = self.circuit.scovmatxp()

        x_idxs = array(modes)
        p_idxs = x_idxs + len(mu)
        modes_idxs = concatenate([x_idxs, p_idxs])
        reduced_cov = cov[ix_(modes_idxs, modes_idxs)]
        reduced_mean = mean[modes_idxs]
        # check we are sampling from a gaussian state with zero mean
        if allclose(mu, zeros_like(mu)):
            samples = hafnian_sample_state(reduced_cov, shots)
        else:
            samples = hafnian_sample_state(reduced_cov,
                                           shots,
                                           mean=reduced_mean)
        # for backward compatibility with previous measurement behaviour,
        # if only one shot, then we drop the shots axis
        if shots == 1:
            samples = samples.reshape((len(modes), ))
        return samples
예제 #3
0
def test_seed():
    """Tests that seed method does reset the random number generators"""
    n_samples = 10
    mean_n = 1.0
    r = np.arcsinh(np.sqrt(mean_n))
    V = np.array([[np.exp(2 * r), 0.0], [0.0, np.exp(-2 * r)]])
    seed(137)
    first_sample = hafnian_sample_state(V, n_samples)
    second_sample = hafnian_sample_state(V, n_samples)
    seed(137)
    first_sample_p = hafnian_sample_state(V, n_samples)
    second_sample_p = hafnian_sample_state(V, n_samples)
    assert np.array_equal(first_sample, first_sample_p)
    assert np.array_equal(second_sample, second_sample_p)
예제 #4
0
    def test_single_squeezed_state_hafnian(self):
        """Test the sampling routines by comparing the photon number frequencies and the exact
        probability distribution of a single mode squeezed vacuum state
        """
        n_samples = 1000
        mean_n = 1.0
        r = np.arcsinh(np.sqrt(mean_n))
        sigma = np.array([[np.exp(2 * r), 0.0], [0.0, np.exp(-2 * r)]])

        n_cut = 10
        samples = hafnian_sample_state(sigma, samples=n_samples, cutoff=n_cut)
        bins = np.arange(0, max(samples) + 1, 1)
        (freq, _) = np.histogram(samples, bins=bins)
        rel_freq = freq / n_samples
        nm = max(samples) // 2

        x = nbinom.pmf(np.arange(0, nm, 1), 0.5,
                       np.tanh(np.arcsinh(np.sqrt(mean_n)))**2)
        x2 = np.zeros(2 * len(x))
        x2[::2] = x
        rel_freq = freq[0:-1] / n_samples
        x2 = x2[0:len(rel_freq)]

        assert np.allclose(rel_freq,
                           x2,
                           atol=rel_tol / np.sqrt(n_samples),
                           rtol=rel_tol / np.sqrt(n_samples))
예제 #5
0
 def test_TMS_hafnian_sample_states_cutoff(self):
     """test sampling from TMS hafnians is correlated"""
     m = 0.432
     phi = 0.546
     V = TMS_cov(np.arcsinh(m), phi)
     res = hafnian_sample_state(V, samples=20, cutoff=5)
     assert np.allclose(res[:, 0], res[:, 1])
예제 #6
0
 def test_hafnian_state_lowmax(self, max_photons):
     """test sampling never exceeds max photons for hafnian"""
     m = 0.432
     phi = 0.546
     V = TMS_cov(np.arcsinh(m), phi)
     res = hafnian_sample_state(V, samples=10, max_photons=max_photons)
     assert np.max(res) <= max_photons
예제 #7
0
    def test_displaced_two_mode_squeezed_state_hafnian(self):
        """Test the sampling routines by comparing the photon number frequencies and the exact
        probability distribution of a displaced two mode squeezed vacuum state
        """
        n_samples = 1000
        n_cut = 10
        mean_n = 1
        r = np.arcsinh(np.sqrt(mean_n))
        c = np.cosh(2 * r)
        s = np.sinh(2 * r)
        sigma = np.array([[c, s, 0, 0], [s, c, 0, 0], [0, 0, c, -s],
                          [0, 0, -s, c]])
        mean = 2 * np.array([0.1, 0.25, 0.1, 0.25])
        samples = hafnian_sample_state(sigma,
                                       samples=n_samples,
                                       mean=mean,
                                       cutoff=n_cut)

        probs = np.real_if_close(
            np.array([[
                density_matrix_element(mean, sigma, [i, j], [i, j])
                for i in range(n_cut)
            ] for j in range(n_cut)]))
        freq, _, _ = np.histogram2d(samples[:, 1],
                                    samples[:, 0],
                                    bins=np.arange(0, n_cut + 1))
        rel_freq = freq / n_samples

        assert np.allclose(rel_freq,
                           probs,
                           rtol=rel_tol / np.sqrt(n_samples),
                           atol=rel_tol / np.sqrt(n_samples))
예제 #8
0
    def test_two_mode_squeezed_state_hafnian(self):
        """Test the sampling routines by comparing the photon number frequencies and the exact
        probability distribution of a two mode squeezed vacuum state
        """
        n_samples = 1000
        n_cut = 5
        mean_n = 1.0
        r = np.arcsinh(np.sqrt(mean_n))
        c = np.cosh(2 * r)
        s = np.sinh(2 * r)
        sigma = np.array([[c, s, 0, 0], [s, c, 0, 0], [0, 0, c, -s],
                          [0, 0, -s, c]])

        samples = hafnian_sample_state(sigma, samples=n_samples, cutoff=n_cut)
        assert np.all(samples[:, 0] == samples[:, 1])

        samples1d = samples[:, 0]
        bins = np.arange(0, max(samples1d) + 1, 1)

        (freq, _) = np.histogram(samples1d, bins=bins)
        rel_freq = freq / n_samples

        probs = (1.0 / (1.0 + mean_n)) * (mean_n / (1.0 + mean_n))**bins[0:-1]
        probs[-1] = 1.0 - np.sum(
            probs[0:-1]
        )  # Coarse grain all the probabilities past the threshold

        assert np.allclose(rel_freq,
                           probs,
                           atol=rel_tol / np.sqrt(n_samples),
                           rtol=rel_tol / np.sqrt(n_samples))
예제 #9
0
 def test_hafnian_sample_states_nans(self):
     """test exception is raised if not a numpy array"""
     with pytest.raises(ValueError,
                        match="Covariance matrix must not contain NaNs."):
         hafnian_sample_state(np.array([[0, 5], [0, np.NaN]]), samples=20)
예제 #10
0
 def test_hafnian_sample_states_nonsquare(self):
     """test exception is raised if not a numpy array"""
     with pytest.raises(ValueError,
                        match="Covariance matrix must be square."):
         hafnian_sample_state(np.array([[0, 5, 3], [0, 1, 2]]), samples=20)
예제 #11
0
 def test_hafnian_sample_states_nonnumpy(self):
     """test exception is raised if not a numpy array"""
     with pytest.raises(TypeError):
         hafnian_sample_state(5, samples=20)