1
- from qiskit import IBMQ
2
1
from qiskit import BasicAer as Aer
3
2
from qiskit import ClassicalRegister , QuantumRegister , QuantumCircuit
4
3
from qiskit import execute
8
7
from matplotlib .patches import Circle , Rectangle
9
8
import copy
10
9
from ipywidgets import widgets
11
- from IPython .display import display , clear_output
12
-
13
- try :
14
- IBMQ .load_accounts ()
15
- except :
16
- pass
10
+ from IPython .display import display , clear_output
17
11
18
12
class run_game ():
19
13
# Implements a puzzle, which is defined by the given inputs.
@@ -43,7 +37,9 @@ def __init__(self,initialize, success_condition, allowed_gates, vi, qubit_names,
43
37
shots=1024
44
38
Number of shots used to to calculate expectation values.
45
39
mode='circle'
46
- Either the standard 'Hello Quantum' visualization can be used (with mode='circle') or the alternative line based one (mode='line').
40
+ Either the standard 'Hello Quantum' visualization can be used (with mode='circle'), or the extended one (mode='y') or the alternative line based one (mode='line').
41
+ y_boxes = False
42
+ Whether to show expectation values involving y.
47
43
verbose=False
48
44
"""
49
45
@@ -79,6 +75,9 @@ def get_success(required_gates):
79
75
for gate in required_gates [qubit ]:
80
76
success = success and (required_gates [qubit ][gate ]== 0 )
81
77
return success
78
+
79
+ def show_circuit ():
80
+ gates = get_total_gate_list
82
81
83
82
def get_command (gate ,qubit ):
84
83
# For a given gate and qubit, return the string describing the corresoinding Qiskit string.
@@ -96,6 +95,9 @@ def get_command(gate,qubit):
96
95
elif gate in ['ry(pi/4)' ,'ry(-pi/4)' ]:
97
96
real_command = 'grid.qc.ry(' + '-' * (gate == 'ry(-pi/4)' )+ 'np.pi/4,grid.qr[' + qubit + '])'
98
97
clean_command = 'qc.ry(' + '-' * (gate == 'ry(-pi/4)' )+ 'np.pi/4,' + qubit_name + ')'
98
+ elif gate in ['rx(pi/4)' ,'rx(-pi/4)' ]:
99
+ real_command = 'grid.qc.rx(' + '-' * (gate == 'rx(-pi/4)' )+ 'np.pi/4,grid.qr[' + qubit + '])'
100
+ clean_command = 'qc.rx(' + '-' * (gate == 'rx(-pi/4)' )+ 'np.pi/4,' + qubit_name + ')'
99
101
elif gate in ['cz' ,'cx' ,'swap' ]:
100
102
real_command = 'grid.qc.' + gate + '(grid.qr[' + '0' * (qubit == '1' )+ '1' * (qubit == '0' )+ '],grid.qr[' + qubit + '])'
101
103
clean_command = 'qc.' + gate + '(' + other_name + ',' + qubit_name + ')'
@@ -105,7 +107,10 @@ def get_command(gate,qubit):
105
107
bloch = [None ]
106
108
107
109
# set up initial state and figure
108
- grid = pauli_grid (backend = backend ,shots = shots ,mode = mode )
110
+ if mode == 'y' :
111
+ grid = pauli_grid (backend = backend ,shots = shots ,mode = 'circle' ,y_boxes = True )
112
+ else :
113
+ grid = pauli_grid (backend = backend ,shots = shots ,mode = mode )
109
114
for gate in initialize :
110
115
eval ( get_command (gate [0 ],gate [1 ])[0 ] )
111
116
@@ -147,8 +152,8 @@ def get_command(gate,qubit):
147
152
148
153
boxes = widgets .VBox ([gate ,qubit ,action ])
149
154
display (boxes )
150
- if vi [ 1 ] :
151
- print ('\n Your quantum program so far\n ' )
155
+ if qubit_names == { '0' : 'q[0]' , '1' : 'q[1]' } :
156
+ print ('\n Your quantum program so far: \n \n q = QuantumRegister(2) \n b = ClassicalRegister(2) \n qc = QuantumCircuit(q,b) \n ' )
152
157
self .program = []
153
158
154
159
def given_gate (a ):
@@ -202,8 +207,8 @@ def given_action(c):
202
207
else :
203
208
command = get_command (q_gate ,q01 )
204
209
eval (command [0 ])
205
- if vi [ 1 ]:
206
- print (command [1 ])
210
+ if qubit_names in [{ '0' : 'q[0]' , '1' : 'q[1]' },{ '0' : 'A' , '1' : 'B' } ]:
211
+ print (' ' + command [1 ])
207
212
self .program .append ( command [1 ] )
208
213
if required_gates [q01 ][gate .value ]> 0 :
209
214
required_gates [q01 ][gate .value ] -= 1
@@ -225,24 +230,41 @@ def given_action(c):
225
230
qubit .observe (given_qubit )
226
231
action .observe (given_action )
227
232
233
+ def get_circuit (puzzle ):
234
+
235
+ q = QuantumRegister (2 ,'q' )
236
+ b = ClassicalRegister (2 ,'b' )
237
+ qc = QuantumCircuit (q ,b )
238
+
239
+ for line in puzzle .program :
240
+ eval (line )
228
241
242
+ return qc
243
+
229
244
class pauli_grid ():
230
245
# Allows a quantum circuit to be created, modified and implemented, and visualizes the output in the style of 'Hello Quantum'.
231
246
232
- def __init__ (self ,backend = Aer .get_backend ('qasm_simulator' ),shots = 1024 ,mode = 'circle' ):
247
+ def __init__ (self ,backend = Aer .get_backend ('qasm_simulator' ),shots = 1024 ,mode = 'circle' , y_boxes = False ):
233
248
"""
234
249
backend=Aer.get_backend('qasm_simulator')
235
250
Backend to be used by Qiskit to calculate expectation values (defaults to local simulator).
236
251
shots=1024
237
252
Number of shots used to to calculate expectation values.
238
253
mode='circle'
239
- Either the standard 'Hello Quantum' visualization can be used (with mode='circle') or the alternative line based one (mode='line').
254
+ Either the standard 'Hello Quantum' visualization can be used (with mode='circle') or the alternative line based one (mode='line').
255
+ y_boxes=True
256
+ Whether to display full grid that includes Y expectation values.
240
257
"""
241
258
242
259
self .backend = backend
243
260
self .shots = shots
244
-
245
- self .box = {'ZI' :(- 1 , 2 ),'XI' :(- 2 , 3 ),'IZ' :( 1 , 2 ),'IX' :( 2 , 3 ),'ZZ' :( 0 , 3 ),'ZX' :( 1 , 4 ),'XZ' :(- 1 , 4 ),'XX' :( 0 , 5 )}
261
+
262
+ self .y_boxes = y_boxes
263
+ if self .y_boxes :
264
+ self .box = {'ZI' :(- 1 , 2 ),'XI' :(- 3 , 4 ),'IZ' :( 1 , 2 ),'IX' :( 3 , 4 ),'ZZ' :( 0 , 3 ),'ZX' :( 2 , 5 ),'XZ' :(- 2 , 5 ),'XX' :( 0 , 7 ),
265
+ 'YY' :(0 ,5 ), 'YI' :(- 2 ,3 ), 'IY' :(2 ,3 ), 'YZ' :(- 1 ,4 ), 'ZY' :(1 ,4 ), 'YX' :(1 ,6 ), 'XY' :(- 1 ,6 ) }
266
+ else :
267
+ self .box = {'ZI' :(- 1 , 2 ),'XI' :(- 2 , 3 ),'IZ' :( 1 , 2 ),'IX' :( 2 , 3 ),'ZZ' :( 0 , 3 ),'ZX' :( 1 , 4 ),'XZ' :(- 1 , 4 ),'XX' :( 0 , 5 )}
246
268
247
269
self .rho = {}
248
270
for pauli in self .box :
@@ -278,51 +300,62 @@ def __init__(self,backend=Aer.get_backend('qasm_simulator'),shots=1024,mode='cir
278
300
279
301
280
302
def get_rho (self ):
281
- # Runs the circuit specified by self.qc and determines the expectation values for 'ZI', 'IZ', 'ZZ', 'XI', 'IX', 'XX', 'ZX' and 'XZ'.
303
+ # Runs the circuit specified by self.qc and determines the expectation values for 'ZI', 'IZ', 'ZZ', 'XI', 'IX', 'XX', 'ZX' and 'XZ' (and the ones with Ys too if needed).
304
+
305
+ if self .y_boxes :
306
+ corr = ['ZZ' ,'ZX' ,'XZ' ,'XX' ,'YY' ,'YX' ,'YZ' ,'XY' ,'ZY' ]
307
+ ps = ['X' ,'Y' ,'Z' ]
308
+ else :
309
+ corr = ['ZZ' ,'ZX' ,'XZ' ,'XX' ]
310
+ ps = ['X' ,'Z' ]
282
311
283
- bases = ['ZZ' ,'ZX' ,'XZ' ,'XX' ]
284
312
results = {}
285
- for basis in bases :
313
+ for basis in corr :
286
314
temp_qc = copy .deepcopy (self .qc )
287
315
for j in range (2 ):
288
316
if basis [j ]== 'X' :
289
317
temp_qc .h (self .qr [j ])
318
+ elif basis [j ]== 'Y' :
319
+ temp_qc .sdg (self .qr [j ])
320
+ temp_qc .h (self .qr [j ])
290
321
temp_qc .barrier (self .qr )
291
322
temp_qc .measure (self .qr ,self .cr )
292
323
job = execute (temp_qc , backend = self .backend , shots = self .shots )
293
324
results [basis ] = job .result ().get_counts ()
294
325
for string in results [basis ]:
295
326
results [basis ][string ] = results [basis ][string ]/ self .shots
296
-
327
+
297
328
prob = {}
298
329
# prob of expectation value -1 for single qubit observables
299
330
for j in range (2 ):
300
- for p in ['X' ,'Z' ]:
331
+
332
+ for p in ps :
301
333
pauli = {}
302
- for pp in 'IXZ' :
334
+ for pp in [ 'I' ] + ps :
303
335
pauli [pp ] = (j == 1 )* pp + p + (j == 0 )* pp
304
336
prob [pauli ['I' ]] = 0
305
- for basis in [pauli ['X' ],pauli ['Z' ]]:
337
+ for ppp in ps :
338
+ basis = pauli [ppp ]
306
339
for string in results [basis ]:
307
340
if string [(j + 1 )% 2 ]== '1' :
308
- prob [pauli ['I' ]] += results [basis ][string ]/ 2
341
+ prob [pauli ['I' ]] += results [basis ][string ]/ (2 + self .y_boxes )
342
+
309
343
# prob of expectation value -1 for two qubit observables
310
- for basis in [ 'ZZ' , 'ZX' , 'XZ' , 'XX' ] :
344
+ for basis in corr :
311
345
prob [basis ] = 0
312
346
for string in results [basis ]:
313
347
if string [0 ]!= string [1 ]:
314
348
prob [basis ] += results [basis ][string ]
315
349
316
350
for pauli in prob :
317
351
self .rho [pauli ] = 1 - 2 * prob [pauli ]
318
-
319
352
320
353
def update_grid (self ,rho = None ,labels = False ,bloch = None ,hidden = [],qubit = True ,corr = True ,message = "" ):
321
354
"""
322
355
rho = None
323
356
Dictionary of expectation values for 'ZI', 'IZ', 'ZZ', 'XI', 'IX', 'XX', 'ZX' and 'XZ'. If supplied, this will be visualized instead of the results of running self.qc.
324
- labels = None
325
- Dictionary of strings for 'ZI', 'IZ', 'ZZ', 'XI', 'IX', 'XX', 'ZX' and 'XZ' that are printed in the corresponding boxes.
357
+ labels = False
358
+ Determines whether basis labels are printed in the corresponding boxes.
326
359
bloch = None
327
360
If a qubit name is supplied, and if mode='line', Bloch circles are displayed for this qubit
328
361
hidden = []
@@ -387,7 +420,7 @@ def add_line(line,pauli_pos,pauli):
387
420
self .lines [pauli ]['w' ] = plt .plot ( [a [0 ],b [0 ]], [a [1 ],b [1 ]], color = (1.0 ,1.0 ,1.0 ), lw = lw )
388
421
self .lines [pauli ]['b' ] = plt .plot ( [b [0 ],c [0 ]], [b [1 ],c [1 ]], color = (0.0 ,0.0 ,0.0 ), lw = lw )
389
422
return coord
390
-
423
+
391
424
l = 0.9 # line length
392
425
r = 0.6 # circle radius
393
426
L = 0.98 * np .sqrt (2 ) # box height and width
@@ -442,11 +475,14 @@ def add_line(line,pauli_pos,pauli):
442
475
self .bottom .set_text (message )
443
476
444
477
if labels :
445
- for pauli in box :
446
- plt .text (self .box [pauli ][0 ]- 0.05 ,self .box [pauli ][1 ]- 0.85 , pauli )
478
+ for pauli in self . box :
479
+ plt .text (self .box [pauli ][0 ]- 0.18 ,self .box [pauli ][1 ]- 0.85 , pauli )
447
480
448
- self .ax .set_xlim ([- 3 ,3 ])
449
- self .ax .set_ylim ([0 ,6 ])
481
+ if self .y_boxes :
482
+ self .ax .set_xlim ([- 4 ,4 ])
483
+ self .ax .set_ylim ([0 ,8 ])
484
+ else :
485
+ self .ax .set_xlim ([- 3 ,3 ])
486
+ self .ax .set_ylim ([0 ,6 ])
450
487
451
- self .fig .canvas .draw ()
452
-
488
+ self .fig .canvas .draw ()
0 commit comments