Skip to content
This repository has been archived by the owner on Jun 12, 2023. It is now read-only.

Interleaved RB option to keep the original interleaved element #548

Merged
merged 7 commits into from
Mar 24, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 40 additions & 25 deletions qiskit/ignis/verification/randomized_benchmarking/circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def check_pattern(pattern, is_purity=False, interleaved_elem=None):
return pattern_flat, np.max(pattern_flat).item(), np.max(pattern_dim)


def handle_interleaved_elem(interleaved_elem, rb_group):
def handle_interleaved_elem(interleaved_elem, rb_group, keep_original_interleaved_elem):
""" Handle the various types of the interleaved element

Args:
Expand All @@ -132,6 +132,8 @@ def handle_interleaved_elem(interleaved_elem, rb_group):
List[qiskit.quantum_info.operators.symplectic.Clifford].
not None only for interleaved RB
rb_group (RBgroup): the relevant RBgroup class object
keep_original_interleaved_elem (bool): whether to transform the
original element to group element or keep as it is

Raises:
ValueError: if interleaved_elem does not have one of the relevant types,
Expand All @@ -147,27 +149,34 @@ def handle_interleaved_elem(interleaved_elem, rb_group):
if interleaved_elem is None:
return None

else:
for elem in interleaved_elem:
if isinstance(elem, (QuantumCircuit, Instruction)):
num_qubits = elem.num_qubits
qc = elem
elem = rb_group.iden(num_qubits)
elem = elem.from_circuit(qc)
if (isinstance(elem, qiskit.quantum_info.operators.symplectic.clifford.Clifford)
and group_gates_type == 0) or (isinstance(elem, CNOTDihedral)
and group_gates_type == 1):
interleaved_elem_list.append(elem)
for elem in interleaved_elem:
group_elem = elem
if isinstance(elem, (QuantumCircuit, Instruction)):
num_qubits = elem.num_qubits
group_elem = rb_group.iden(num_qubits)
group_elem = group_elem.from_circuit(elem)
if not (isinstance(group_elem, qiskit.quantum_info.operators.symplectic.clifford.Clifford)
and group_gates_type == 0) and \
not (isinstance(group_elem, CNOTDihedral) and group_gates_type == 1):
raise ValueError("Invalid interleaved element type.")

if not isinstance(group_elem, QuantumCircuit) and \
not isinstance(group_elem,
qiskit.quantum_info.operators.symplectic.clifford.Clifford) \
and not isinstance(group_elem, CNOTDihedral):
raise ValueError("Invalid interleaved element type. "
"interleaved_elem should be a list of QuantumCircuit,"
"or a list of Clifford / CNOTDihedral objects")
if keep_original_interleaved_elem:
if isinstance(elem, Instruction):
circuit_elem = QuantumCircuit(elem.num_qubits)
circuit_elem.append(elem, range(elem.num_qubits))
else:
raise ValueError("Invalid interleaved element type.")

if not isinstance(elem, QuantumCircuit) and \
not isinstance(elem,
qiskit.quantum_info.operators.symplectic.clifford.Clifford) \
and not isinstance(elem, CNOTDihedral):
raise ValueError("Invalid interleaved element type. "
"interleaved_elem should be a list of QuantumCircuit,"
"or a list of Clifford / CNOTDihedral objects")
circuit_elem = elem
else:
circuit_elem = rb_group.to_circuit(group_elem)
interleaved_elem_list.append((circuit_elem, group_elem))

return interleaved_elem_list


Expand Down Expand Up @@ -202,6 +211,7 @@ def randomized_benchmarking_seq(nseeds: int = 1,
Union[List[QuantumCircuit], List[Instruction],
List[qiskit.quantum_info.operators.symplectic.Clifford],
List[CNOTDihedral]]] = None,
keep_original_interleaved_elem: Optional[bool] = True,
is_purity: bool = False,
group_gates: Optional[str] = None,
rand_seed: Optional[Union[int, RandomState]] = None) -> \
Expand Down Expand Up @@ -267,6 +277,10 @@ def randomized_benchmarking_seq(nseeds: int = 1,
The lengths of the lists should be equal to the length of the
lists in ``rb_pattern``.

keep_original_interleaved_elem: whether to keep the original interleaved
element as it is when adding it to the RB circuits or to transform
it to a standard representation via group elements

is_purity: ``True`` only for purity randomized benchmarking
(default is ``False``).

Expand Down Expand Up @@ -401,7 +415,9 @@ def randomized_benchmarking_seq(nseeds: int = 1,
rb_circ_type = rb_group.rb_circ_type()

# Handle various types of the interleaved element
interleaved_elem = handle_interleaved_elem(interleaved_elem, rb_group)
interleaved_elem = handle_interleaved_elem(interleaved_elem,
rb_group,
keep_original_interleaved_elem)

# initialization: rb sequences
circuits = [[] for e in range(nseeds)]
Expand Down Expand Up @@ -467,13 +483,12 @@ def randomized_benchmarking_seq(nseeds: int = 1,
Elmnts_interleaved[rb_pattern_index] = \
rb_group.compose(
Elmnts_interleaved[rb_pattern_index],
interleaved_elem[rb_pattern_index])
interleaved_elem[rb_pattern_index][1])
# add a barrier - interleaved rb
interleaved_circ.barrier(
*[qr[x] for x in rb_pattern[rb_pattern_index]])
interleaved_circ += replace_q_indices(
rb_group.to_circuit(
interleaved_elem[rb_pattern_index]),
interleaved_elem[rb_pattern_index][0],
rb_pattern[rb_pattern_index], qr)
# add a barrier - interleaved rb
interleaved_circ.barrier(
Expand Down