Beispiel #1
0
def kraus_error(noise_ops, standard_gates=None, canonical_kraus=False):
    """
    Return a Kraus quantum error channel.

    Args:
        noise_ops (list[matrix]): Kraus matrices.
        standard_gates (bool): DEPRECATED, Check if input matrices are standard gates.
        canonical_kraus (bool): Convert input Kraus matrices into the
                                canonical Kraus representation (default: False)

    Returns:
        QuantumError: The quantum error object.

    Raises:
        NoiseError: if error parameters are invalid.
    """
    if not isinstance(noise_ops, (list, tuple)):
        raise NoiseError("Invalid Kraus error input.")
    if not noise_ops:
        raise NoiseError("Kraus error noise_ops must not be empty.")

    if standard_gates is not None:
        warnings.warn(
            '"standard_gates" option has been deprecated as of qiskit-aer 0.10.0'
            ' and will be removed no earlier than 3 months from that release date.',
            DeprecationWarning,
            stacklevel=2)

    kraus = Kraus(noise_ops)
    if canonical_kraus:
        # Convert to Choi and back to get canonical Kraus
        kraus = Kraus(Choi(kraus))
    return QuantumError(kraus)
Beispiel #2
0
def kraus_error(noise_ops, standard_gates=True, canonical_kraus=False):
    """
    Return a Kraus quantum error channel.

    Args:
        noise_ops (list[matrix]): Kraus matrices.
        standard_gates (bool): Check if input matrices are standard gates.
        canonical_kraus (bool): Convert input Kraus matrices into the
                                canonical Kraus representation (default: False)

    Returns:
        QuantumError: The quantum error object.

    Raises:
        NoiseError: if error parameters are invalid.
    """
    if not isinstance(noise_ops, (list, tuple)):
        raise NoiseError("Invalid Kraus error input.")
    if not noise_ops:
        raise NoiseError("Kraus error noise_ops must not be empty.")
    kraus = Kraus(noise_ops)
    if canonical_kraus:
        # Convert to Choi and back to get canonical Kraus
        kraus = Kraus(Choi(kraus))
    return QuantumError(kraus, standard_gates=standard_gates)
 def test_is_cptp(self):
     """Test is_cptp method."""
     self.assertTrue(Kraus(self.depol_kraus(0.5)).is_cptp())
     self.assertTrue(Kraus(self.UX).is_cptp())
     # Non-CPTP should return false
     self.assertFalse(Kraus(([self.UI], [self.UX])).is_cptp())
     self.assertFalse(Kraus(([self.UI, self.UX])).is_cptp())
    def test_init(self):
        """Test initialization"""
        # Initialize from unitary
        chan = Kraus(self.UI)
        self.assertAllClose(chan.data, [self.UI])
        self.assertEqual(chan.dim, (2, 2))

        # Initialize from Kraus
        chan = Kraus(self.depol_kraus(0.5))
        self.assertAllClose(chan.data, self.depol_kraus(0.5))
        self.assertEqual(chan.dim, (2, 2))

        # Initialize from Non-CPTP
        kraus_l, kraus_r = [self.UI, self.UX], [self.UY, self.UZ]
        chan = Kraus((kraus_l, kraus_r))
        self.assertAllClose(chan.data, (kraus_l, kraus_r))
        self.assertEqual(chan.dim, (2, 2))

        # Initialize with redundant second op
        chan = Kraus((kraus_l, kraus_l))
        self.assertAllClose(chan.data, kraus_l)
        self.assertEqual(chan.dim, (2, 2))

        # Initialize from rectangular
        kraus = [np.zeros((4, 2))]
        chan = Kraus(kraus)
        self.assertAllClose(chan.data, kraus)
        self.assertEqual(chan.dim, (2, 4))

        # Wrong input or output dims should raise exception
        self.assertRaises(QiskitError,
                          Kraus,
                          kraus,
                          input_dims=4,
                          output_dims=4)
Beispiel #5
0
    def test_transform(self):
        X = self.ops['X']
        Y = self.ops['Y']
        Z = self.ops['Z']
        p = 0.34
        theta = numpy.pi / 7
        E0 = numpy.sqrt(1 - p) * numpy.array(numpy.eye(2))
        E1 = numpy.sqrt(p) * (numpy.cos(theta) * numpy.array(X) +
                              numpy.sin(theta) * numpy.array(Y))

        results_dict = approximate_quantum_error(Kraus([E0, E1]),
                                                 operator_dict={
                                                     "X": X,
                                                     "Y": Y,
                                                     "Z": Z
                                                 })
        results_string = approximate_quantum_error(Kraus([E0, E1]),
                                                   operator_string='pauli')
        results_list = approximate_quantum_error(Kraus([E0, E1]),
                                                 operator_list=[X, Y, Z])
        results_tuple = approximate_quantum_error(Kraus([E0, E1]),
                                                  operator_list=(X, Y, Z))

        self.assertErrorsAlmostEqual(results_dict, results_string)
        self.assertErrorsAlmostEqual(results_string, results_list)
        self.assertErrorsAlmostEqual(results_list, results_tuple)
 def test_copy(self):
     """Test copy method"""
     mat = np.eye(4)
     orig = Kraus(mat)
     cpy = orig.copy()
     cpy._data[0][0][0, 0] = 0.0
     self.assertFalse(cpy == orig)
Beispiel #7
0
    def test_approx_random_unitary_channel(self):
        # run without raising any error
        noise = Kraus(random_unitary(2, seed=123))
        for opstr in ['pauli', 'reset', 'clifford']:
            approximate_quantum_error(noise, operator_string=opstr)

        noise = Kraus(random_unitary(4, seed=123))
        for opstr in ['pauli', 'reset']:
            approximate_quantum_error(noise, operator_string=opstr)
    def test_tensor(self):
        """Test tensor method."""
        rho0, rho1 = np.diag([1, 0]), np.diag([0, 1])
        rho_init = np.kron(rho0, rho0)
        chan1 = Kraus(self.UI)
        chan2 = Kraus(self.UX)

        # X \otimes I
        chan = chan2.tensor(chan1)
        rho_targ = np.kron(rho1, rho0)
        self.assertEqual(chan.dim, (4, 4))
        self.assertAllClose(chan._evolve(rho_init), rho_targ)

        # I \otimes X
        chan = chan1.tensor(chan2)
        rho_targ = np.kron(rho0, rho1)
        self.assertEqual(chan.dim, (4, 4))
        self.assertAllClose(chan._evolve(rho_init), rho_targ)

        # Completely depolarizing
        chan_dep = Kraus(self.depol_kraus(1))
        chan = chan_dep.tensor(chan_dep)
        rho_targ = np.diag([1, 1, 1, 1]) / 4
        self.assertEqual(chan.dim, (4, 4))
        self.assertAllClose(chan._evolve(rho_init), rho_targ)
Beispiel #9
0
    def test_expand(self):
        """Test expand method."""
        rho0, rho1 = np.diag([1, 0]), np.diag([0, 1])
        rho_init = DensityMatrix(np.kron(rho0, rho0))
        chan1 = Kraus(self.UI)
        chan2 = Kraus(self.UX)

        # X \otimes I
        chan = chan1.expand(chan2)
        rho_targ = DensityMatrix(np.kron(rho1, rho0))
        self.assertEqual(chan.dim, (4, 4))
        self.assertEqual(rho_init @ chan, rho_targ)

        # I \otimes X
        chan = chan2.expand(chan1)
        rho_targ = DensityMatrix(np.kron(rho0, rho1))
        self.assertEqual(chan.dim, (4, 4))
        self.assertEqual(rho_init @ chan, rho_targ)

        # Completely depolarizing
        chan_dep = Kraus(self.depol_kraus(1))
        chan = chan_dep.expand(chan_dep)
        rho_targ = DensityMatrix(np.diag([1, 1, 1, 1]) / 4)
        self.assertEqual(chan.dim, (4, 4))
        self.assertEqual(rho_init @ chan, rho_targ)
Beispiel #10
0
    def test_multiply(self):
        """Test multiply method."""
        # Random initial state and Kraus ops
        rho = self.rand_rho(2)
        val = 0.5
        kraus1, kraus2 = self.rand_kraus(2, 4, 4), self.rand_kraus(2, 4, 4)

        # Single Kraus set
        chan1 = Kraus(kraus1)
        targ = val * chan1._evolve(rho)
        chan = chan1.multiply(val)
        self.assertAllClose(chan._evolve(rho), targ)
        chan = val * chan1
        self.assertAllClose(chan._evolve(rho), targ)
        chan = chan1 * val
        self.assertAllClose(chan._evolve(rho), targ)

        # Double Kraus set
        chan2 = Kraus((kraus1, kraus2))
        targ = val * chan2._evolve(rho)
        chan = chan2.multiply(val)
        self.assertAllClose(chan._evolve(rho), targ)
        chan = val * chan2
        self.assertAllClose(chan._evolve(rho), targ)
        chan = chan2 * val
        self.assertAllClose(chan._evolve(rho), targ)
Beispiel #11
0
    def test_power(self):
        """Test power method."""
        # 10% depolarizing channel
        rho = DensityMatrix(np.diag([1, 0]))
        p_id = 0.9
        chan = Kraus(self.depol_kraus(1 - p_id))

        # Compose 3 times
        p_id3 = p_id**3
        chan3 = chan.power(3)
        targ3a = rho @ chan @ chan @ chan
        self.assertEqual(rho @ chan3, targ3a)
        targ3b = rho @ Kraus(self.depol_kraus(1 - p_id3))
        self.assertEqual(rho @ chan3, targ3b)
Beispiel #12
0
 def test_multiply_except(self):
     """Test multiply method raises exceptions."""
     chan = Kraus(self.depol_kraus(1))
     self.assertRaises(QiskitError, chan._multiply, 's')
     self.assertRaises(QiskitError, chan.__rmul__, 's')
     self.assertRaises(QiskitError, chan._multiply, chan)
     self.assertRaises(QiskitError, chan.__rmul__, chan)
 def test_transpose_inplace(self):
     """Test inplace transpose method."""
     kraus_l, kraus_r = self.rand_kraus(2, 4, 4), self.rand_kraus(2, 4, 4)
     # Single Kraus list
     targ = Kraus([np.transpose(k) for k in kraus_l])
     chan = Kraus(kraus_l)
     chan.transpose(inplace=True)
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dims, (4, 2))
     # Double Kraus list
     targ = Kraus(([np.transpose(k) for k in kraus_l],
                   [np.transpose(k) for k in kraus_r]))
     chan = Kraus((kraus_l, kraus_r))
     chan.transpose(inplace=True)
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dims, (4, 2))
Beispiel #14
0
    def ideal(self):
        """Return True if this error object is composed only of identity operations.
        Note that the identity check is best effort and up to global phase."""
        for circ in self.circuits:
            try:
                # Circuit-level identity check for clifford Circuits
                clifford = Clifford(circ)
                if clifford != Clifford(np.eye(2 * circ.num_qubits,
                                               dtype=bool)):
                    return False
            except QiskitError:
                pass

            # Component-wise check for non-Clifford circuits
            for op, _, _ in circ:
                if isinstance(op, IGate):
                    continue
                if isinstance(op, PauliGate):
                    if op.params[0].replace('I', ''):
                        return False
                else:
                    # Convert to Kraus and check if identity
                    kmats = Kraus(op).data
                    if len(kmats) > 1:
                        return False
                    if not is_identity_matrix(kmats[0],
                                              ignore_phase=True,
                                              atol=self.atol,
                                              rtol=self.rtol):
                        return False
        return True
Beispiel #15
0
    def transform_by_given_channel(self, channel_matrices,
                                   const_channel_matrix):
        """
        Transform by by quantum channels.

        This method creates objective function representing the
        Hilbert-Schmidt norm of the matrix (A-B) obtained
        as the difference of the input noise channel and the output
        channel we wish to determine.

        This function is represented by a matrix P and a vector q, such that
        f(x) = 1/2(x*P*x)+q*x
        where x is the vector we wish to minimize, where x represents
        probabilities for the noise operators that construct the output channel

        Args:
            channel_matrices (list): A list of 4x4 symbolic matrices
            const_channel_matrix (matrix): a 4x4 constant matrix

        Returns:
            list: a list of the optimal probabilities for the channel matrices,
            determined by the quadratic program solver
        """
        target_channel = SuperOp(Kraus(self.noise_kraus_operators))
        target_channel_matrix = target_channel._data.T

        const_matrix = const_channel_matrix - target_channel_matrix
        P = self.compute_P(channel_matrices)
        q = self.compute_q(channel_matrices, const_matrix)
        return self.solve_quadratic_program(P, q)
Beispiel #16
0
def qchannel_to_qiskit(representation):
    """
    Create a qiskit representation of quantum channel from a myqlm representation
    of a quantum channel.

    Args:
        representation: (QuantumChannel) myqlm representation of a quantum channel.

    Returns:
        (Kraus|Choi|Chi|SuperOp|PTM): qiskit representation of a quantum channel.
    """

    rep = representation.representation
    # Find what representation it is.
    # Then create the corresponding matrix and shape it like qiskit is expecting it.
    # Finally, create the qiskit representation from that matrix.
    if rep in (RepresentationType.PTM, RepresentationType.CHOI):
        matri = representation.matrix
        data_re = []
        data_im = []
        for i in range(matri.nRows):
            for j in range(matri.nCols):
                data_re.append(matri.data[i * matri.nRows + j].re + 0.j)
                data_im.append(matri.data[i * matri.nRows + j].im)
        data = np.array(data_re)
        data.imag = np.array(data_im)
        data = data.reshape((matri.nRows, matri.nCols))
        return PTM(data) if (rep == RepresentationType.PTM) else Choi(data)
    if rep in (RepresentationType.CHI, RepresentationType.SUPEROP):
        final_data = []
        for matri in representation.basis:
            data_re = []
            data_im = []
            for i in range(matri.nRows):
                for j in range(matri.nCols):
                    data_re.append(matri.data[i * matri.nRows + j].re + 0.j)
                    data_im.append(matri.data[i * matri.nRows + j].im)
            data = np.array(data_re)
            data.imag = np.array(data_im)
            data = data.reshape((matri.nRows, matri.nCols))
            final_data.append(data)
        if rep == RepresentationType.CHI:
            return Chi(final_data) if len(final_data) > 1 else Chi(final_data[0])
        return SuperOp(final_data) if len(final_data) > 1 else SuperOp(final_data[0])
    if rep == RepresentationType.KRAUS:
        final_data = []
        for matri in representation.kraus_ops:
            data_re = []
            data_im = []
            for i in range(matri.nRows):
                for j in range(matri.nCols):
                    data_re.append(matri.data[i * matri.nRows + j].re + 0.j)
                    data_im.append(matri.data[i * matri.nRows + j].im)
            data = np.array(data_re)
            data.imag = np.array(data_im)
            data = data.reshape((matri.nRows, matri.nCols))
            final_data.append(data)
        return Kraus(final_data)
    return None
 def test_adjoint_inplace(self):
     """Test inplace adjoint method."""
     kraus_l = [self.rand_matrix(4, 2) for _ in range(4)]
     kraus_r = [self.rand_matrix(4, 2) for _ in range(4)]
     # Single Kraus list
     targ = Kraus([np.transpose(k).conj() for k in kraus_l])
     chan = Kraus(kraus_l)
     chan.adjoint(inplace=True)
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dims, (4, 2))
     # Double Kraus list
     targ = Kraus(([np.transpose(k).conj() for k in kraus_l],
                   [np.transpose(k).conj() for k in kraus_r]))
     chan = Kraus((kraus_l, kraus_r))
     chan.adjoint(inplace=True)
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dims, (4, 2))
    def test_power_inplace(self):
        """Test inplace power method."""
        # 10% depolarizing channel
        rho = np.diag([1, 0])
        p_id = 0.9
        chan = Kraus(self.depol_kraus(1 - p_id))

        # Compose 3 times
        p_id3 = p_id ** 3
        targ3a = chan._evolve(chan._evolve(chan._evolve(rho)))
        targ3b = Kraus(self.depol_kraus(1 - p_id3))._evolve(rho)
        chan.power(3, inplace=True)
        self.assertAllClose(chan._evolve(rho), targ3a)
        self.assertAllClose(chan._evolve(rho), targ3b)
Beispiel #19
0
    def test_subtract(self):
        """Test subtract method."""
        # Random input test state
        rho = DensityMatrix(self.rand_rho(2))
        kraus1, kraus2 = self.rand_kraus(2, 4, 4), self.rand_kraus(2, 4, 4)

        # Random Single-Kraus maps
        chan1 = Kraus(kraus1)
        chan2 = Kraus(kraus2)
        targ = (rho @ chan1) - (rho @ chan2)
        chan = chan1 - chan2
        self.assertEqual(rho @ chan, targ)

        # Random Single-Kraus maps
        chan = Kraus((kraus1, kraus2))
        targ = 0 * (rho @ chan)
        chan = chan - chan
        self.assertEqual(rho @ chan, targ)
Beispiel #20
0
 def test_power_except(self):
     """Test power method raises exceptions."""
     chan = Kraus(self.depol_kraus(0.9))
     # Negative power raises error
     self.assertRaises(QiskitError, chan.power, -1)
     # 0 power raises error
     self.assertRaises(QiskitError, chan.power, 0)
     # Non-integer power raises error
     self.assertRaises(QiskitError, chan.power, 0.5)
Beispiel #21
0
    def old_approximate_quantum_error(error,
                                      *,
                                      operator_string=None,
                                      operator_dict=None,
                                      operator_list=None):
        if not isinstance(error, QuantumError):
            error = QuantumError(error)
        if error.number_of_qubits > 2:
            raise NoiseError(
                "Only 1-qubit and 2-qubit noises can be converted, {}-qubit "
                "noise found in model".format(error.number_of_qubits))

        error_kraus_operators = Kraus(error.to_quantumchannel()).data
        transformer = NoiseTransformer()
        if operator_string is not None:
            no_info_error = "No information about noise type {}".format(
                operator_string)
            operator_string = operator_string.lower()
            if operator_string not in transformer.named_operators.keys():
                raise RuntimeError(no_info_error)
            operator_lists = transformer.named_operators[operator_string]
            if len(operator_lists) < error.number_of_qubits:
                raise RuntimeError(
                    no_info_error +
                    " for {} qubits".format(error.number_of_qubits))
            operator_dict = operator_lists[error.number_of_qubits - 1]
        if operator_dict is not None:
            _, operator_list = zip(*operator_dict.items())
        if operator_list is not None:
            op_matrix_list = [
                transformer.operator_matrix(operator)
                for operator in operator_list
            ]
            probabilities = transformer.transform_by_operator_list(
                op_matrix_list, error_kraus_operators)
            identity_prob = numpy.round(1 - sum(probabilities), 9)
            if identity_prob < 0 or identity_prob > 1:
                raise RuntimeError(
                    "Channel probabilities sum to {}".format(1 -
                                                             identity_prob))
            quantum_error_spec = [([{
                'name': 'id',
                'qubits': [0]
            }], identity_prob)]
            op_circuit_list = [
                transformer.operator_circuit(operator)
                for operator in operator_list
            ]
            for (operator, probability) in zip(op_circuit_list, probabilities):
                quantum_error_spec.append((operator, probability))
            return QuantumError(quantum_error_spec)

        raise NoiseError(
            "Quantum error approximation failed - no approximating operators detected"
        )
 def test_from_qiskit(self):
     """
     Test quantum channels created from qiskit are equals to quantum channels
     created by qiskit -> to myqlm -> to qiskit
     """
     circuit = QuantumCircuit(3)
     circuit.h(0)
     circuit.cx(0, 1)
     circuit.x(2)
     self.assertEqual(
         Kraus(circuit),
         qchannel_to_qiskit(qiskit_to_qchannel(Kraus(circuit))))
     self.assertEqual(Chi(circuit),
                      qchannel_to_qiskit(qiskit_to_qchannel(Chi(circuit))))
     self.assertEqual(Choi(circuit),
                      qchannel_to_qiskit(qiskit_to_qchannel(Choi(circuit))))
     self.assertEqual(
         SuperOp(circuit),
         qchannel_to_qiskit(qiskit_to_qchannel(SuperOp(circuit))))
     self.assertEqual(PTM(circuit),
                      qchannel_to_qiskit(qiskit_to_qchannel(PTM(circuit))))
Beispiel #23
0
    def test_multiply(self):
        """Test multiply method."""
        # Random initial state and Kraus ops
        rho = DensityMatrix(self.rand_rho(2))
        val = 0.5
        kraus1, kraus2 = self.rand_kraus(2, 4, 4), self.rand_kraus(2, 4, 4)

        # Single Kraus set
        chan1 = Kraus(kraus1)
        targ = val * (rho @ chan1)
        chan = chan1.multiply(val)
        self.assertEqual(rho @ chan, targ)
        chan = val * chan1
        self.assertEqual(rho @ chan, targ)
        chan = chan1 * val
        self.assertEqual(rho @ chan, targ)

        # Double Kraus set
        chan2 = Kraus((kraus1, kraus2))
        targ = val * (rho @ chan2)
        chan = chan2.multiply(val)
        self.assertEqual(rho @ chan, targ)
        chan = val * chan2
        self.assertEqual(rho @ chan, targ)
        chan = chan2 * val
        self.assertEqual(rho @ chan, targ)
    def transform_by_given_channel(self, channel_matrices,
                                   const_channel_matrix):
        # This method creates the quadratic programming instance for
        # minimizing the Hilbert-Schmidt norm of the matrix (A-B) obtained
        # as the difference of the input noise channel and the output
        # channel we wish to determine.
        target_channel = SuperOp(Kraus(self.noise_kraus_operators))
        target_channel_matrix = target_channel._data.T

        const_matrix = const_channel_matrix - target_channel_matrix
        P = self.compute_P(channel_matrices)
        q = self.compute_q(channel_matrices, const_matrix)
        return self.solve_quadratic_program(P, q)
Beispiel #25
0
    def test_transformation_by_kraus(self):
        gamma = 0.23
        error = amplitude_damping_error(gamma)
        reset_to_0 = [
            numpy.array([[1, 0], [0, 0]]),
            numpy.array([[0, 1], [0, 0]])
        ]
        reset_to_1 = [
            numpy.array([[0, 0], [1, 0]]),
            numpy.array([[0, 0], [0, 1]])
        ]
        reset_kraus = [Kraus(reset_to_0), Kraus(reset_to_1)]

        actual = approximate_quantum_error(error, operator_list=reset_kraus)

        p = (1 + gamma - numpy.sqrt(1 - gamma)) / 2
        expected_probs = [1 - p, p, 0]
        self.assertListAlmostEqual(expected_probs, actual.probabilities)

        with self.assertWarns(DeprecationWarning):
            approximate_quantum_error(error,
                                      operator_list=[reset_to_0, reset_to_1])
 def test_from_myqlm_kraus(self):
     """
     Test all combinations of kraus quantum channel between myqlm and qiskit
     """
     arr = np.arange(8 * 8, dtype=complex).reshape((8, 8))
     kraus_ops = [array_to_matrix(arr)]
     qchannel = QuantumChannel(representation=RepresentationType.KRAUS,
                               arity=3,
                               kraus_ops=kraus_ops)
     qiskit_qchannel = Kraus(arr)
     self.assertEqual(qchannel,
                      qiskit_to_qchannel(qchannel_to_qiskit(qchannel)))
     self.assertEqual(qiskit_qchannel, qchannel_to_qiskit(qchannel))
     self.assertEqual(qchannel, qiskit_to_qchannel(qiskit_qchannel))
 def test_adjoint(self):
     """Test adjoint method."""
     kraus_l, kraus_r = self.rand_kraus(2, 4, 4), self.rand_kraus(2, 4, 4)
     # Single Kraus list
     targ = Kraus([np.transpose(k).conj() for k in kraus_l])
     chan1 = Kraus(kraus_l)
     chan = chan1.adjoint()
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dims, (4, 2))
     # Double Kraus list
     targ = Kraus(([np.transpose(k).conj() for k in kraus_l],
                   [np.transpose(k).conj() for k in kraus_r]))
     chan1 = Kraus((kraus_l, kraus_r))
     chan = chan1.adjoint()
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dims, (4, 2))
Beispiel #28
0
 def test_conjugate(self):
     """Test conjugate method."""
     kraus_l, kraus_r = self.rand_kraus(2, 4, 4), self.rand_kraus(2, 4, 4)
     # Single Kraus list
     targ = Kraus([np.conjugate(k) for k in kraus_l])
     chan1 = Kraus(kraus_l)
     chan = chan1.conjugate()
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dim, (2, 4))
     # Double Kraus list
     targ = Kraus(([np.conjugate(k)
                    for k in kraus_l], [np.conjugate(k) for k in kraus_r]))
     chan1 = Kraus((kraus_l, kraus_r))
     chan = chan1.conjugate()
     self.assertEqual(chan, targ)
     self.assertEqual(chan.dim, (2, 4))
Beispiel #29
0
    def test_reset_2_qubit(self):
        # approximating amplitude damping using relaxation operators
        gamma = 0.23
        p = (gamma - numpy.sqrt(1 - gamma) + 1) / 2
        A0 = [[1, 0], [0, numpy.sqrt(1 - gamma)]]
        A1 = [[0, numpy.sqrt(gamma)], [0, 0]]
        error_1 = QuantumError([([(Kraus([A0, A1]), [0]), (IGate(), [1])], 1)])
        error_2 = QuantumError([([(Kraus([A0, A1]), [1]), (IGate(), [0])], 1)])

        expected_results_1 = QuantumError([([(IGate(), [0]),
                                             (IGate(), [1])], 1 - p),
                                           ([(Reset(), [0]),
                                             (IGate(), [1])], p)])
        expected_results_2 = QuantumError([([(IGate(), [1]),
                                             (IGate(), [0])], 1 - p),
                                           ([(Reset(), [1]),
                                             (IGate(), [0])], p)])

        results_1 = approximate_quantum_error(error_1, operator_string="reset")
        results_2 = approximate_quantum_error(error_2, operator_string="reset")

        self.assertErrorsAlmostEqual(results_1, expected_results_1)
        self.assertErrorsAlmostEqual(results_2, expected_results_2)
Beispiel #30
0
    def operator_matrix(self, operator):
        """Converts an operator representation to Kraus matrix representation

        Args:
            operator (operator): operator representation. Can be a noise
                circuit or a matrix or a list of matrices.

        Returns:
            Kraus: the operator, converted to Kraus representation.
        """
        if isinstance(operator, list) and isinstance(operator[0], dict):
            operator_error = QuantumError([(operator, 1)])
            kraus_rep = Kraus(operator_error.to_quantumchannel()).data
            return kraus_rep
        return operator