def setUp(self): """ Setup internal variables and a fake simulation. Aer is used to get the structure of the qiskit.Result. The IQ data is generated using gaussian random number generators. """ self.shots = 52 self.qubits = [0, 1] meas_cal, _ = tensored_meas_cal([[0], [1]]) backend = Aer.get_backend('qasm_simulator') job = qiskit.execute(meas_cal, backend=backend, shots=self.shots, meas_level=1) self.cal_results = job.result() i0, q0, i1, q1 = 0., -1., 0., 1. ground = utils.create_shots(i0, q0, 0.1, 0.1, self.shots, self.qubits) excited = utils.create_shots(i1, q1, 0.1, 0.1, self.shots, self.qubits) self.cal_results.results[0].meas_level = 1 self.cal_results.results[1].meas_level = 1 self.cal_results.results[0].data = ExperimentResultData(memory=ground) self.cal_results.results[1].data = ExperimentResultData(memory=excited)
def tensored_calib_circ_creation(): """ create tensored measurement calibration circuits and a GHZ state circuit for the tests Returns: QuantumCircuit: the tensored measurement calibration circuit list[list[int]]: the mitigation pattern QuantumCircuit: ghz circuit with 5 qubits (3 are used) """ mit_pattern = [[2], [4, 1]] meas_layout = [2, 4, 1] qr = qiskit.QuantumRegister(5) # Generate the calibration circuits meas_calibs, mit_pattern = tensored_meas_cal(mit_pattern, qr=qr) cr = qiskit.ClassicalRegister(3) ghz_circ = qiskit.QuantumCircuit(qr, cr) ghz_circ.h(mit_pattern[0][0]) ghz_circ.cx(mit_pattern[0][0], mit_pattern[1][0]) ghz_circ.cx(mit_pattern[0][0], mit_pattern[1][1]) ghz_circ.measure(mit_pattern[0][0], cr[0]) ghz_circ.measure(mit_pattern[1][0], cr[1]) ghz_circ.measure(mit_pattern[1][1], cr[2]) return meas_calibs, mit_pattern, ghz_circ, meas_layout
def test_ideal_tensored_meas_cal(self): """Test ideal execution, without noise.""" mit_pattern = [[1, 2], [3, 4, 5], [6]] meas_layout = [1, 2, 3, 4, 5, 6] # Generate the calibration circuits meas_calibs, _ = tensored_meas_cal(mit_pattern=mit_pattern) # Perform an ideal execution on the generated circuits backend = Aer.get_backend('qasm_simulator') cal_results = qiskit.execute(meas_calibs, backend=backend, shots=self.shots).result() # Make calibration matrices meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) # Assert that the calibration matrices are equal to identity cal_matrices = meas_cal.cal_matrices self.assertEqual(len(mit_pattern), len(cal_matrices), 'Wrong number of calibration matrices') for qubit_list, cal_mat in zip(mit_pattern, cal_matrices): IdentityMatrix = np.identity(2**len(qubit_list)) self.assertListEqual( cal_mat.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, _ = \ self.generate_ideal_results(count_keys(6), 6) # 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', meas_layout=meas_layout) results_dict_0 = meas_filter.apply(results_dict, method='pseudo_inverse', meas_layout=meas_layout) # Assert that the results are equally distributed 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 tensored_calib_circ_execution(shots: int, seed: int): """ create tensored measurement calibration circuits and simulates them with noise Args: shots (int): number of shots per simulation seed (int): the seed to use in the simulations Returns: list: list of Results of the measurement calibration simulations list: the mitigation pattern dict: dictionary of results counts of bell circuit simulation with measurement errors """ # define the circuits qr = qiskit.QuantumRegister(5) mit_pattern = [[2], [4, 1]] meas_calibs, mit_pattern = tensored_meas_cal(mit_pattern=mit_pattern, qr=qr, circlabel='test') # define noise prob = 0.2 error_meas = pauli_error([('X', prob), ('I', 1 - prob)]) noise_model = NoiseModel() noise_model.add_all_qubit_quantum_error(error_meas, "measure") # run the circuits multiple times backend = qiskit.Aer.get_backend('qasm_simulator') cal_results = qiskit.execute(meas_calibs, backend=backend, shots=shots, noise_model=noise_model, seed_simulator=seed).result() # create bell state and get it's results cr = qiskit.ClassicalRegister(3) qc = qiskit.QuantumCircuit(qr, cr) qc.h(qr[2]) qc.cx(qr[2], qr[4]) qc.cx(qr[2], qr[1]) qc.measure(qr[2], cr[0]) qc.measure(qr[4], cr[1]) qc.measure(qr[1], cr[2]) bell_results = qiskit.execute(qc, backend=backend, shots=shots, noise_model=noise_model, seed_simulator=seed).result() return cal_results, mit_pattern, bell_results
def test_tensored_meas_cal_on_circuit(self): """Test an execution on a circuit.""" mit_pattern = [[2], [4, 1]] qr = qiskit.QuantumRegister(5) # Generate the calibration circuits meas_calibs, _ = tensored_meas_cal(mit_pattern, qr=qr) # Run the calibration circuits backend = Aer.get_backend('qasm_simulator') cal_results = qiskit.execute(meas_calibs, backend=backend, shots=self.shots).result() # Make a calibration matrix meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) # Calculate the fidelity fidelity = meas_cal.readout_fidelity(0) * meas_cal.readout_fidelity(1) # Make a 3Q GHZ state cr = ClassicalRegister(3) ghz = QuantumCircuit(qr, cr) ghz.h(qr[2]) ghz.cx(qr[2], qr[4]) ghz.cx(qr[2], qr[1]) ghz.measure(qr[2], cr[0]) ghz.measure(qr[4], cr[1]) ghz.measure(qr[1], cr[2]) results = qiskit.execute([ghz], backend=backend, shots=self.shots).result() # Predicted equally distributed results predicted_results = {'000': 0.5, '111': 0.5} meas_filter = meas_cal.filter # Calculate the results after mitigation output_results_pseudo_inverse = meas_filter.apply( results, method='pseudo_inverse').get_counts(0) output_results_least_square = meas_filter.apply( results, method='least_squares').get_counts(0) # Compare with expected fidelity and expected results self.assertAlmostEqual(fidelity, 1.0) self.assertAlmostEqual(output_results_pseudo_inverse['000'] / self.shots, predicted_results['000'], places=1) self.assertAlmostEqual(output_results_least_square['000'] / self.shots, predicted_results['000'], places=1) self.assertAlmostEqual(output_results_pseudo_inverse['111'] / self.shots, predicted_results['111'], places=1) self.assertAlmostEqual(output_results_least_square['111'] / self.shots, predicted_results['111'], places=1)
def build_measurement_error_mitigation_qobj( qubit_list: List[int], fitter_cls: Callable, backend: BaseBackend, 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 """ try: from qiskit.ignis.mitigation.measurement import ( complete_meas_cal, tensored_meas_cal, CompleteMeasFitter, TensoredMeasFitter, ) except ImportError as ex: raise MissingOptionalLibraryError( libname="qiskit-ignis", name="build_measurement_error_mitigation_qobj", pip_install="pip install qiskit-ignis", ) from ex 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