7
7
from qibo import gates
8
8
from qibo .backends import GlobalBackend
9
9
from qibo .models import Circuit
10
- from qibolab import ExecutionParameters
11
10
from qibolab .platform import Platform
12
- from qibolab .pulses import PulseSequence
13
11
from qibolab .qubits import QubitId
14
12
15
13
from qibocal .auto .operation import Data , Parameters , Results , Routine
16
14
from qibocal .auto .transpile import dummy_transpiler , execute_transpiled_circuit
17
15
from qibocal .config import log
18
16
19
- from .utils import calculate_frequencies
20
-
21
17
22
18
@dataclass
23
19
class ReadoutMitigationMatrixParameters (Parameters ):
24
20
"""ReadoutMitigationMatrix matrix inputs."""
25
21
26
- pulses : Optional [bool ] = True
27
- """Get readout mitigation matrix using pulses. If False gates will be used."""
28
22
nshots : Optional [int ] = None
29
23
"""Number of shots."""
30
24
relaxation_time : Optional [int ] = None
@@ -37,10 +31,14 @@ class ReadoutMitigationMatrixResults(Results):
37
31
field (default_factory = dict )
38
32
)
39
33
"""Readout mitigation matrices (inverse of measurement matrix)."""
40
- measurement_matrix : dict [tuple [QubitId , ...], npt .NDArray [np .float64 ]] = field (
41
- default_factory = dict
42
- )
43
- """Matrix containing measurement matrices for each state."""
34
+
35
+
36
+ ReadoutMitigationMatrixType = np .dtype (
37
+ [
38
+ ("state" , int ),
39
+ ("frequency" , np .float64 ),
40
+ ]
41
+ )
44
42
45
43
46
44
@dataclass
@@ -54,40 +52,6 @@ class ReadoutMitigationMatrixData(Data):
54
52
data : dict = field (default_factory = dict )
55
53
"""Raw data acquited."""
56
54
57
- def add (self , qubits , state , freqs ):
58
- for result_state , freq in freqs .items ():
59
- self .data [
60
- qubits
61
- + (
62
- state ,
63
- result_state ,
64
- )
65
- ] = freq
66
-
67
- for basis in [format (i , f"0{ len (qubits )} b" ) for i in range (2 ** len (qubits ))]:
68
- if (
69
- qubits
70
- + (
71
- state ,
72
- basis ,
73
- )
74
- not in self .data
75
- ):
76
- self .data [
77
- qubits
78
- + (
79
- state ,
80
- basis ,
81
- )
82
- ] = 0
83
-
84
- def __getitem__ (self , qubits ):
85
- return {
86
- index : value
87
- for index , value in self .data .items ()
88
- if qubits == list (index [: len (index ) - 2 ])
89
- }
90
-
91
55
92
56
def _acquisition (
93
57
params : ReadoutMitigationMatrixParameters ,
@@ -105,75 +69,52 @@ def _acquisition(
105
69
nqubits = len (qubits )
106
70
for i in range (2 ** nqubits ):
107
71
state = format (i , f"0{ nqubits } b" )
108
- if params .pulses :
109
- sequence = PulseSequence ()
110
- for q , bit in enumerate (state ):
111
- if bit == "1" :
112
- sequence .add (
113
- platform .create_RX_pulse (
114
- qubits [q ], start = 0 , relative_phase = 0
115
- )
116
- )
117
- measurement_start = sequence .finish
118
- for q in range (len (state )):
119
- MZ_pulse = platform .create_MZ_pulse (
120
- qubits [q ], start = measurement_start
121
- )
122
- sequence .add (MZ_pulse )
123
- results = platform .execute_pulse_sequence (
124
- sequence , ExecutionParameters (nshots = params .nshots )
125
- )
126
- data .add (
127
- tuple (qubits ), state , calculate_frequencies (results , tuple (qubits ))
72
+ c = Circuit (
73
+ nqubits ,
74
+ )
75
+ for q , bit in enumerate (state ):
76
+ if bit == "1" :
77
+ c .add (gates .X (q ))
78
+ c .add (gates .M (* range (nqubits )))
79
+ _ , results = execute_transpiled_circuit (
80
+ c , qubits , backend , nshots = params .nshots , transpiler = transpiler
81
+ )
82
+ frequencies = np .zeros (2 ** len (qubits ))
83
+ for i , freq in results .frequencies ().items ():
84
+ frequencies [int (i , 2 )] = freq
85
+ for freq in frequencies :
86
+ data .register_qubit (
87
+ ReadoutMitigationMatrixType ,
88
+ (qubits ),
89
+ dict (
90
+ state = np .array ([int (state , 2 )]),
91
+ frequency = freq ,
92
+ ),
128
93
)
129
- else :
130
- c = Circuit (
131
- platform .nqubits ,
132
- wire_names = [str (i ) for i in range (platform .nqubits )],
133
- )
134
- for q , bit in enumerate (state ):
135
- if bit == "1" :
136
- c .add (gates .X (qubits [q ]))
137
- c .add (gates .M (* [qubits [i ] for i in range (len (state ))]))
138
- _ , results = execute_transpiled_circuit (
139
- c , qubit_map , backend , nshots = params .nshots , transpiler = transpiler
140
- )
141
- data .add (tuple (qubits ), state , dict (results .frequencies ()))
142
94
return data
143
95
144
96
145
97
def _fit (data : ReadoutMitigationMatrixData ) -> ReadoutMitigationMatrixResults :
146
98
"""Post processing for readout mitigation matrix protocol."""
147
99
readout_mitigation_matrix = {}
148
- measurement_matrix = {}
149
- for qubit in data .qubit_list :
150
- qubit_data = data [qubit ]
151
- matrix = np .zeros ((2 ** len (qubit ), 2 ** len (qubit )))
152
- computational_basis = [
153
- format (i , f"0{ len (qubit )} b" ) for i in range (2 ** len (qubit ))
154
- ]
155
- for state in computational_basis :
156
- column = np .zeros (2 ** len (qubit ))
157
- qubit_state_data = {
158
- index : value
159
- for index , value in qubit_data .items ()
160
- if index [- 2 ] == state
161
- }
162
- for index , value in qubit_state_data .items ():
163
- column [(int (index [- 1 ], 2 ))] = value / data .nshots
164
- matrix [:, int (state , 2 )] = np .flip (column )
165
-
166
- measurement_matrix [tuple (qubit )] = matrix .tolist ()
100
+ for qubits in data .qubit_list :
101
+ qubit_data = data .data [tuple (qubits )]
102
+ mitigation_matrix = []
103
+ for state in range (2 ** len (qubits )):
104
+ mitigation_matrix .append (qubit_data [qubit_data .state == state ].frequency )
105
+ mitigation_matrix = np .vstack (mitigation_matrix ) / data .nshots
167
106
try :
168
- readout_mitigation_matrix [tuple (qubit )] = np .linalg .inv (matrix ).tolist ()
107
+ readout_mitigation_matrix [tuple (qubits )] = np .linalg .inv (
108
+ mitigation_matrix
109
+ ).tolist ()
169
110
except np .linalg .LinAlgError as e :
170
111
log .warning (f"ReadoutMitigationMatrix: the fitting was not succesful. { e } " )
171
-
172
- return ReadoutMitigationMatrixResults (
112
+ res = ReadoutMitigationMatrixResults (
173
113
readout_mitigation_matrix = readout_mitigation_matrix ,
174
- measurement_matrix = measurement_matrix ,
175
114
)
176
115
116
+ return res
117
+
177
118
178
119
def _plot (
179
120
data : ReadoutMitigationMatrixData ,
@@ -187,12 +128,12 @@ def _plot(
187
128
computational_basis = [
188
129
format (i , f"0{ len (target )} b" ) for i in range (2 ** len (target ))
189
130
]
190
- z = fit .measurement_matrix [tuple (target )]
191
-
131
+ measurement_matrix = np . linalg . inv ( fit .readout_mitigation_matrix [tuple (target )])
132
+ z = measurement_matrix
192
133
fig = px .imshow (
193
134
z ,
194
135
x = computational_basis ,
195
- y = computational_basis [:: - 1 ] ,
136
+ y = computational_basis ,
196
137
text_auto = True ,
197
138
labels = {
198
139
"x" : "Prepeared States" ,
0 commit comments