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 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" )