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
示例#2
0
    def test_auto_method_clifford_circuits_and_reset_noise(self):
        """Test statevector method is used for Clifford circuit"""
        # Test noise model
        noise_circs = [[{
            "name": "reset",
            "qubits": [0]
        }], [{
            "name": "id",
            "qubits": [0]
        }]]
        noise_probs = [0.5, 0.5]
        error = QuantumError(zip(noise_circs, noise_probs))
        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(
            error, ['id', 'x', 'y', 'z', 'h', 's', 'sdg'])
        backend = self.backend(noise_model=noise_model)

        # Test circuits
        shots = 100
        circuits = ref_2q_clifford.cz_gate_circuits_deterministic(
            final_measure=True)
        result = backend.run(circuits, shots=shots).result()
        success = getattr(result, 'success', False)
        self.assertTrue(success)
        self.compare_result_metadata(result, circuits, 'method', 'stabilizer')
示例#3
0
    def test_backend_method_clifford_circuits_and_reset_noise(self):
        """Test statevector method is used for Clifford circuit"""
        # Test noise model
        noise_circs = [[{
            "name": "reset",
            "qubits": [0]
        }], [{
            "name": "id",
            "qubits": [0]
        }]]
        noise_probs = [0.5, 0.5]
        error = QuantumError(zip(noise_circs, noise_probs))
        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(
            error, ['id', 'x', 'y', 'z', 'h', 's', 'sdg'])

        # Test circuits
        shots = 100
        circuits = ref_2q_clifford.cz_gate_circuits_deterministic(
            final_measure=True)
        qobj = assemble(circuits, self.SIMULATOR, shots=shots)

        result = self.SIMULATOR.run(qobj,
                                    backend_options=self.BACKEND_OPTS,
                                    noise_model=noise_model).result()
        success = getattr(result, 'success', False)
        self.assertTrue(success)
        # Check simulation method
        method = self.BACKEND_OPTS.get('method', 'automatic')
        if method != 'automatic':
            self.compare_result_metadata(result, circuits, 'method', method)
        else:
            self.compare_result_metadata(result, circuits, 'method',
                                         'stabilizer')
示例#4
0
    def test_from_dict(self):
        noise_ops_1q = [((IGate(), [0]), 0.9),
                     ((XGate(), [0]), 0.1)]

        noise_ops_2q = [((PauliGate('II'), [0, 1]), 0.9),
                     ((PauliGate('IX'), [0, 1]), 0.045),
                     ((PauliGate('XI'), [0, 1]), 0.045),
                     ((PauliGate('XX'), [0, 1]), 0.01)]

        noise_model = NoiseModel()
        with self.assertWarns(DeprecationWarning):
            noise_model.add_quantum_error(QuantumError(noise_ops_1q, 1), 'h', [0])
            noise_model.add_quantum_error(QuantumError(noise_ops_1q, 1), 'h', [1])
            noise_model.add_quantum_error(QuantumError(noise_ops_2q, 2), 'cx', [0, 1])
            noise_model.add_quantum_error(QuantumError(noise_ops_2q, 2), 'cx', [1, 0])
            deserialized = NoiseModel.from_dict(noise_model.to_dict())
            self.assertEqual(noise_model, deserialized)
示例#5
0
    def test_auto_method_nonclifford_circuit_and_reset_noise(self):
        """Test statevector method is used for Clifford circuit"""
        # Test noise model
        noise_circs = [Reset(), IGate()]
        noise_probs = [0.5, 0.5]
        error = QuantumError(zip(noise_circs, noise_probs))
        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(
            error, ['id', 'x', 'y', 'z', 'h', 's', 'sdg'])
        backend = self.backend(noise_model=noise_model)

        # Test circuits
        shots = 100
        circuits = ref_non_clifford.ccx_gate_circuits_deterministic(
            final_measure=True)
        result = backend.run(circuits, shots=shots).result()
        success = getattr(result, 'success', False)
        self.compare_result_metadata(result, circuits, 'method',
                                     "density_matrix")
示例#6
0
def get_error_channel(dag_cir, noisy_position, p):
    """to get the error channel of the noisy circuit
    """
    t_start = time.time()
    num_qubit = get_real_qubit_num(dag_cir)
    noise_ops = [([{
        "name": 'unitary',
        "qubits": [num_qubit - 1],
        'params': [np.eye(2)]
    }], 1)]
    error = QuantumError(noise_ops,
                         number_of_qubits=num_qubit).to_quantumchannel()
    for k in dag_cir.nodes:
        operation = dag_cir.nodes[k]['operation']
        nam = operation.name
        q = operation.involve_qubits_list
        if nam != 'CX':
            U = operation.u_matrix
        else:
            if q[0] < q[1]:
                U = np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0],
                              [0, 1, 0, 0]])
            else:
                U = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1],
                              [0, 0, 1, 0]])
        noise_ops = [([{"name": 'unitary', "qubits": q, 'params': [U]}], 1)]
        temp_error = QuantumError(
            noise_ops, number_of_qubits=num_qubit).to_quantumchannel()
        error = error.compose(temp_error)
        if k in noisy_position:
            q = [q[0]]
            for q0 in q:
                noise_ops = [([{
                    "name": 'id',
                    "qubits": [q0]
                }], 1 - p), ([{
                    "name": 'x',
                    "qubits": [q0]
                }], p / 3), ([{
                    "name": 'y',
                    "qubits": [q0]
                }], p / 3), ([{
                    "name": 'z',
                    "qubits": [q0]
                }], p / 3)]
                temp_error = QuantumError(
                    noise_ops, number_of_qubits=num_qubit).to_quantumchannel()
                error = error.compose(temp_error)
    return error
示例#7
0
    def test_backend_method_nonclifford_circuit_and_reset_noise(self):
        """Test statevector method is used for Clifford circuit"""
        # Test noise model
        noise_circs = [[{
            "name": "reset",
            "qubits": [0]
        }], [{
            "name": "id",
            "qubits": [0]
        }]]
        noise_probs = [0.5, 0.5]
        error = QuantumError(zip(noise_circs, noise_probs))
        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(
            error, ['id', 'x', 'y', 'z', 'h', 's', 'sdg'])

        # Test circuits
        shots = 100
        circuits = ref_non_clifford.ccx_gate_circuits_deterministic(
            final_measure=True)
        qobj = assemble(circuits, self.SIMULATOR, shots=shots)

        def get_result():
            return self.SIMULATOR.run(qobj,
                                      backend_options=self.BACKEND_OPTS,
                                      noise_model=noise_model).result()

        # Check simulation method
        method = self.BACKEND_OPTS.get('method', 'automatic')
        if method == 'stabilizer':
            self.assertRaises(AerError, get_result)
        else:
            result = get_result()
            self.is_completed(result)
            if method == 'automatic':
                target_method = 'density_matrix'
            else:
                target_method = method
            self.compare_result_metadata(result, circuits, 'method',
                                         target_method)
def approximate_quantum_error(error,
                              *,
                              operator_string=None,
                              operator_dict=None,
                              operator_list=None):
    """Return an approximate QuantumError bases on the Hilbert-Schmidt metric.

    Currently this is only implemented for 1-qubit QuantumErrors.

    Args:
        error (QuantumError): the error to be approximated.
        operator_string (string or None): a name for a premade set of
            building blocks for the output channel (Default: None).
        operator_dict (dict or None): a dictionary whose values are the
            building blocks for the output channel (Default: None).
        operator_list (dict or None): list of building blocks for the
            output channel (Default: None).

    Returns:
        QuantumError: the approximate quantum error.

    Raises:
        NoiseError: if number of qubits is not supported or approximation
                    failsed.
        RuntimeError: If there's no information about the noise type

    Additional Information
    ----------------------
    The operator input precedence is as follows: list < dict < string
    if a string is given, dict is overwritten; if a dict is given, list is
    overwritten possible values for string are 'pauli', 'reset', 'clifford'
    For further information see `NoiseTransformer.named_operators`.
    """

    if not isinstance(error, QuantumError):
        error = QuantumError(error)
    if error.number_of_qubits > 1:
        raise NoiseError("Only 1-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:
        operator_string = operator_string.lower()
        if operator_string not in transformer.named_operators.keys():
            raise RuntimeError(
                "No information about noise type {}".format(operator_string))
        operator_dict = transformer.named_operators[operator_string]
    if operator_dict is not None:
        names, 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 = 1 - sum(probabilities)
        if identity_prob < 0 or identity_prob > 1:
            raise RuntimeError(
                "Approximated channel operators 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"
    )
# In[5]:

# Convert to Kraus operator
bit_flip_kraus = Kraus(bit_flip)
print(bit_flip_kraus)

# In[6]:

# Convert to Superoperator
phase_flip_sop = SuperOp(phase_flip)
print(phase_flip_sop)

# In[7]:

# Convert back to a quantum error
print(QuantumError(bit_flip_kraus))

# Check conversion is equivalent to original error
QuantumError(bit_flip_kraus) == bit_flip

# ### Readout Error
#
# Classical readout errors are specified by a list of assignment probabilities vectors $P(A|B)$:
#
#   * $A$ is the *recorded* classical bit value
#   * $B$ is the *true* bit value returned from the measurement
#
# E.g. for 1 qubits: $ P(A|B) = [P(A|0), P(A|1)]$.

# In[8]: