From 8604ffcbed83803da8634211b9037adc404f15b8 Mon Sep 17 00:00:00 2001 From: Toshinari Itoko Date: Fri, 1 Dec 2023 18:45:37 +0900 Subject: [PATCH] Change to return results with quality=='failed' so that the lack of sub-results does not cause incorrect parent analysis --- .../randomized_benchmarking/layer_fidelity.py | 1 + .../layer_fidelity_analysis.py | 125 +++++++++++------- 2 files changed, 80 insertions(+), 46 deletions(-) diff --git a/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py b/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py index 9e44eb3164..f8ab601e69 100644 --- a/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py +++ b/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py @@ -363,4 +363,5 @@ def _metadata(self): if hasattr(self.run_options, run_opt): metadata[run_opt] = getattr(self.run_options, run_opt) + metadata["two_qubit_layers"] = self.experiment_options["two_qubit_layers"] return metadata diff --git a/qiskit_experiments/library/randomized_benchmarking/layer_fidelity_analysis.py b/qiskit_experiments/library/randomized_benchmarking/layer_fidelity_analysis.py index 0d0c8b4b7c..42faca439b 100644 --- a/qiskit_experiments/library/randomized_benchmarking/layer_fidelity_analysis.py +++ b/qiskit_experiments/library/randomized_benchmarking/layer_fidelity_analysis.py @@ -149,6 +149,24 @@ def _create_analysis_results( ) return outcomes + def _run_analysis( + self, experiment_data: ExperimentData + ) -> Tuple[List[AnalysisResultData], List["matplotlib.figure.Figure"]]: + r"""TODO + + Note: Empty analysis results will be returned when failing analysis. + """ + try: + return super()._run_analysis(experiment_data) + except Exception: + failed_result = AnalysisResultData( + name="ProcessFidelity", + value=None, + quality="failed", + extra={"qubits": self._physical_qubits}, + ) + return [failed_result], [] + def _get_experiment_components(self, experiment_data: ExperimentData): """Set physical qubits to the experiment components.""" return [device.Qubit(qubit) for qubit in self._physical_qubits] @@ -157,6 +175,8 @@ def _get_experiment_components(self, experiment_data: ExperimentData): class _SingleLayerFidelityAnalysis(CompositeAnalysis): r"""A class to estimate a process fidelity per disjoint layer. + Note: Empty analysis results will be returned when failing analysis. + # section: reference .. ref_arxiv:: 1 2311.05933 """ @@ -175,25 +195,30 @@ def _run_analysis( self, experiment_data: ExperimentData ) -> Tuple[List[AnalysisResultData], List["matplotlib.figure.Figure"]]: r"""TODO""" - - # Run composite analysis and extract sub-experiments results - analysis_results, figures = super()._run_analysis(experiment_data) - - # Calculate single layer fidelity from process fidelities of subsystems - pfs = [res.value for res in analysis_results if res.name == "ProcessFidelity"] - slf = np.prod(pfs) - quality_slf = "good" if all(sub.quality == "good" for sub in analysis_results) else "bad" - slf_result = AnalysisResultData( - name="SingleLF", - value=slf, - chisq=None, - quality=quality_slf, - extra={}, - ) - - # Return combined results - analysis_results = [slf_result] + analysis_results - return analysis_results, figures + try: + # Run composite analysis and extract sub-experiments results + analysis_results, figures = super()._run_analysis(experiment_data) + # Calculate single layer fidelity from process fidelities of subsystems + pfs = [res.value for res in analysis_results if res.name == "ProcessFidelity"] + slf = np.prod(pfs) + quality_slf = "good" if all(sub.quality == "good" for sub in analysis_results) else "bad" + slf_result = AnalysisResultData( + name="SingleLF", + value=slf, + quality=quality_slf, + extra={"qubits": [q for qubits in self._layer for q in qubits]}, + ) + # Return combined results + analysis_results = [slf_result] + analysis_results + return analysis_results, figures + except Exception: + failed_result = AnalysisResultData( + name="SingleLF", + value=None, + quality="failed", + extra={"qubits": [q for qubits in self._layer for q in qubits]}, + ) + return [failed_result] + analysis_results, figures def _get_experiment_components(self, experiment_data: ExperimentData): """Set physical qubits to the experiment components.""" @@ -226,30 +251,38 @@ def _run_analysis( _run_analysis for the sub-experiments (1Q/2Q simultaneous direct RBs). Based on the results, it computes the result for Layer Fidelity. """ - - # Run composite analysis and extract sub-experiments results - analysis_results, figures = super()._run_analysis(experiment_data) - - # Calculate full layer fidelity from single layer fidelities - slfs = [res.value for res in analysis_results if res.name == "SingleLF"] - lf = np.prod(slfs) - quality_lf = "good" if all(sub.quality == "good" for sub in analysis_results) else "bad" - lf_result = AnalysisResultData( - name="LF", - value=lf, - chisq=None, - quality=quality_lf, - extra={}, - ) - eplg = 1 - (lf ** (1 / self.num_2q_gates)) - eplg_result = AnalysisResultData( - name="EPLG", - value=eplg, - chisq=None, - quality=quality_lf, - extra={}, - ) - - # Return combined results - analysis_results = [lf_result, eplg_result] + analysis_results - return analysis_results, figures + try: + # Run composite analysis and extract sub-experiments results + analysis_results, figures = super()._run_analysis(experiment_data) + # Calculate full layer fidelity from single layer fidelities + slfs = [res.value for res in analysis_results if res.name == "SingleLF"] + lf = np.prod(slfs) + quality_lf = "good" if all(sub.quality == "good" for sub in analysis_results) else "bad" + lf_result = AnalysisResultData( + name="LF", + value=lf, + quality=quality_lf, + ) + eplg = 1 - (lf ** (1 / self.num_2q_gates)) + eplg_result = AnalysisResultData( + name="EPLG", + value=eplg, + quality=quality_lf, + ) + # Return combined results + analysis_results = [lf_result, eplg_result] + analysis_results + return analysis_results, figures + except Exception: + failed_results = [ + AnalysisResultData( + name="LF", + value=None, + quality="failed", + ), + AnalysisResultData( + name="EPLG", + value=None, + quality="failed", + ) + ] + return failed_results + analysis_results, figures