diff --git a/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py b/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py index f1fe6fa1f5..3d6ea7d3d2 100644 --- a/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py +++ b/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py @@ -12,6 +12,7 @@ """ Interleaved RB Experiment class. """ +import itertools import warnings from typing import Union, Iterable, Optional, List, Sequence, Tuple @@ -25,6 +26,7 @@ from qiskit.quantum_info import Clifford from qiskit.transpiler.exceptions import TranspilerError from qiskit_experiments.warnings import deprecate_arguments +from qiskit_experiments.framework import Options from qiskit_experiments.framework.backend_timing import BackendTiming from .clifford_utils import _truncate_inactive_qubits from .clifford_utils import num_from_1q_circuit, num_from_2q_circuit @@ -63,6 +65,7 @@ def __init__( num_samples: int = 3, seed: Optional[Union[int, SeedSequence, BitGenerator, Generator]] = None, full_sampling: bool = False, + circuit_order: str = "RIRIRI", ): """Initialize an interleaved randomized benchmarking experiment. @@ -87,6 +90,9 @@ def __init__( all lengths. If False for sample of lengths longer sequences are constructed by appending additional Clifford samples to shorter sequences. + circuit_order: How to order the reference and the interleaved circuits. + ``"RIRIRI"`` (default) - Alternate a reference and an interleaved circuit. Or + ``"RRRIII"`` - Push all reference circuits first, then all interleaved ones. Raises: QiskitError: When interleaved_element has different number of qubits @@ -153,9 +159,25 @@ def __init__( self._interleaved_cliff = interleaved_clifford.to_circuit() self._interleaved_element = interleaved_element # Original interleaved element self._interleaved_op = None # Transpiled interleaved element for speed + self.set_experiment_options(circuit_order=circuit_order) self.analysis = InterleavedRBAnalysis() self.analysis.set_options(outcome="0" * self.num_qubits) + @classmethod + def _default_experiment_options(cls) -> Options: + """Default InterleavedRB experiment options. + + Experiment Options: + circuit_order (str): How to order the reference and the interleaved circuits. + ``"RIRIRI"`` (alternate a reference and an interleaved circuit) or + ``"RRRIII"`` (push all reference circuits first, then all interleaved ones). + """ + options = super()._default_experiment_options() + options.update_options( + circuit_order="RIRIRI", + ) + return options + def circuits(self) -> List[QuantumCircuit]: """Return a list of RB circuits. @@ -195,7 +217,11 @@ def circuits(self) -> List[QuantumCircuit]: "physical_qubits": self.physical_qubits, "interleaved": True, } - return reference_circuits + interleaved_circuits + + if self.experiment_options.circuit_order == "RRRIII": + return reference_circuits + interleaved_circuits + # Default order: RIRIRI + return list(itertools.chain.from_iterable(zip(reference_circuits, interleaved_circuits))) def _to_instruction( self, elem: SequenceElementType, basis_gates: Optional[Tuple[str]] = None diff --git a/releasenotes/notes/irb-circuit-order-619845a707519c44.yaml b/releasenotes/notes/irb-circuit-order-619845a707519c44.yaml new file mode 100644 index 0000000000..f0837e8600 --- /dev/null +++ b/releasenotes/notes/irb-circuit-order-619845a707519c44.yaml @@ -0,0 +1,15 @@ +--- +features: + - | + A new experiment option ``circuit_order`` was added to :class:`~.InterleavedRB`. + It allows to change the order of the reference and the interleaved circuits + and hence slightly alter the impact of noise on interleaved RB results. + The default value is set to ``"RIRIRI"`` that alternate a reference and + an interleaved circuit. +fixes: + - | + Changed the ordering of circuits generated by :class:`~.InterleavedRB` back to + RIRIRI (R: Reference, I: Interleaved) order. + It was accidentally changed into RRRIII order in + `#898 `_. + Before that, it had been RIRIRI order. diff --git a/test/library/randomized_benchmarking/test_interleaved_rb.py b/test/library/randomized_benchmarking/test_interleaved_rb.py index 3d7c066ea6..038f1b03fa 100644 --- a/test/library/randomized_benchmarking/test_interleaved_rb.py +++ b/test/library/randomized_benchmarking/test_interleaved_rb.py @@ -104,10 +104,16 @@ def test_generate_interleaved_circuits(self, interleaved_element, qubits, length interleaved_element=interleaved_element, physical_qubits=qubits, lengths=[length], - num_samples=1, + num_samples=2, ) circuits = exp.circuits() self.assertAllIdentity(circuits) + # check order of circuits + for i, circ in enumerate(circuits): + if i % 2 == 0: # even <=> reference sequence + self.assertFalse(circ.metadata["interleaved"]) + else: # odd <=> interleaved sequence + self.assertTrue(circ.metadata["interleaved"]) @data([SXGate(), [3], 4], [CXGate(), [4, 7], 5]) @unpack