Esempio n. 1
0
def rescale_adjacency(A: np.ndarray, n_mean: float,
                      threshold: bool) -> np.ndarray:
    """Rescale an adjacency matrix so that it can be mapped to GBS.

    An adjacency matrix must have singular values not exceeding one if it can be mapped to GBS.
    Arbitrary adjacency matrices must first be rescaled to satisfy this condition.

    This function rescales an input adjacency matrix :math:`A` so that the corresponding gaussian
    state has:

    - a mean number of *clicks* equal to ``n_mean`` when ``threshold=True``;
    - a mean number of *photons* equal to ``n_mean`` when ``threshold=False``.

    **Example usage:**

    >>> a = np.ones((3, 3))
    >>> rescale_adjacency(a, 2, True)
    array([[0.32232919, 0.32232919, 0.32232919],
           [0.32232919, 0.32232919, 0.32232919],
           [0.32232919, 0.32232919, 0.32232919]])

    Args:
        A (array): the adjacency matrix to rescale
        n_mean (float): the target mean number of clicks or mean number of photons
        threshold (bool): determines whether rescaling is for a target mean number of clicks or
            photons

    Returns:
        array: the rescaled adjacency matrix
    """
    scale = rescale_tor(A, n_mean) if threshold else rescale(A, n_mean)
    return A * scale
Esempio n. 2
0
def test_rescale_adjacency():
    """Test for the ``train.param.rescale_adjacency`` function. We find the rescaled
    adjacency matrix when using threshold and PNR detection and check that: (i) the two matrices
    are not the same, (ii) they are rescaled by the correct factor."""
    adj = np.ones((10, 10))
    n_mean = 5

    r1 = train.param.rescale_adjacency(adj, n_mean, True)
    r2 = train.param.rescale_adjacency(adj, n_mean, False)
    s1 = rescale_tor(adj, n_mean)
    s2 = rescale(adj, n_mean)

    assert not np.allclose(r1, r2)
    assert np.allclose(r1, s1 * adj)
    assert np.allclose(r2, s2 * adj)
Esempio n. 3
0
    def apply(self, operation, wires, par):
        self._params, A, n_mean = par
        A *= rescale(A, n_mean)
        self.Z_inv = self._calculate_z_inv(A)

        if len(self._params) != self.num_wires:
            raise ValueError(
                "The number of variable parameters must be equal to the total number of wires."
            )

        self._WAW = self.calculate_WAW(self._params, A)

        if self.shots is not None and self._use_cache:
            op = GraphEmbed(A, mean_photon_per_mode=n_mean / len(A))
        else:
            n_mean_WAW = self.calculate_n_mean(self._WAW)
            op = GraphEmbed(self._WAW, mean_photon_per_mode=n_mean_WAW / len(A))

        op | [self.q[wires.index(i)] for i in wires]

        if self.shots is not None:
            MeasureFock() | [self.q[wires.index(i)] for i in wires]