Exemplo n.º 1
0
 def test_reshape(self):
     """Test Operator _reshape method."""
     op = Operator(self.rand_matrix(8, 8))
     self.assertEqual(op.output_dims(), (2, 2, 2))
     self.assertEqual(op.input_dims(), (2, 2, 2))
     op._reshape(input_dims=[8], output_dims=[8])
     self.assertEqual(op.output_dims(), (8, ))
     self.assertEqual(op.input_dims(), (8, ))
     op._reshape(input_dims=[4, 2], output_dims=[2, 4])
     self.assertEqual(op.output_dims(), (2, 4))
     self.assertEqual(op.input_dims(), (4, 2))
Exemplo n.º 2
0
 def test_chi_tensor_random(self):
     """Test tensor of Chi matrices is correct."""
     mats = [self.rand_matrix(2, 2) for _ in range(4)]
     chans = [Chi(Operator(mat)) for mat in mats]
     self._compare_tensor_to_operator(chans, mats)
Exemplo n.º 3
0
 def test_kraus_compose_random(self):
     """Test compose of Kraus matrices is correct."""
     mats = [self.rand_matrix(4, 4) for _ in range(4)]
     chans = [Kraus(Operator(mat)) for mat in mats]
     self._compare_compose_to_operator(chans, mats)
Exemplo n.º 4
0
 def test_negate(self):
     """Test negate method"""
     mat = self.rand_matrix(4, 4)
     op = Operator(mat)
     self.assertEqual(-op, Operator(-1 * mat))
Exemplo n.º 5
0
    def test_evolve_subsystem(self):
        """Test subsystem evolve method for operators."""
        # Test evolving single-qubit of 3-qubit system
        for _ in range(5):
            rho = self.rand_rho(8)
            state = DensityMatrix(rho)
            op0 = random_unitary(2)
            op1 = random_unitary(2)
            op2 = random_unitary(2)

            # Test evolve on 1-qubit
            op = op0
            op_full = Operator(np.eye(4)).tensor(op)
            target = DensityMatrix(
                np.dot(op_full.data, rho).dot(op_full.adjoint().data))
            self.assertEqual(state.evolve(op, qargs=[0]), target)

            # Evolve on qubit 1
            op_full = Operator(np.eye(2)).tensor(op).tensor(np.eye(2))
            target = DensityMatrix(
                np.dot(op_full.data, rho).dot(op_full.adjoint().data))
            self.assertEqual(state.evolve(op, qargs=[1]), target)

            # Evolve on qubit 2
            op_full = op.tensor(np.eye(4))
            target = DensityMatrix(
                np.dot(op_full.data, rho).dot(op_full.adjoint().data))
            self.assertEqual(state.evolve(op, qargs=[2]), target)

            # Test evolve on 2-qubits
            op = op1.tensor(op0)

            # Evolve on qubits [0, 2]
            op_full = op1.tensor(np.eye(2)).tensor(op0)
            target = DensityMatrix(
                np.dot(op_full.data, rho).dot(op_full.adjoint().data))
            self.assertEqual(state.evolve(op, qargs=[0, 2]), target)

            # Evolve on qubits [2, 0]
            op_full = op0.tensor(np.eye(2)).tensor(op1)
            target = DensityMatrix(
                np.dot(op_full.data, rho).dot(op_full.adjoint().data))
            self.assertEqual(state.evolve(op, qargs=[2, 0]), target)

            # Test evolve on 3-qubits
            op = op2.tensor(op1).tensor(op0)

            # Evolve on qubits [0, 1, 2]
            op_full = op
            target = DensityMatrix(
                np.dot(op_full.data, rho).dot(op_full.adjoint().data))
            self.assertEqual(state.evolve(op, qargs=[0, 1, 2]), target)

            # Evolve on qubits [2, 1, 0]
            op_full = op0.tensor(op1).tensor(op2)
            target = DensityMatrix(
                np.dot(op_full.data, rho).dot(op_full.adjoint().data))
            self.assertEqual(state.evolve(op, qargs=[2, 1, 0]), target)
Exemplo n.º 6
0
 def test_compose_except(self):
     """Test compose different dimension exception"""
     self.assertRaises(QiskitError,
                       Operator(np.eye(2)).compose, Operator(np.eye(3)))
     self.assertRaises(QiskitError, Operator(np.eye(2)).compose, 2)
Exemplo n.º 7
0
 def test_power_except(self):
     """Test power method raises exceptions if not square."""
     op = Operator(self.rand_matrix(2, 3))
     # Non-integer power raises error
     self.assertRaises(QiskitError, op.power, 0.5)
Exemplo n.º 8
0
 def to_operator(self):
     """Convert to an Operator object."""
     return Operator(self.to_instruction())
Exemplo n.º 9
0
 def to_operator(self):
     """Convert to an Operator object."""
     return Operator(self.to_matrix(),
                     input_dims=self.input_dims(),
                     output_dims=self.output_dims())
Exemplo n.º 10
0
 def to_operator(self):
     """Convert to Operator object."""
     # Place import here to avoid cyclic import from circuit visualization
     from qiskit.quantum_info.operators.operator import Operator
     return Operator(self.to_matrix())
Exemplo n.º 11
0
def process_fidelity(channel, target=None, require_cp=True, require_tp=False):
    r"""Return the process fidelity of a noisy quantum channel.

    This process fidelity :math:`F_{\text{pro}}` is given by

    .. math::
        F_{\text{pro}}(\mathcal{E}, U)
            = \frac{Tr[S_U^\dagger S_{\mathcal{E}}]}{d^2}

    where :math:`S_{\mathcal{E}}, S_{U}` are the
    :class:`~qiskit.quantum_info.SuperOp` matrices for the input quantum
    *channel* :math:`\cal{E}` and *target* unitary :math:`U` respectively,
    and :math:`d` is the dimension of the *channel*.

    Args:
        channel (QuantumChannel or Operator): noisy quantum channel.
        target (Operator or None): target unitary operator.
            If `None` target is the identity operator [Default: None].
        require_cp (bool): require channel to be completely-positive
            [Default: True].
        require_tp (bool): require channel to be trace-preserving
            [Default: False].

    Returns:
        float: The process fidelity :math:`F_{\text{pro}}`.

    Raises:
        QiskitError: if the channel and target do not have the same dimensions,
                     or have different input and output dimensions.
        QiskitError: if the channel and target or are not completely-positive
                     (with ``require_cp=True``) or not trace-preserving
                     (with ``require_tp=True``).
    """
    # Format inputs
    if isinstance(channel, (list, np.ndarray, Operator, Pauli, Clifford)):
        channel = Operator(channel)
    else:
        channel = SuperOp(channel)

    if target is not None:
        try:
            target = Operator(target)
        except QiskitError:
            raise QiskitError('Target channel is not a unitary channel.')
        if channel.dim != target.dim:
            raise QiskitError(
                'Input quantum channel and target unitary must have the same '
                'dimensions ({} != {}).'.format(channel.dim, target.dim))

    # Validate complete-positivity and trace-preserving
    if require_cp or require_tp:
        # Validate target channel
        if target is not None:
            is_unitary = target.is_unitary()
            if require_cp and not is_unitary:
                raise QiskitError(
                    'Target unitary channel is not completely-positive')
            if require_tp and not is_unitary:
                raise QiskitError(
                    'Target unitary channel is not trace-preserving')
        # Validate input channel
        if isinstance(channel, Operator):
            is_unitary = channel.is_unitary()
            # Validate as unitary
            if require_cp and not is_unitary:
                raise QiskitError(
                    'Input quantum channel is not completely-positive')
            if require_tp and not is_unitary:
                raise QiskitError(
                    'Input quantum channel is not trace-preserving')
        else:
            # Validate as QuantumChannel
            if require_cp and not channel.is_cp():
                raise QiskitError(
                    'Input quantum channel is not completely-positive')
            if require_tp and not channel.is_tp():
                raise QiskitError(
                    'Input quantum channel is not trace-preserving')

    # Compute process fidelity with identity channel
    if target is not None:
        channel = channel.compose(target.adjoint())
    input_dim, _ = channel.dim
    if isinstance(channel, Operator):
        # |Tr[U]/dim| ** 2
        fid = np.abs(np.trace(channel.data) / input_dim)**2
    else:
        # Tr[S] / (dim ** 2)
        fid = np.trace(SuperOp(channel).data) / (input_dim**2)
    return float(np.real(fid))
Exemplo n.º 12
0
 def test_multiply_except(self):
     """Test multiply method raises exceptions."""
     op = Operator(self.rand_matrix(2, 2))
     self.assertRaises(QiskitError, op.multiply, 's')
     self.assertRaises(QiskitError, op.multiply, op)
Exemplo n.º 13
0
 def test_subtract_except(self):
     """Test subtract method raises exceptions."""
     op1 = Operator(self.rand_matrix(2, 2))
     op2 = Operator(self.rand_matrix(3, 3))
     self.assertRaises(QiskitError, op1.subtract, op2)
Exemplo n.º 14
0
    def test_evolve_subsystem(self):
        """Test subsytem _evolve method."""
        # Test evolving single-qubit of 3-qubit system
        mat = self.rand_matrix(2, 2)
        op = Operator(mat)
        psi = self.rand_matrix(1, 8).flatten()
        rho = self.rand_rho(8)

        # Evolve on qubit 0
        mat0 = np.kron(np.eye(4), mat)
        psi0_targ = np.dot(mat0, psi)
        self.assertAllClose(op._evolve(psi, qargs=[0]), psi0_targ)
        rho0_targ = np.dot(np.dot(mat0, rho), np.conj(mat0.T))
        self.assertAllClose(op._evolve(rho, qargs=[0]), rho0_targ)

        # Evolve on qubit 1
        mat1 = np.kron(np.kron(np.eye(2), mat), np.eye(2))
        psi1_targ = np.dot(mat1, psi)
        self.assertAllClose(op._evolve(psi, qargs=[1]), psi1_targ)
        rho1_targ = np.dot(np.dot(mat1, rho), np.conj(mat1.T))
        self.assertAllClose(op._evolve(rho, qargs=[1]), rho1_targ)

        # Evolve on qubit 2
        mat2 = np.kron(mat, np.eye(4))
        psi2_targ = np.dot(mat2, psi)
        self.assertAllClose(op._evolve(psi, qargs=[2]), psi2_targ)
        rho2_targ = np.dot(np.dot(mat2, rho), np.conj(mat2.T))
        self.assertAllClose(op._evolve(rho, qargs=[2]), rho2_targ)

        # Test 2-qubit evolution
        mat_a = self.rand_matrix(2, 2)
        mat_b = self.rand_matrix(2, 2)
        op = Operator(np.kron(mat_b, mat_a))
        psi = self.rand_matrix(1, 8).flatten()
        rho = self.rand_rho(8)

        # Evolve on qubits [0, 2]
        mat02 = np.kron(mat_b, np.kron(np.eye(2), mat_a))
        psi02_targ = np.dot(mat02, psi)
        self.assertAllClose(op._evolve(psi, qargs=[0, 2]), psi02_targ)
        rho02_targ = np.dot(np.dot(mat02, rho), np.conj(mat02.T))
        self.assertAllClose(op._evolve(rho, qargs=[0, 2]), rho02_targ)

        # Evolve on qubits [2, 0]
        mat20 = np.kron(mat_a, np.kron(np.eye(2), mat_b))
        psi20_targ = np.dot(mat20, psi)
        self.assertAllClose(op._evolve(psi, qargs=[2, 0]), psi20_targ)
        rho20_targ = np.dot(np.dot(mat20, rho), np.conj(mat20.T))
        self.assertAllClose(op._evolve(rho, qargs=[2, 0]), rho20_targ)

        # Test evolve on 3-qubits
        mat_a = self.rand_matrix(2, 2)
        mat_b = self.rand_matrix(2, 2)
        mat_c = self.rand_matrix(2, 2)
        op = Operator(np.kron(mat_c, np.kron(mat_b, mat_a)))
        psi = self.rand_matrix(1, 8).flatten()
        rho = self.rand_rho(8)

        # Evolve on qubits [0, 1, 2]
        mat012 = np.kron(mat_c, np.kron(mat_b, mat_a))
        psi012_targ = np.dot(mat012, psi)
        self.assertAllClose(op._evolve(psi, qargs=[0, 1, 2]), psi012_targ)
        rho012_targ = np.dot(np.dot(mat012, rho), np.conj(mat012.T))
        self.assertAllClose(op._evolve(rho, qargs=[0, 1, 2]), rho012_targ)

        # Evolve on qubits [2, 1, 0]
        mat210 = np.kron(mat_a, np.kron(mat_b, mat_c))
        psi210_targ = np.dot(mat210, psi)
        self.assertAllClose(op._evolve(psi, qargs=[2, 1, 0]), psi210_targ)
        rho210_targ = np.dot(np.dot(mat210, rho), np.conj(mat210.T))
        self.assertAllClose(op._evolve(rho, qargs=[2, 1, 0]), rho210_targ)
Exemplo n.º 15
0
 def test_reshape_raise(self):
     """Test Operator reshape method with invalid args."""
     op = Operator(self.rand_matrix(3, 3))
     self.assertRaises(QiskitError, op.reshape, num_qubits=2)
Exemplo n.º 16
0
def process_fidelity(channel,
                     target=None,
                     require_cp=True,
                     require_tp=False,
                     require_cptp=False):
    r"""Return the process fidelity of a noisy quantum channel.

    This process fidelity :math:`F_{\text{pro}}` is given by

    .. math::
        F_{\text{pro}}(\mathcal{E}, U)
            = \frac{Tr[S_U^\dagger S_{\mathcal{E}}]}{d^2}

    where :math:`S_{\mathcal{E}}, S_{U}` are the
    :class:`~qiskit.quantum_info.SuperOp` matrices for the input quantum
    *channel* :math:`\cal{E}` and *target* unitary :math:`U` respectively,
    and :math:`d` is the dimension of the *channel*.

    Args:
        channel (QuantumChannel): noisy quantum channel.
        target (Operator or None): target unitary operator.
            If `None` target is the identity operator [Default: None].
        require_cp (bool): require channel to be completely-positive
            [Default: True].
        require_tp (bool): require channel to be trace-preserving
            [Default: False].
        require_cptp (bool): (DEPRECATED) require input channels to be
            CPTP [Default: False].

    Returns:
        float: The process fidelity :math:`F_{\text{pro}}`.

    Raises:
        QiskitError: if the channel and target do not have the same dimensions,
                     or have different input and output dimensions.
        QiskitError: if the channel and target or are not completely-positive
                     (with ``require_cp=True``) or not trace-preserving
                     (with ``require_tp=True``).
    """
    # Format inputs
    if isinstance(channel, (list, np.ndarray, Operator, Pauli)):
        channel = Operator(channel)
    else:
        channel = SuperOp(channel)
    input_dim, output_dim = channel.dim
    if input_dim != output_dim:
        raise QiskitError(
            'Quantum channel must have equal input and output dimensions.')

    if target is not None:
        # Multiple channel by adjoint of target
        target = Operator(target)
        if (input_dim, output_dim) != target.dim:
            raise QiskitError(
                'Quantum channel and target must have the same dimensions.')
        channel = channel @ target.adjoint()

    # Validate complete-positivity and trace-preserving
    if require_cptp:
        # require_cptp kwarg is DEPRECATED
        # Remove in future qiskit version
        warnings.warn(
            "Please use `require_cp=True, require_tp=True` "
            "instead of `require_cptp=True`.", DeprecationWarning)
        require_cp = True
        require_tp = True
    if isinstance(channel, Operator) and (require_cp or require_tp):
        is_unitary = channel.is_unitary()
        # Validate as unitary
        if require_cp and not is_unitary:
            raise QiskitError('channel is not completely-positive')
        if require_tp and not is_unitary:
            raise QiskitError('channel is not trace-preserving')
    else:
        # Validate as QuantumChannel
        if require_cp and not channel.is_cp():
            raise QiskitError('channel is not completely-positive')
        if require_tp and not channel.is_tp():
            raise QiskitError('channel is not trace-preserving')

    # Compute process fidelity with identity channel
    if isinstance(channel, Operator):
        # |Tr[U]/dim| ** 2
        fid = np.abs(np.trace(channel.data) / input_dim)**2
    else:
        # Tr[S] / (dim ** 2)
        fid = np.trace(channel.data) / (input_dim**2)
    return float(np.real(fid))
Exemplo n.º 17
0
 def test_to_operator(self):
     """Test to_operator method."""
     op1 = Operator(self.rand_matrix(4, 4))
     op2 = op1.to_operator()
     self.assertEqual(op1, op2)
Exemplo n.º 18
0
 def to_operator(self):
     """Convert to a matrix Operator object"""
     return Operator(self.to_matrix())
Exemplo n.º 19
0
    def test_compose_front_subsystem(self):
        """Test subsystem front compose method."""
        # 3-qubit operator
        mat = self.rand_matrix(8, 8)
        mat_a = self.rand_matrix(2, 2)
        mat_b = self.rand_matrix(2, 2)
        mat_c = self.rand_matrix(2, 2)
        op = Operator(mat)
        op1 = Operator(mat_a)
        op2 = Operator(np.kron(mat_b, mat_a))
        op3 = Operator(np.kron(mat_c, np.kron(mat_b, mat_a)))

        # op3 qargs=[0, 1, 2]
        targ = np.dot(mat, np.kron(mat_c, np.kron(mat_b, mat_a)))
        self.assertEqual(op.compose(op3, qargs=[0, 1, 2], front=True),
                         Operator(targ))
        # op3 qargs=[2, 1, 0]
        targ = np.dot(mat, np.kron(mat_a, np.kron(mat_b, mat_c)))
        self.assertEqual(op.compose(op3, qargs=[2, 1, 0], front=True),
                         Operator(targ))

        # op2 qargs=[0, 1]
        targ = np.dot(mat, np.kron(np.eye(2), np.kron(mat_b, mat_a)))
        self.assertEqual(op.compose(op2, qargs=[0, 1], front=True),
                         Operator(targ))
        # op2 qargs=[2, 0]
        targ = np.dot(mat, np.kron(mat_a, np.kron(np.eye(2), mat_b)))
        self.assertEqual(op.compose(op2, qargs=[2, 0], front=True),
                         Operator(targ))

        # op1 qargs=[0]
        targ = np.dot(mat, np.kron(np.eye(4), mat_a))
        self.assertEqual(op.compose(op1, qargs=[0], front=True),
                         Operator(targ))

        # op1 qargs=[1]
        targ = np.dot(mat, np.kron(np.eye(2), np.kron(mat_a, np.eye(2))))
        self.assertEqual(op.compose(op1, qargs=[1], front=True),
                         Operator(targ))

        # op1 qargs=[2]
        targ = np.dot(mat, np.kron(mat_a, np.eye(4)))
        self.assertEqual(op.compose(op1, qargs=[2], front=True),
                         Operator(targ))
Exemplo n.º 20
0
 def to_operator(self):
     """Convert to Operator"""
     dims = self.dims()
     return Operator(self.data, input_dims=dims, output_dims=dims)
Exemplo n.º 21
0
 def test_add_except(self):
     """Test add method raises exceptions."""
     op1 = Operator(self.rand_matrix(2, 2))
     op2 = Operator(self.rand_matrix(3, 3))
     self.assertRaises(QiskitError, op1._add, op2)
Exemplo n.º 22
0
 def to_operator(self):
     """Convert state to a rank-1 projector operator"""
     mat = np.outer(self.data, np.conj(self.data))
     return Operator(mat, input_dims=self.dims(), output_dims=self.dims())
Exemplo n.º 23
0
 def test_from_circuit_empty_circuit_empty_layout(self):
     """Test an out of order ghz state with a layout set."""
     circuit = QuantumCircuit()
     circuit._layout = Layout()
     op = Operator.from_circuit(circuit)
     self.assertEqual(Operator([1]), op)
Exemplo n.º 24
0
 def test_init_operator(self):
     """Test initialization from Operator."""
     op1 = Operator(self.rand_matrix(4, 4))
     op2 = Operator(op1)
     self.assertEqual(op1, op2)
Exemplo n.º 25
0
 def to_operator(self):
     """Try to convert channel to a unitary representation Operator."""
     mat = _to_operator(self._channel_rep, self._data, *self.dim)
     return Operator(mat, self.input_dims(), self.output_dims())
Exemplo n.º 26
0
 def test_equal(self):
     """Test __eq__ method"""
     mat = self.rand_matrix(2, 2, real=True)
     self.assertEqual(Operator(np.array(mat, dtype=complex)), Operator(mat))
     mat = self.rand_matrix(4, 4)
     self.assertEqual(Operator(mat.tolist()), Operator(mat))
Exemplo n.º 27
0
 def test_ptm_expand_random(self):
     """Test expand of PTM matrices is correct."""
     mats = [self.rand_matrix(2, 2) for _ in range(4)]
     chans = [PTM(Operator(mat)) for mat in mats]
     self._compare_expand_to_operator(chans, mats)
Exemplo n.º 28
0
 def test_data(self):
     """Test Operator representation string property."""
     mat = self.rand_matrix(2, 2)
     op = Operator(mat)
     assert_allclose(mat, op.data)
Exemplo n.º 29
0
 def test_stinespring_compose_random(self):
     """Test compose of Stinespring matrices is correct."""
     mats = [self.rand_matrix(4, 4) for _ in range(4)]
     chans = [Stinespring(Operator(mat)) for mat in mats]
     self._compare_compose_to_operator(chans, mats)
Exemplo n.º 30
0
 def test_rep(self):
     """Test Operator representation string property."""
     op = Operator(self.rand_matrix(2, 2))
     self.assertEqual(op.rep, 'Operator')