Beispiel #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
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
Beispiel #3
0
    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)
Beispiel #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