def build_measurement_error_mitigation_qobj( qubit_list: List[int], fitter_cls: Callable, backend: Backend, backend_config: Optional[Dict] = None, compile_config: Optional[Dict] = None, run_config: Optional[RunConfig] = None, mit_pattern: Optional[List[List[int]]] = None, ) -> Tuple[QasmQobj, List[str], List[str]]: """ Args: qubit_list: list of ordered qubits used in the algorithm fitter_cls: CompleteMeasFitter or TensoredMeasFitter backend: backend instance backend_config: configuration for backend compile_config: configuration for compilation run_config: configuration for running a circuit mit_pattern: Qubits on which to perform the measurement correction, divided to groups according to tensors. If `None` and `qr` is given then assumed to be performed over the entire `qr` as one group (default `None`). Returns: the Qobj with calibration circuits at the beginning the state labels for build MeasFitter the labels of the calibration circuits Raises: QiskitError: when the fitter_cls is not recognizable. MissingOptionalLibraryError: Qiskit-Ignis not installed """ circlabel = "mcal" if not qubit_list: raise QiskitError("The measured qubit list can not be [].") if fitter_cls == CompleteMeasFitter: meas_calibs_circuits, state_labels = complete_meas_cal( qubit_list=range(len(qubit_list)), circlabel=circlabel ) elif fitter_cls == TensoredMeasFitter: meas_calibs_circuits, state_labels = tensored_meas_cal( mit_pattern=mit_pattern, circlabel=circlabel ) else: raise QiskitError(f"Unknown fitter {fitter_cls}") # the provided `qubit_list` would be used as the initial layout to # assure the consistent qubit mapping used in the main circuits. tmp_compile_config = copy.deepcopy(compile_config) tmp_compile_config["initial_layout"] = qubit_list t_meas_calibs_circuits = compiler.transpile( meas_calibs_circuits, backend, **backend_config, **tmp_compile_config ) cals_qobj = compiler.assemble(t_meas_calibs_circuits, backend, **run_config.to_dict()) if hasattr(cals_qobj.config, "parameterizations"): del cals_qobj.config.parameterizations return cals_qobj, state_labels, circlabel
def meas_calib_circ_creation(): """ create measurement calibration circuits and a GHZ state circuit for the tests Returns: QuantumCircuit: the measurement calibrations circuits list[str]: the mitigation pattern QuantumCircuit: ghz circuit with 5 qubits (3 are used) """ qubit_list = [1, 2, 3] total_number_of_qubit = 5 meas_calibs, state_labels = complete_meas_cal(qubit_list=qubit_list, qr=total_number_of_qubit) # Choose 3 qubits qubit_1 = qubit_list[0] qubit_2 = qubit_list[1] qubit_3 = qubit_list[2] ghz = qiskit.QuantumCircuit(total_number_of_qubit, len(qubit_list)) ghz.h(qubit_1) ghz.cx(qubit_1, qubit_2) ghz.cx(qubit_1, qubit_3) for i in qubit_list: ghz.measure(i, i - 1) return meas_calibs, state_labels, ghz
def test_ideal_meas_cal(self): """Test ideal execution, without noise.""" for nq in self.nq_list: for pattern_type in range(1, 2**nq): # Generate the quantum register according to the pattern qubits, weight = self.choose_calibration(nq, pattern_type) # Generate the calibration circuits meas_calibs, state_labels = complete_meas_cal(qubit_list=qubits, circlabel="test") # Perform an ideal execution on the generated circuits backend = Aer.get_backend("qasm_simulator") job = qiskit.execute(meas_calibs, backend=backend, shots=self.shots) cal_results = job.result() # Make a calibration matrix meas_cal = CompleteMeasFitter(cal_results, state_labels, circlabel="test") # Assert that the calibration matrix is equal to identity IdentityMatrix = np.identity(2**weight) self.assertListEqual( meas_cal.cal_matrix.tolist(), IdentityMatrix.tolist(), "Error: the calibration matrix is not equal to identity", ) # Assert that the readout fidelity is equal to 1 self.assertEqual( meas_cal.readout_fidelity(), 1.0, "Error: the average fidelity is not equal to 1", ) # Generate ideal (equally distributed) results results_dict, results_list = self.generate_ideal_results(state_labels, weight) # Output the filter meas_filter = meas_cal.filter # Apply the calibration matrix to results # in list and dict forms using different methods results_dict_1 = meas_filter.apply(results_dict, method="least_squares") results_dict_0 = meas_filter.apply(results_dict, method="pseudo_inverse") results_list_1 = meas_filter.apply(results_list, method="least_squares") results_list_0 = meas_filter.apply(results_list, method="pseudo_inverse") # Assert that the results are equally distributed self.assertListEqual(results_list, results_list_0.tolist()) self.assertListEqual(results_list, np.round(results_list_1).tolist()) self.assertDictEqual(results_dict, results_dict_0) round_results = {} for key, val in results_dict_1.items(): round_results[key] = np.round(val) self.assertDictEqual(results_dict, round_results)
def build_measurement_error_mitigation_circuits( qubit_list: List[int], fitter_cls: Callable, backend: Backend, backend_config: Optional[Dict] = None, compile_config: Optional[Dict] = None, mit_pattern: Optional[List[List[int]]] = None, ) -> Tuple[QuantumCircuit, List[str], List[str]]: """Build measurement error mitigation circuits Args: qubit_list: list of ordered qubits used in the algorithm fitter_cls: CompleteMeasFitter or TensoredMeasFitter backend: backend instance backend_config: configuration for backend compile_config: configuration for compilation mit_pattern: Qubits on which to perform the measurement correction, divided to groups according to tensors. If `None` and `qr` is given then assumed to be performed over the entire `qr` as one group (default `None`). Returns: the circuit the state labels for build MeasFitter the labels of the calibration circuits Raises: QiskitError: when the fitter_cls is not recognizable. """ circlabel = "mcal" if not qubit_list: raise QiskitError("The measured qubit list can not be [].") run = False if fitter_cls == CompleteMeasFitter: meas_calibs_circuits, state_labels = complete_meas_cal( qubit_list=range(len(qubit_list)), circlabel=circlabel ) run = True elif fitter_cls == TensoredMeasFitter: meas_calibs_circuits, state_labels = tensored_meas_cal( mit_pattern=mit_pattern, circlabel=circlabel ) run = True if not run: try: from qiskit.ignis.mitigation.measurement import ( CompleteMeasFitter as CompleteMeasFitter_IG, TensoredMeasFitter as TensoredMeasFitter_IG, ) except ImportError as ex: # If ignis can't be imported we don't have a valid fitter # class so just fail here with an appropriate error message raise QiskitError(f"Unknown fitter {fitter_cls}") from ex if fitter_cls == CompleteMeasFitter_IG: meas_calibs_circuits, state_labels = complete_meas_cal( qubit_list=range(len(qubit_list)), circlabel=circlabel ) elif fitter_cls == TensoredMeasFitter_IG: meas_calibs_circuits, state_labels = tensored_meas_cal( mit_pattern=mit_pattern, circlabel=circlabel ) else: raise QiskitError(f"Unknown fitter {fitter_cls}") # the provided `qubit_list` would be used as the initial layout to # assure the consistent qubit mapping used in the main circuits. tmp_compile_config = copy.deepcopy(compile_config) tmp_compile_config["initial_layout"] = qubit_list t_meas_calibs_circuits = compiler.transpile( meas_calibs_circuits, backend, **backend_config, **tmp_compile_config ) return t_meas_calibs_circuits, state_labels, circlabel