Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
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