def test_rescaling_thermal():
    r"""Test that the rescaled eigenvalues of the matrix give the correct mean photon number for thermal rescaling"""

    n = 10
    A = generate_positive_definite_matrix(n)
    n_mean = 1.0
    ls, _ = rescale_adjacency_matrix_thermal(A, n_mean)
    assert np.allclose(n_mean, np.sum(ls / (1 - ls)))
def test_mean_thermal():
    r"""Test that the thermal samples have the correct mean photon number"""
    n = 10
    n_samples = 100000
    A = generate_positive_definite_matrix(n)
    n_mean = 10.0
    ls, O = rescale_adjacency_matrix_thermal(A, n_mean)
    samples = np.array(generate_thermal_samples(ls, O, num_samples=n_samples))
    tot_photon_sample = np.sum(samples, axis=1)
    n_mean_calc = tot_photon_sample.mean()
    assert np.allclose(n_mean_calc, n_mean, rtol=10 / np.sqrt(n_samples))
def test_dist_thermal():
    r"""Test that the thermal sampling for a single mode produces the correct photon number distribution"""
    n_samples = 100000
    n_mean = 1.0
    A = generate_positive_definite_matrix(1)
    ls, O = rescale_adjacency_matrix_thermal(A, n_mean)

    samples = np.array(generate_thermal_samples(ls, O, num_samples=n_samples))
    bins = np.arange(0, max(samples), 1)
    (freq, _) = np.histogram(samples, bins=bins)
    rel_freq = freq / n_samples
    expected = (1 / (1 + n_mean)) * (n_mean /
                                     (1 + n_mean))**(np.arange(len(rel_freq)))
    assert np.allclose(rel_freq, expected, atol=10 / np.sqrt(n_samples))
Ejemplo n.º 4
0
def sample(K: np.ndarray, n_mean: float, n_samples: int) -> list:
    """Sample subsets of points using the permanental point process.

    Points are encoded through a radial basis function kernel, provided in :func:`kernel`,
    that is a function of the distance between pairs of points. Subsets of points are sampled
    with probabilities that are proportional to the permanent of the *sub*matrix of the kernel
    selected by those points.

    This permanental point process is likely to sample points that are clustered together
    :cite:`jahangiri2019point`. It can be realised using a variant of Gaussian boson sampling
    with thermal states as input.

    **Example usage:**

    >>> K = np.array([[1., 0.36787944, 0.60653066, 0.60653066],
    >>>               [0.36787944, 1., 0.60653066, 0.60653066],
    >>>               [0.60653066, 0.60653066, 1., 0.36787944],
    >>>               [0.60653066, 0.60653066, 0.36787944, 1.]])
    >>> sample(K, 1.0, 10)
    [[0, 1, 1, 1],
     [0, 0, 0, 0],
     [1, 0, 0, 0],
     [0, 0, 0, 1],
     [0, 1, 1, 0],
     [2, 0, 0, 0],
     [0, 0, 0, 0],
     [0, 0, 0, 0],
     [0, 0, 1, 1],
     [0, 0, 0, 0]]

    Args:
        K (array): the kernel matrix
        n_mean (float): average number of points
        n_samples (int): number of samples to be generated

    Returns:
        samples (list[list[int]]): samples generated by the point process
    """
    ls, O = rescale_adjacency_matrix_thermal(K, n_mean)
    return np.array(generate_thermal_samples(ls, O,
                                             num_samples=n_samples)).tolist()
def test_number_moments_multimode_thermal(nmodes):
    r"""Test the correct values of the photon number means and covariances"""
    # This test requires nmodes > 1
    n_samples = 100000
    n_mean = 3.0
    A = generate_positive_definite_matrix(nmodes)
    ls, O = rescale_adjacency_matrix_thermal(A, n_mean)
    Nmat = O @ np.diag(ls / (1.0 - ls)) @ O.T
    samples = np.array(generate_thermal_samples(ls, O, n_samples))

    nmean_est = samples.mean(axis=0)
    cov_est = np.cov(samples.T)
    expected_cov = np.zeros_like(cov_est)
    for i in range(nmodes):
        for j in range(i):
            expected_cov[i, j] = Nmat[i, i] * Nmat[j, j] + Nmat[i, j]**2
            expected_cov[j, i] = expected_cov[i, j]
        expected_cov[i, i] = 2 * (Nmat[i, i]**2) + Nmat[i, i]
    ## These moments are obtained using Wick's theorem for a multimode thermal state
    expected_cov = expected_cov - np.outer(np.diag(Nmat), np.diag(Nmat))
    # To construct the covariance matrix we need to subtract the projector onto the mean
    assert np.allclose(nmean_est, np.diag(Nmat), rtol=20 / np.sqrt(n_samples))
    assert np.allclose(expected_cov, cov_est, rtol=20 / np.sqrt(n_samples))