Exemple #1
0
    def test_dm_two_mode(self, setup_eng, hbar, cutoff, tol):
        """Tests multimode dm preparation"""
        eng, prog = setup_eng(2)

        ket0 = np.random.uniform(
            -1, 1, cutoff) + 1j * np.random.uniform(-1, 1, cutoff)
        ket0 = ket0 / np.linalg.norm(ket0)
        ket1 = np.random.uniform(
            -1, 1, cutoff) + 1j * np.random.uniform(-1, 1, cutoff)
        ket1 = ket1 / np.linalg.norm(ket1)

        ket = np.outer(ket0, ket1)
        rho = np.einsum("ij,kl->ikjl", ket, ket.conj())
        with prog.context as q:
            ops.DensityMatrix(rho) | q
        state = eng.run(prog).state
        assert np.allclose(state.dm(), rho, atol=tol, rtol=0)

        eng.reset()

        prog = sf.Program(2)
        state1 = BaseFockState(rho, 2, False, cutoff)
        with prog.context as q:
            ops.DensityMatrix(state1) | q
        state2 = eng.run(prog).state
        assert np.allclose(state1.dm(), state2.dm(), atol=tol, rtol=0)
    def probability(self, wires=None):
        """Return the (marginal) probability of each computational basis
        state from the last run of the device.

        Args:
            wires (Iterable[Number, str], Number, str, Wires): wires to return
                marginal probabilities for. Wires not provided
                are traced out of the system.

        Returns:
            OrderedDict[tuple, float]: Dictionary mapping a tuple representing the state
            to the resulting probability. The dictionary should be sorted such that the
            state tuples are in lexicographical order.
        """
        wires = wires or self.wires
        # convert to a wires object
        wires = Wires(wires)
        # translate to wires used by device
        device_wires = self.map_wires(wires)

        N = len(wires)
        cutoff = getattr(self, "cutoff", 10)

        if N == self.state.num_modes:
            # probabilities of the entire system
            probs = self.state.all_fock_probs(cutoff=cutoff).flat

        else:
            if isinstance(self.state, BaseFockState):
                rdm = self.state.reduced_dm(modes=device_wires.tolist())
                new_state = BaseFockState(rdm,
                                          N,
                                          pure=False,
                                          cutoff_dim=cutoff)

            elif isinstance(self.state, BaseGaussianState):
                # Reduced Gaussian state
                mu, cov = self.state.reduced_gaussian(
                    modes=device_wires.tolist())

                # scale so that hbar = 2
                mu /= np.sqrt(sf.hbar / 2)
                cov /= sf.hbar / 2

                # create reduced Gaussian state
                new_state = BaseGaussianState((mu, cov), N)

            probs = new_state.all_fock_probs(cutoff=cutoff).flat

        ind = np.indices([cutoff] * N).reshape(N, -1).T
        probs = OrderedDict((tuple(k), v) for k, v in zip(ind, probs))
        return probs
Exemple #3
0
    def test_ket_one_mode(self, setup_eng, hbar, cutoff, tol):
        """Tests single mode ket preparation"""
        eng, prog = setup_eng(2)
        ket0 = np.random.uniform(-1, 1, cutoff) + 1j * np.random.uniform(-1, 1, cutoff)
        ket0 = ket0 / np.linalg.norm(ket0)
        with prog.context as q:
            ops.Ket(ket0) | q[0]
        state = eng.run(prog, modes=[0])
        assert np.allclose(state.dm(), np.outer(ket0, ket0.conj()), atol=tol, rtol=0)

        eng.reset()

        prog = sf.Program(2)
        state1 = BaseFockState(ket0, 1, True, cutoff, hbar)
        with prog.context as q:
            ops.Ket(state1) | q[0]
        state2 = eng.run(prog, modes=[0])
        assert np.allclose(state1.dm(), state2.dm(), atol=tol, rtol=0)
    def state(self, modes=None, **kwargs):
        s, pure = self.circuit.get_state()

        if modes is None:
            # reduced state is full state
            red_state = s
            num_modes = len(s.shape) if pure else len(s.shape) // 2
            modes = [m for m in range(num_modes)]
        else:
            # convert to mixed state representation
            if pure:
                num_modes = len(s.shape)
                left_str = [indices[i] for i in range(0, 2 * num_modes, 2)]
                right_str = [indices[i] for i in range(1, 2 * num_modes, 2)]
                out_str = [indices[: 2 * num_modes]]
                einstr = ''.join(left_str + [','] + right_str + ['->'] + out_str)
                rho = np.einsum(einstr, s, s.conj())
            else:
                rho = s

            # reduce rho down to specified subsystems
            if isinstance(modes, int):
                modes = [modes]

            if len(modes) != len(set(modes)):
                raise ValueError("The specified modes cannot be duplicated.")

            num_modes = len(rho.shape) // 2
            if len(modes) > num_modes:
                raise ValueError("The number of specified modes cannot be larger than the number of subsystems.")

            keep_indices = indices[: 2 * len(modes)]
            trace_indices = indices[2 * len(modes) : len(modes) + num_modes]
            ind = [i * 2 for i in trace_indices]
            ctr = 0

            for m in range(num_modes):
                if m in modes:
                    ind.insert(m, keep_indices[2 * ctr : 2 * (ctr + 1)])
                    ctr += 1

            indStr = ''.join(ind) + '->' + keep_indices
            red_state = np.einsum(indStr, rho)

            # permute indices of returned state to reflect the ordering of modes (we know and hence can assume that red_state is a mixed state)
        if modes != sorted(modes):
            mode_permutation = np.argsort(modes)
            index_permutation = [2*x+i for x in mode_permutation for i in (0, 1)]
            red_state = np.transpose(red_state, np.argsort(index_permutation))

        cutoff = self.circuit._trunc
        mode_names = ["q[{}]".format(i) for i in np.array(self.get_modes())[modes]]
        state = BaseFockState(red_state, len(modes), pure, cutoff, mode_names)
        return state
Exemple #5
0
    def test_dm_one_mode(self, setup_eng, hbar, cutoff, tol):
        """Tests single mode DM preparation"""
        eng, prog = setup_eng(2)

        ket = np.random.uniform(-1, 1, cutoff) + 1j * np.random.uniform(-1, 1, cutoff)
        ket = ket / np.linalg.norm(ket)
        rho = np.outer(ket, ket.conj())
        with prog.context as q:
            ops.DensityMatrix(rho) | q[0]
        state = eng.run(prog, modes=[0])
        assert np.allclose(state.dm(), rho, atol=tol, rtol=0)

        eng.reset()

        prog = sf.Program(2)
        state1 = BaseFockState(rho, 1, False, cutoff, hbar)
        with prog.context as q:
            ops.DensityMatrix(state1) | q[0]
        state2 = eng.run(prog, modes=[0])
        assert np.allclose(state1.dm(), state2.dm(), atol=tol, rtol=0)
Exemple #6
0
    def test_ket_input_validation(self, setup_eng, hbar, cutoff):
        """Test exceptions"""
        mu = np.array([0.0, 0.0])
        cov = np.identity(2)
        state1 = GaussianState((mu, cov), 1, True, hbar)
        state2 = BaseFockState(np.zeros(cutoff), 1, False, cutoff, hbar)

        eng, prog = setup_eng(2)

        with prog.context as q:
            with pytest.raises(ValueError, match="Gaussian states are not supported"):
                ops.Ket(state1) | q[0]
            with pytest.raises(ValueError, match="not pure"):
                ops.Ket(state2) | q[0]
Exemple #7
0
    def test_ket_two_mode(self, setup_eng, hbar, cutoff, tol):
        """Tests multimode ket preparation"""
        eng, prog = setup_eng(2)
        ket0 = np.random.uniform(-1, 1, cutoff) + 1j * np.random.uniform(-1, 1, cutoff)
        ket0 = ket0 / np.linalg.norm(ket0)
        ket1 = np.random.uniform(-1, 1, cutoff) + 1j * np.random.uniform(-1, 1, cutoff)
        ket1 = ket1 / np.linalg.norm(ket1)

        ket = np.outer(ket0, ket1)
        with prog.context as q:
            ops.Ket(ket) | q
        state = eng.run(prog)
        assert np.allclose(
            state.dm(), np.einsum("ij,kl->ikjl", ket, ket.conj()), atol=tol, rtol=0
        )

        eng.reset()

        prog = sf.Program(2)
        state1 = BaseFockState(ket, 2, True, cutoff, hbar)
        with prog.context as q:
            ops.Ket(state1) | q
        state2 = eng.run(prog)
        assert np.allclose(state1.dm(), state2.dm(), atol=tol, rtol=0)