diff --git a/.buildinfo b/.buildinfo
index f9aa9d2..77688ec 100644
--- a/.buildinfo
+++ b/.buildinfo
@@ -1,4 +1,4 @@
# Sphinx build info version 1
-# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: 42cebe1db5a1e3fefae0206dd987fba9
+# This file records the configuration used when building these files. When it is not found, a full rebuild will be done.
+config: d34437364b4a3362dca2bf305d551f77
tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle
index b5c8704..aa19ea1 100644
Binary files a/.doctrees/environment.pickle and b/.doctrees/environment.pickle differ
diff --git a/_modules/index.html b/_modules/index.html
index be5672c..6e9edbd 100644
--- a/_modules/index.html
+++ b/_modules/index.html
@@ -4,7 +4,7 @@
-
+
Source code for qiskit_research.utils.pauli_twirling
CXCancellation,Optimize1qGatesDecomposition,)
-fromqiskit.quantum_infoimportPauli,pauli_basis
+fromqiskit.quantum_infoimportPauli,Operator,pauli_basisfromqiskit_research.utils.pulse_scalingimportBASIS_GATES
+# Single qubit Pauli gatesI=IGate()X=XGate()Y=YGate()Z=ZGate()
+# 2Q entangling gates
+CX=CXGate()# cnot; controlled-X
+CY=CYGate()# controlled-Y
+CZ=CZGate()# controlled-Z
+CH=CHGate()# controlled-Hadamard
+CS=CSGate()# controlled-S
+DCX=DCXGate()# double cnot
+CSX=CSXGate()# controlled sqrt X
+CSdg=CSdgGate()# controlled S^dagger
+ECR=ECRGate()# echoed cross-resonance
+Swap=SwapGate()# swap
+iSwap=iSwapGate()# imaginary swap
+
# this list consists of the 2-qubit rotation gatesTWO_QUBIT_PAULI_GENERATORS={"rxx":Pauli("XX"),
@@ -294,6 +321,74 @@
Source code for qiskit_research.utils.pauli_twirling
"secr":Pauli("XZ"),}
+
+defmatch_global_phase(a,b):
+"""Phase the given arrays so that their phases match at one entry.
+
+ Args:
+ a: A Numpy array.
+ b: Another Numpy array.
+
+ Returns:
+ A pair of arrays (a', b') that are equal if and only if a == b * exp(i phi)
+ for some real number phi.
+ """
+ ifa.shape!=b.shape:
+ returna,b
+ # use the largest entry of one of the matrices to maximize precision
+ index=max(np.ndindex(*a.shape),key=lambdai:abs(b[i]))
+ phase_a=cmath.phase(a[index])
+ phase_b=cmath.phase(b[index])
+ returna*cmath.rect(1,-phase_a),b*cmath.rect(1,-phase_b)
+
+
+defallclose_up_to_global_phase(a,b,rtol=1e-05,atol=1e-08,equal_nan=False):
+"""Check if two operators are close up to a global phase."""
+ # Phase both operators to match their phases
+ phased_op1,phased_op2=match_global_phase(a,b)
+ returnnp.allclose(phased_op1,phased_op2,rtol,atol,equal_nan)
+
+
+defcreate_pauli_twirling_sets(two_qubit_gate):
+"""Generate the Pauli twirling sets for a given 2Q gate.
+
+ Sets are ordered such that gate[0] and gate[1] are pre-rotations
+ applied to control and target, respectively. gate[2] and gate[3]
+ are post-rotations for control and target, respectively.
+
+ Parameters:
+ two_qubit_gate (Gate): Input two-qubit gate
+
+ Returns:
+ tuple: Tuple of all twirling gate sets
+ """
+
+ target_unitary=np.array(two_qubit_gate)
+ twirling_sets=[]
+
+ # Generate combinations of 4 gates from the operator list
+ forgatesinitertools.product(itertools.product([I,X,Y,Z],repeat=2),repeat=2):
+ qc=_build_twirl_circuit(gates,two_qubit_gate)
+ qc_array=Operator.from_circuit(qc).to_matrix()
+ ifallclose_up_to_global_phase(qc_array,target_unitary):
+ twirling_sets.append(gates)
+
+ returntuple(twirling_sets)
+
+
+def_build_twirl_circuit(gates,two_qubit_gate):
+"""Build the twirled quantum circuit with specified gates."""
+ qc=QuantumCircuit(2)
+
+ qc.append(gates[0][0],[0])
+ qc.append(gates[0][1],[1])
+ qc.append(two_qubit_gate,[0,1])
+ qc.append(gates[1][0],[0])
+ qc.append(gates[1][1],[1])
+
+ returnqc
+
+
# this dictionary stores the twirl sets for each supported gate# each key is the name of a supported gate# each value is a tuple that represents the twirl set for the gate
@@ -301,24 +396,17 @@
Source code for qiskit_research.utils.pauli_twirling
# "before" and "after" are tuples of single-qubit gates to be applied
# before and after the gate to be twirledTWIRL_GATES={
- "cx":(
- ((I,I),(I,I)),
- ((I,X),(I,X)),
- ((I,Y),(Z,Y)),
- ((I,Z),(Z,Z)),
- ((X,I),(X,X)),
- ((X,X),(X,I)),
- ((X,Y),(Y,Z)),
- ((X,Z),(Y,Y)),
- ((Y,I),(Y,X)),
- ((Y,X),(Y,I)),
- ((Y,Y),(X,Z)),
- ((Y,Z),(X,Y)),
- ((Z,I),(Z,I)),
- ((Z,X),(Z,X)),
- ((Z,Y),(I,Y)),
- ((Z,Z),(I,Z)),
- ),
+ "cx":create_pauli_twirling_sets(CX),
+ "cy":create_pauli_twirling_sets(CY),
+ "cz":create_pauli_twirling_sets(CZ),
+ "ch":create_pauli_twirling_sets(CH),
+ "cs":create_pauli_twirling_sets(CS),
+ "dcx":create_pauli_twirling_sets(DCX),
+ "csx":create_pauli_twirling_sets(CSX),
+ "csdg":create_pauli_twirling_sets(CSdg),
+ "ecr":create_pauli_twirling_sets(ECR),
+ "swap":create_pauli_twirling_sets(Swap),
+ "iswap":create_pauli_twirling_sets(iSwap),}
@@ -447,7 +535,7 @@
Source code for qiskit_research.utils.pauli_twirling