tequila-basic 1.9.8__py3-none-any.whl → 1.9.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. tequila/__init__.py +29 -14
  2. tequila/apps/__init__.py +14 -5
  3. tequila/apps/_unary_state_prep_impl.py +145 -112
  4. tequila/apps/adapt/__init__.py +9 -1
  5. tequila/apps/adapt/adapt.py +154 -113
  6. tequila/apps/krylov/__init__.py +1 -1
  7. tequila/apps/krylov/krylov.py +23 -21
  8. tequila/apps/robustness/helpers.py +10 -6
  9. tequila/apps/robustness/interval.py +238 -156
  10. tequila/apps/unary_state_prep.py +29 -23
  11. tequila/autograd_imports.py +8 -5
  12. tequila/circuit/__init__.py +2 -1
  13. tequila/circuit/_gates_impl.py +135 -67
  14. tequila/circuit/circuit.py +177 -88
  15. tequila/circuit/compiler.py +114 -105
  16. tequila/circuit/gates.py +288 -120
  17. tequila/circuit/gradient.py +35 -23
  18. tequila/circuit/noise.py +83 -74
  19. tequila/circuit/postselection.py +120 -0
  20. tequila/circuit/pyzx.py +10 -6
  21. tequila/circuit/qasm.py +201 -83
  22. tequila/circuit/qpic.py +63 -61
  23. tequila/grouping/binary_rep.py +148 -146
  24. tequila/grouping/binary_utils.py +84 -75
  25. tequila/grouping/compile_groups.py +334 -230
  26. tequila/grouping/ev_utils.py +77 -41
  27. tequila/grouping/fermionic_functions.py +383 -308
  28. tequila/grouping/fermionic_methods.py +170 -123
  29. tequila/grouping/overlapping_methods.py +69 -52
  30. tequila/hamiltonian/paulis.py +12 -13
  31. tequila/hamiltonian/paulistring.py +1 -1
  32. tequila/hamiltonian/qubit_hamiltonian.py +45 -35
  33. tequila/ml/__init__.py +1 -0
  34. tequila/ml/interface_torch.py +19 -16
  35. tequila/ml/ml_api.py +11 -10
  36. tequila/ml/utils_ml.py +12 -11
  37. tequila/objective/__init__.py +8 -3
  38. tequila/objective/braket.py +55 -47
  39. tequila/objective/objective.py +91 -56
  40. tequila/objective/qtensor.py +36 -27
  41. tequila/optimizers/__init__.py +31 -23
  42. tequila/optimizers/_containers.py +11 -7
  43. tequila/optimizers/optimizer_base.py +111 -83
  44. tequila/optimizers/optimizer_gd.py +258 -231
  45. tequila/optimizers/optimizer_gpyopt.py +56 -42
  46. tequila/optimizers/optimizer_scipy.py +157 -112
  47. tequila/quantumchemistry/__init__.py +66 -38
  48. tequila/quantumchemistry/chemistry_tools.py +394 -203
  49. tequila/quantumchemistry/encodings.py +121 -13
  50. tequila/quantumchemistry/madness_interface.py +170 -96
  51. tequila/quantumchemistry/orbital_optimizer.py +86 -40
  52. tequila/quantumchemistry/psi4_interface.py +166 -97
  53. tequila/quantumchemistry/pyscf_interface.py +70 -23
  54. tequila/quantumchemistry/qc_base.py +866 -414
  55. tequila/simulators/__init__.py +0 -3
  56. tequila/simulators/simulator_api.py +258 -106
  57. tequila/simulators/simulator_aqt.py +102 -0
  58. tequila/simulators/simulator_base.py +156 -55
  59. tequila/simulators/simulator_cirq.py +58 -42
  60. tequila/simulators/simulator_cudaq.py +600 -0
  61. tequila/simulators/simulator_ddsim.py +390 -0
  62. tequila/simulators/simulator_mqp.py +30 -0
  63. tequila/simulators/simulator_pyquil.py +190 -171
  64. tequila/simulators/simulator_qibo.py +95 -87
  65. tequila/simulators/simulator_qiskit.py +124 -114
  66. tequila/simulators/simulator_qlm.py +52 -26
  67. tequila/simulators/simulator_qulacs.py +85 -59
  68. tequila/simulators/simulator_spex.py +464 -0
  69. tequila/simulators/simulator_symbolic.py +6 -5
  70. tequila/simulators/test_spex_simulator.py +208 -0
  71. tequila/tools/convenience.py +4 -4
  72. tequila/tools/qng.py +72 -64
  73. tequila/tools/random_generators.py +38 -34
  74. tequila/utils/bitstrings.py +13 -7
  75. tequila/utils/exceptions.py +19 -5
  76. tequila/utils/joined_transformation.py +8 -10
  77. tequila/utils/keymap.py +0 -5
  78. tequila/utils/misc.py +6 -4
  79. tequila/version.py +1 -1
  80. tequila/wavefunction/qubit_wavefunction.py +52 -30
  81. {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/METADATA +23 -17
  82. tequila_basic-1.9.10.dist-info/RECORD +93 -0
  83. {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/WHEEL +1 -1
  84. tequila_basic-1.9.8.dist-info/RECORD +0 -86
  85. {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info/licenses}/LICENSE +0 -0
  86. {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,7 @@ import numpy as np
8
8
  import numpy.linalg as npl
9
9
  import copy
10
10
 
11
+
11
12
  def compile_commuting_parts(H, unitary_circuit="improved", *args, **kwargs):
12
13
  """
13
14
  Compile the commuting parts of a QubitHamiltonian
@@ -20,7 +21,7 @@ def compile_commuting_parts(H, unitary_circuit="improved", *args, **kwargs):
20
21
  -------
21
22
  A list of tuples containing all-Z Hamiltonian and corresponding Rotations
22
23
  """
23
- if "options" in kwargs and not(kwargs["options"] is None) and "method" in kwargs["options"]:
24
+ if "options" in kwargs and kwargs["options"] is not None and "method" in kwargs["options"]:
24
25
  method = kwargs["options"]["method"]
25
26
  else:
26
27
  method = "rlf"
@@ -30,8 +31,8 @@ def compile_commuting_parts(H, unitary_circuit="improved", *args, **kwargs):
30
31
  return "qubit"
31
32
  elif method == "lr" or method == "fff-lr":
32
33
  return "fermionic"
33
-
34
- if method_class(method) == 'qubit':
34
+
35
+ if method_class(method) == "qubit":
35
36
  if unitary_circuit is None or unitary_circuit.lower() == "improved":
36
37
  # @ Zack
37
38
  result, suggested_samples = _compile_commuting_parts_zb(H, *args, **kwargs)
@@ -41,46 +42,51 @@ def compile_commuting_parts(H, unitary_circuit="improved", *args, **kwargs):
41
42
  commuting_parts, suggested_samples = binary_H.commuting_groups(*args, **kwargs)
42
43
  result = [cH.get_qubit_wise() for cH in commuting_parts]
43
44
  return result, suggested_samples
44
-
45
- elif method_class(method) == 'fermionic':
45
+
46
+ elif method_class(method) == "fermionic":
46
47
  options = kwargs["options"]
47
48
  if "n_el" in options:
48
49
  n_el = int(options["n_el"])
49
- elif "mol_name" in options:
50
+ elif "mol_name" in options:
50
51
  n_el = n_elec(options["mol_name"])
51
52
  else:
52
- raise TequilaException("Please specify either {mol_name:} or {n_el:} in the dictionary provided as the keyward argument (optimize_measurements) to function (ExpectationValue).")
53
+ raise TequilaException(
54
+ "Please specify either {mol_name:} or {n_el:} in the dictionary provided as the keyward argument (optimize_measurements) to function (ExpectationValue)."
55
+ )
53
56
 
54
57
  if "reverse_H_transf" in options:
55
58
  reverse_H_transf = options["reverse_H_transf"]
56
59
  else:
57
60
  print("Using default reverse_H_transf, i.e., reverse_jordan_wigner.")
58
61
  reverse_H_transf = _reverse_jordan_wigner
59
-
62
+
60
63
  h_ferm = reverse_H_transf(H)
61
64
 
62
- if method == 'lr':
65
+ if method == "lr":
63
66
  u_ops, cartan_obt, cartan_tbt, suggested_samples = do_svd(h_ferm, n_el)
64
67
  result = [get_fermion_wise(cartan_obt, u_ops[0])]
65
68
  for i in range(len(cartan_tbt)):
66
- result.append(get_fermion_wise(cartan_tbt[i], u_ops[i+1]))
69
+ result.append(get_fermion_wise(cartan_tbt[i], u_ops[i + 1]))
67
70
  return result, suggested_samples
68
- elif method == 'fff-lr':
69
-
70
- all_ops, u_ops, cartan_obt, cartan_tbt, suggested_samples = do_fff(h_ferm, n_el, options=options, metric_estim=False)
71
+ elif method == "fff-lr":
72
+ all_ops, u_ops, cartan_obt, cartan_tbt, suggested_samples = do_fff(
73
+ h_ferm, n_el, options=options, metric_estim=False
74
+ )
71
75
  result = [get_fermion_wise(cartan_obt, u_ops[0])]
72
76
  for i in range(len(cartan_tbt)):
73
- result.append(get_fermion_wise(cartan_tbt[i], u_ops[i+1]))
77
+ result.append(get_fermion_wise(cartan_tbt[i], u_ops[i + 1]))
74
78
  return result, suggested_samples
75
79
 
80
+
76
81
  def _reverse_jordan_wigner(H):
77
- '''
82
+ """
78
83
  Default funcion used by fermionic methods to obtain the H in the second quantized form.
79
- The user can specify a different reverse function if H was obtained from the fermionic
84
+ The user can specify a different reverse function if H was obtained from the fermionic
80
85
  Hamiltonian using a mapping different than the JordanWigner transformation.
81
- '''
86
+ """
82
87
  return reverse_jordan_wigner(H.to_openfermion())
83
88
 
89
+
84
90
  def _compile_commuting_parts_zb(H, *args, **kwargs):
85
91
  # @ Zack add main function here and rest in this file
86
92
  # should return list of commuting Hamiltonians in Z-Form and Circuits
@@ -132,28 +138,39 @@ def Tableau_algorithm(circuits):
132
138
  num_qubits = U.n_qubits
133
139
  Tableau, Phase_stabilizer, Phase_destabilizer, Circuit = initial_tableau(U, U.n_qubits)
134
140
 
135
- Tableau, Phase_stabilizer, Phase_destabilizer, Q0 = first_round_hadamard(Tableau, Phase_stabilizer,
136
- Phase_destabilizer) # H
137
- Tableau, Phase_stabilizer, Phase_destabilizer, Q1 = first_round_cnot(Tableau, Phase_stabilizer,
138
- Phase_destabilizer) # C
139
- Tableau, Phase_stabilizer, Phase_destabilizer, Q2 = first_round_phase(Tableau, Phase_stabilizer,
140
- Phase_destabilizer) # P
141
- Tableau, Phase_stabilizer, Phase_destabilizer, Q3 = second_round_cnot(Tableau, Phase_stabilizer,
142
- Phase_destabilizer) # C
143
- Tableau, Phase_stabilizer, Phase_destabilizer, Q4 = second_round_phase(Tableau, Phase_stabilizer,
144
- Phase_destabilizer) # P
145
- Tableau, Phase_stabilizer, Phase_destabilizer, Q5 = third_round_cnot(Tableau, Phase_stabilizer,
146
- Phase_destabilizer) # C
147
- Tableau, Phase_stabilizer, Phase_destabilizer, Q6 = second_round_hadamard(Tableau, Phase_stabilizer,
148
- Phase_destabilizer) # H
149
- Tableau, Phase_stabilizer, Phase_destabilizer, Q7 = third_round_phase(Tableau, Phase_stabilizer,
150
- Phase_destabilizer) # P
151
- Tableau, Phase_stabilizer, Phase_destabilizer, Q8 = fourth_round_cnot(Tableau, Phase_stabilizer,
152
- Phase_destabilizer) # C
153
- Tableau, Phase_stabilizer, Phase_destabilizer, Q9 = fourth_round_phase(Tableau, Phase_stabilizer,
154
- Phase_destabilizer) # P
155
- Tableau, Phase_stabilizer, Phase_destabilizer, Q10 = final_round_cnot(Tableau, Phase_stabilizer,
156
- Phase_destabilizer) # C
141
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q0 = first_round_hadamard(
142
+ Tableau, Phase_stabilizer, Phase_destabilizer
143
+ ) # H
144
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q1 = first_round_cnot(
145
+ Tableau, Phase_stabilizer, Phase_destabilizer
146
+ ) # C
147
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q2 = first_round_phase(
148
+ Tableau, Phase_stabilizer, Phase_destabilizer
149
+ ) # P
150
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q3 = second_round_cnot(
151
+ Tableau, Phase_stabilizer, Phase_destabilizer
152
+ ) # C
153
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q4 = second_round_phase(
154
+ Tableau, Phase_stabilizer, Phase_destabilizer
155
+ ) # P
156
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q5 = third_round_cnot(
157
+ Tableau, Phase_stabilizer, Phase_destabilizer
158
+ ) # C
159
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q6 = second_round_hadamard(
160
+ Tableau, Phase_stabilizer, Phase_destabilizer
161
+ ) # H
162
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q7 = third_round_phase(
163
+ Tableau, Phase_stabilizer, Phase_destabilizer
164
+ ) # P
165
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q8 = fourth_round_cnot(
166
+ Tableau, Phase_stabilizer, Phase_destabilizer
167
+ ) # C
168
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q9 = fourth_round_phase(
169
+ Tableau, Phase_stabilizer, Phase_destabilizer
170
+ ) # P
171
+ Tableau, Phase_stabilizer, Phase_destabilizer, Q10 = final_round_cnot(
172
+ Tableau, Phase_stabilizer, Phase_destabilizer
173
+ ) # C
157
174
  # now the code will optimize the CNOT segments
158
175
  # as put forth in https://arxiv.org/abs/quant-ph/0302002
159
176
 
@@ -268,7 +285,7 @@ def CNOT_matrix(list_of_gates, num_qubits):
268
285
  else:
269
286
  C_NOT_matrix = np.matmul(C_NOT_matrix, j) % 2
270
287
 
271
- return (C_NOT_matrix)
288
+ return C_NOT_matrix
272
289
 
273
290
 
274
291
  def optimize_circuit(CNOT_matrix):
@@ -281,7 +298,7 @@ def optimize_circuit(CNOT_matrix):
281
298
  ## putting together the two circuits
282
299
 
283
300
  # the CNOT gates in circuit two have the control and target qubits swapped
284
- for U in (circuit2):
301
+ for U in circuit2:
285
302
  control_qubit = U[1]
286
303
  target_qubit = U[0]
287
304
  optimized_circuit += tq.gates.CNOT(control_qubit, target_qubit)
@@ -292,7 +309,7 @@ def optimize_circuit(CNOT_matrix):
292
309
  target_qubit = U[1]
293
310
  optimized_circuit += tq.gates.CNOT(control_qubit, target_qubit)
294
311
 
295
- return (optimized_circuit)
312
+ return optimized_circuit
296
313
 
297
314
 
298
315
  def Lwr_CNOT_Synth(C_NOT_matrix):
@@ -306,12 +323,12 @@ def Lwr_CNOT_Synth(C_NOT_matrix):
306
323
  for sec in range(len(partitions)):
307
324
  # eliminate duplicate rows
308
325
  for j in range(m, m + iter):
309
- if np.all(C_NOT_matrix[j, m:m + iter] == 0):
326
+ if np.all(C_NOT_matrix[j, m : m + iter] == 0):
310
327
  break
311
328
  for k in range(0, num_qubits):
312
329
  if k < m + iter:
313
330
  continue
314
- if np.array_equal(C_NOT_matrix[j, m:m + iter], C_NOT_matrix[k, m:m + iter]):
331
+ if np.array_equal(C_NOT_matrix[j, m : m + iter], C_NOT_matrix[k, m : m + iter]):
315
332
  target_qubit = k
316
333
  control_qubit = j
317
334
  C_NOT_matrix[target_qubit, :] = (C_NOT_matrix[control_qubit, :] + C_NOT_matrix[target_qubit, :]) % 2
@@ -326,8 +343,9 @@ def Lwr_CNOT_Synth(C_NOT_matrix):
326
343
  if diag_one == 0:
327
344
  target_qubit = j
328
345
  control_qubit = row
329
- C_NOT_matrix[target_qubit, :] = (C_NOT_matrix[target_qubit, :] + C_NOT_matrix[control_qubit,
330
- :]) % 2
346
+ C_NOT_matrix[target_qubit, :] = (
347
+ C_NOT_matrix[target_qubit, :] + C_NOT_matrix[control_qubit, :]
348
+ ) % 2
331
349
  circ.append([control_qubit, target_qubit])
332
350
  diag_one = 1
333
351
  target_qubit = row
@@ -338,6 +356,7 @@ def Lwr_CNOT_Synth(C_NOT_matrix):
338
356
  m += iter
339
357
  return (C_NOT_matrix, circ)
340
358
 
359
+
341
360
  def is_canonical(tableau, phase_stab, phase_destab):
342
361
  dim = len(tableau)
343
362
  eye = np.identity(dim)
@@ -346,71 +365,85 @@ def is_canonical(tableau, phase_stab, phase_destab):
346
365
  else:
347
366
  return False
348
367
 
368
+
349
369
  def initial_tableau(circuit, number_of_qubits):
350
370
  """Goes through Thomsons circuit (expressed only in H,CNOT and S gates) to update the standard initial tableau
351
371
  as a 2*n X 2*n binary matrix. The final tableau is a binary representation of the circuit"""
352
372
  n = number_of_qubits
353
373
  a = np.identity(2 * n)
354
374
  x_destab = a[0:n, 0:n]
355
- z_destab = a[0:n, n:2 * n]
356
- x_stab = a[n:2 * n, 0:n]
357
- z_stab = a[n:2 * n, n:2 * n]
375
+ z_destab = a[0:n, n : 2 * n]
376
+ x_stab = a[n : 2 * n, 0:n]
377
+ z_stab = a[n : 2 * n, n : 2 * n]
358
378
  phase_destabilizer = np.zeros(n)
359
379
  phase_stabilizer = np.zeros(n)
360
380
  test_circuit = tq.circuit.QCircuit()
361
381
 
362
- for U in (circuit.gates):
363
-
364
- if U.name == 'Ry':
382
+ for U in circuit.gates:
383
+ if U.name == "Ry":
365
384
  if U.parameter > 0:
366
385
  # decomposing Ry as S^+ * H * S* H * S (we can only use clifford gates S,H,CNOT)
367
386
  target_qubit = U.target[0]
368
387
  test_circuit += tq.gates.S(target_qubit)
369
388
  for i in range(0, n):
370
389
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
371
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
390
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
391
+ )
372
392
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
373
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
393
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
394
+ )
374
395
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
375
396
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
376
397
 
377
398
  test_circuit += tq.gates.H(target_qubit)
378
399
  for i in range(0, n):
379
400
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
380
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
401
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
402
+ )
381
403
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
382
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
383
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
384
- i, target_qubit]
404
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
405
+ )
406
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
407
+ z_destab[i, target_qubit],
408
+ x_destab[i, target_qubit],
409
+ )
385
410
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
386
411
 
387
412
  for k in range(3):
388
413
  test_circuit += tq.gates.S(target_qubit)
389
414
  for i in range(0, n):
390
415
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
391
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
416
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
417
+ )
392
418
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
393
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
419
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
420
+ )
394
421
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
395
422
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
396
423
 
397
424
  test_circuit += tq.gates.H(target_qubit)
398
425
  for i in range(0, n):
399
426
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
400
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
427
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
428
+ )
401
429
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
402
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
403
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
404
- i, target_qubit]
430
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
431
+ )
432
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
433
+ z_destab[i, target_qubit],
434
+ x_destab[i, target_qubit],
435
+ )
405
436
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
406
437
 
407
438
  for k in range(3):
408
439
  test_circuit += tq.gates.S(target_qubit)
409
440
  for i in range(0, n):
410
441
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
411
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
442
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
443
+ )
412
444
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
413
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
445
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
446
+ )
414
447
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
415
448
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
416
449
 
@@ -419,95 +452,119 @@ def initial_tableau(circuit, number_of_qubits):
419
452
  test_circuit += tq.gates.S(target_qubit)
420
453
  for i in range(0, n):
421
454
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
422
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
455
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
456
+ )
423
457
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
424
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
458
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
459
+ )
425
460
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
426
461
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
427
462
 
428
463
  test_circuit += tq.gates.H(target_qubit)
429
464
  for i in range(0, n):
430
465
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
431
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
466
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
467
+ )
432
468
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
433
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
434
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
435
- i, target_qubit]
469
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
470
+ )
471
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
472
+ z_destab[i, target_qubit],
473
+ x_destab[i, target_qubit],
474
+ )
436
475
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
437
476
 
438
477
  test_circuit += tq.gates.S(target_qubit)
439
478
  for i in range(0, n):
440
479
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
441
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
480
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
481
+ )
442
482
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
443
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
483
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
484
+ )
444
485
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
445
486
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
446
487
 
447
488
  test_circuit += tq.gates.H(target_qubit)
448
489
  for i in range(0, n):
449
490
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
450
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
491
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
492
+ )
451
493
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
452
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
453
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
454
- i, target_qubit]
455
- z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[
456
- i, target_qubit]
494
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
495
+ )
496
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
497
+ z_destab[i, target_qubit],
498
+ x_destab[i, target_qubit],
499
+ )
500
+ z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
457
501
 
458
502
  for k in range(3):
459
503
  test_circuit += tq.gates.S(target_qubit)
460
504
  for i in range(0, n):
461
505
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
462
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
506
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
507
+ )
463
508
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
464
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
509
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
510
+ )
465
511
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
466
512
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
467
513
 
468
- if U.name == 'Phase':
514
+ if U.name == "Phase":
469
515
  target_qubit = U.target[0]
470
516
  test_circuit += tq.gates.S(target_qubit)
471
517
  for i in range(0, n):
472
518
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
473
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
519
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
520
+ )
474
521
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
475
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
522
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
523
+ )
476
524
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
477
525
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
478
526
 
479
527
  # decomposing Rx as H*S^3*H, (we can only use clifford gates S,H,CNOT)
480
- if U.name == 'Rx':
528
+ if U.name == "Rx":
481
529
  if U.parameter > 0:
482
-
483
530
  target_qubit = U.target[0]
484
531
  test_circuit += tq.gates.H(target_qubit)
485
532
  for i in range(0, n):
486
533
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
487
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
534
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
535
+ )
488
536
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
489
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
490
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
491
- i, target_qubit]
537
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
538
+ )
539
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
540
+ z_destab[i, target_qubit],
541
+ x_destab[i, target_qubit],
542
+ )
492
543
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
493
544
 
494
545
  test_circuit += tq.gates.S(target_qubit)
495
546
  for i in range(0, n):
496
547
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
497
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
548
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
549
+ )
498
550
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
499
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
551
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
552
+ )
500
553
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
501
554
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
502
555
 
503
556
  test_circuit += tq.gates.H(target_qubit)
504
557
  for i in range(0, n):
505
558
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
506
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
559
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
560
+ )
507
561
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
508
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
509
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
510
- i, target_qubit]
562
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
563
+ )
564
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
565
+ z_destab[i, target_qubit],
566
+ x_destab[i, target_qubit],
567
+ )
511
568
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
512
569
 
513
570
  else:
@@ -515,42 +572,54 @@ def initial_tableau(circuit, number_of_qubits):
515
572
  test_circuit += tq.gates.H(target_qubit)
516
573
  for i in range(0, n):
517
574
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
518
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
575
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
576
+ )
519
577
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
520
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
521
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
522
- i, target_qubit]
578
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
579
+ )
580
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
581
+ z_destab[i, target_qubit],
582
+ x_destab[i, target_qubit],
583
+ )
523
584
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
524
585
 
525
586
  for j in range(3):
526
587
  test_circuit += tq.gates.S(target_qubit)
527
588
  for i in range(0, n):
528
589
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
529
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
590
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
591
+ )
530
592
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
531
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
593
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
594
+ )
532
595
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
533
596
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
534
597
 
535
598
  test_circuit += tq.gates.H(target_qubit)
536
599
  for i in range(0, n):
537
600
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
538
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
601
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
602
+ )
539
603
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
540
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
541
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
542
- i, target_qubit]
604
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
605
+ )
606
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
607
+ z_destab[i, target_qubit],
608
+ x_destab[i, target_qubit],
609
+ )
543
610
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
544
611
 
545
- if U.name == 'Rz':
612
+ if U.name == "Rz":
546
613
  if U.parameter > 0:
547
614
  target_qubit = U.target[0]
548
615
  test_circuit += tq.gates.S(target_qubit)
549
616
  for i in range(0, n):
550
617
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
551
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
618
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
619
+ )
552
620
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
553
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
621
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
622
+ )
554
623
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
555
624
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
556
625
  else:
@@ -559,36 +628,43 @@ def initial_tableau(circuit, number_of_qubits):
559
628
  test_circuit += tq.gates.S(target_qubit)
560
629
  for i in range(0, n):
561
630
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
562
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
631
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
632
+ )
563
633
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
564
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
634
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
635
+ )
565
636
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
566
637
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
567
638
 
568
- if U.name == 'H':
569
-
639
+ if U.name == "H":
570
640
  target_qubit = U.target[0]
571
641
  test_circuit += tq.gates.H(target_qubit)
572
642
  for i in range(0, n):
573
643
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
574
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
644
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
645
+ )
575
646
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
576
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
577
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
578
- i, target_qubit]
647
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
648
+ )
649
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
650
+ z_destab[i, target_qubit],
651
+ x_destab[i, target_qubit],
652
+ )
579
653
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
580
654
 
581
- if U.name == 'X':
655
+ if U.name == "X":
582
656
  target_qubit = U.target[0]
583
657
  control_qubit = U.control[0]
584
658
  test_circuit += tq.gates.CNOT(control_qubit, target_qubit)
585
659
  for i in range(0, n):
586
660
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
587
- (int(x_destab[i, control_qubit]) * int(z_destab[i, target_qubit]))
588
- * (int(x_destab[i, target_qubit]) ^ int(z_destab[i, control_qubit]) ^ 1))
661
+ (int(x_destab[i, control_qubit]) * int(z_destab[i, target_qubit]))
662
+ * (int(x_destab[i, target_qubit]) ^ int(z_destab[i, control_qubit]) ^ 1)
663
+ )
589
664
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
590
- (int(x_stab[i, control_qubit]) * int(z_stab[i, target_qubit]))
591
- * (int(x_stab[i, target_qubit]) ^ int(z_stab[i, control_qubit]) ^ 1))
665
+ (int(x_stab[i, control_qubit]) * int(z_stab[i, target_qubit]))
666
+ * (int(x_stab[i, target_qubit]) ^ int(z_stab[i, control_qubit]) ^ 1)
667
+ )
592
668
  x_stab[i, target_qubit] = int(x_stab[i, target_qubit]) ^ int(x_stab[i, control_qubit])
593
669
  x_destab[i, target_qubit] = int(x_destab[i, target_qubit]) ^ int(x_destab[i, control_qubit])
594
670
  z_stab[i, control_qubit] = int(z_stab[i, control_qubit]) ^ int(z_stab[i, target_qubit])
@@ -601,13 +677,13 @@ def initial_tableau(circuit, number_of_qubits):
601
677
 
602
678
 
603
679
  def first_round_hadamard(tableau, phase_stabilizer, phase_destabilizer):
604
- """Hadamard gates makes the X stabilizer matrix of the tableau have full rank """
680
+ """Hadamard gates makes the X stabilizer matrix of the tableau have full rank"""
605
681
  num_qubits = int(len(tableau[0, :]) / 2)
606
682
  circ = []
607
683
  x_destab = tableau[0:num_qubits, 0:num_qubits]
608
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
609
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
610
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
684
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
685
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
686
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
611
687
  rank = npl.matrix_rank(x_stab)
612
688
 
613
689
  if is_canonical(tableau, phase_stabilizer, phase_destabilizer):
@@ -633,11 +709,15 @@ def first_round_hadamard(tableau, phase_stabilizer, phase_destabilizer):
633
709
  circ.append(tq.gates.H(target=target_qubit))
634
710
  for i in range(0, num_qubits):
635
711
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
636
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
712
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
713
+ )
637
714
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
638
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
639
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
640
- i, target_qubit]
715
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
716
+ )
717
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
718
+ z_destab[i, target_qubit],
719
+ x_destab[i, target_qubit],
720
+ )
641
721
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
642
722
  destabilizer = np.concatenate((x_destab, z_destab), axis=1)
643
723
  stabilizer = np.concatenate((x_stab, z_stab), axis=1)
@@ -654,9 +734,9 @@ def first_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
654
734
  """CNOT gates make the X stabilizer matrix the identity matrix"""
655
735
  num_qubits = int(len(tableau[0, :]) / 2)
656
736
  x_destab = tableau[0:num_qubits, 0:num_qubits]
657
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
658
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
659
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
737
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
738
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
739
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
660
740
  circ = []
661
741
 
662
742
  if is_canonical(tableau, phase_stabilizer, phase_destabilizer):
@@ -676,16 +756,19 @@ def first_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
676
756
  circ.append(tq.gates.CNOT(control_qubit, target_qubit))
677
757
  for k in range(0, num_qubits):
678
758
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
679
- (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit])) \
680
- * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1))
759
+ (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit]))
760
+ * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1)
761
+ )
681
762
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
682
- (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit])) \
683
- * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1))
763
+ (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit]))
764
+ * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1)
765
+ )
684
766
  x_stab[k, target_qubit] = int(x_stab[k, target_qubit]) ^ int(x_stab[k, control_qubit])
685
767
  x_destab[k, target_qubit] = int(x_destab[k, target_qubit]) ^ int(x_destab[k, control_qubit])
686
768
  z_stab[k, control_qubit] = int(z_stab[k, control_qubit]) ^ int(z_stab[k, target_qubit])
687
769
  z_destab[k, control_qubit] = int(z_destab[k, control_qubit]) ^ int(
688
- z_destab[k, target_qubit])
770
+ z_destab[k, target_qubit]
771
+ )
689
772
 
690
773
  # if one on diagnal guassian elimination on rows below
691
774
  diag_one = 1
@@ -697,17 +780,18 @@ def first_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
697
780
  circ.append(tq.gates.CNOT(control_qubit, target_qubit))
698
781
  for k in range(0, num_qubits):
699
782
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
700
- (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit])) \
701
- * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1))
783
+ (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit]))
784
+ * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1)
785
+ )
702
786
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
703
- (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit])) \
704
- * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1))
787
+ (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit]))
788
+ * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1)
789
+ )
705
790
  x_stab[k, target_qubit] = int(x_stab[k, target_qubit]) ^ int(x_stab[k, control_qubit])
706
791
  x_destab[k, target_qubit] = int(x_destab[k, target_qubit]) ^ int(x_destab[k, control_qubit])
707
792
  z_stab[k, control_qubit] = int(z_stab[k, control_qubit]) ^ int(z_stab[k, target_qubit])
708
793
  z_destab[k, control_qubit] = int(z_destab[k, control_qubit]) ^ int(z_destab[k, target_qubit])
709
794
 
710
-
711
795
  # making matrix identity
712
796
  for i in reversed(range(num_qubits)):
713
797
  for j in range(i - 1, -1, -1):
@@ -717,11 +801,13 @@ def first_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
717
801
  circ.append(tq.gates.CNOT(control_qubit, target_qubit))
718
802
  for k in range(num_qubits):
719
803
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
720
- (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit])) \
721
- * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1))
804
+ (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit]))
805
+ * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1)
806
+ )
722
807
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
723
- (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit])) \
724
- * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1))
808
+ (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit]))
809
+ * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1)
810
+ )
725
811
  x_stab[k, target_qubit] = int(x_stab[k, target_qubit]) ^ int(x_stab[k, control_qubit])
726
812
  x_destab[k, target_qubit] = int(x_destab[k, target_qubit]) ^ int(x_destab[k, control_qubit])
727
813
  z_stab[k, control_qubit] = int(z_stab[k, control_qubit]) ^ int(z_stab[k, target_qubit])
@@ -733,15 +819,14 @@ def first_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
733
819
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
734
820
 
735
821
 
736
-
737
822
  def first_round_phase(tableau, phase_stabilizer, phase_destabilizer):
738
823
  """This phase round adds a diagonal matrix D to the Z stabilizer matrix such that Z + D = M*M' for some
739
824
  invertible M"""
740
825
  num_qubits = int(len(tableau[0, :]) / 2)
741
826
  x_destab = tableau[0:num_qubits, 0:num_qubits]
742
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
743
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
744
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
827
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
828
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
829
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
745
830
  matrix = copy.deepcopy(z_stab)
746
831
  M = np.identity(num_qubits)
747
832
  circ = []
@@ -773,9 +858,11 @@ def first_round_phase(tableau, phase_stabilizer, phase_destabilizer):
773
858
  circ.append(tq.gates.S(target=target_qubit))
774
859
  for i in range(0, num_qubits):
775
860
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
776
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
861
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
862
+ )
777
863
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
778
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
864
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
865
+ )
779
866
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
780
867
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
781
868
  destabilizer = np.concatenate((x_destab, z_destab), axis=1)
@@ -784,14 +871,13 @@ def first_round_phase(tableau, phase_stabilizer, phase_destabilizer):
784
871
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
785
872
 
786
873
 
787
-
788
874
  def second_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
789
- """performs a cholesky decompostion of the symmetric Z = D + M*M' stabilizer matrix """
875
+ """performs a cholesky decompostion of the symmetric Z = D + M*M' stabilizer matrix"""
790
876
  num_qubits = int(len(tableau[0, :]) / 2)
791
877
  x_destab = tableau[0:num_qubits, 0:num_qubits]
792
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
793
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
794
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
878
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
879
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
880
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
795
881
  matrix = copy.deepcopy(z_stab)
796
882
  circ = []
797
883
 
@@ -820,11 +906,13 @@ def second_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
820
906
  if control_qubit != target_qubit:
821
907
  for l in range(0, num_qubits):
822
908
  phase_destabilizer[l] = int(phase_destabilizer[l]) ^ (
823
- (int(x_destab[l, control_qubit]) * int(z_destab[l, target_qubit])) \
824
- * (int(x_destab[l, target_qubit]) ^ int(z_destab[l, control_qubit]) ^ 1))
909
+ (int(x_destab[l, control_qubit]) * int(z_destab[l, target_qubit]))
910
+ * (int(x_destab[l, target_qubit]) ^ int(z_destab[l, control_qubit]) ^ 1)
911
+ )
825
912
  phase_stabilizer[l] = int(phase_stabilizer[l]) ^ (
826
- (int(x_stab[l, control_qubit]) * int(z_stab[l, target_qubit])) \
827
- * (int(x_stab[l, target_qubit]) ^ int(z_stab[l, control_qubit]) ^ 1))
913
+ (int(x_stab[l, control_qubit]) * int(z_stab[l, target_qubit]))
914
+ * (int(x_stab[l, target_qubit]) ^ int(z_stab[l, control_qubit]) ^ 1)
915
+ )
828
916
  x_stab[l, target_qubit] = int(x_stab[l, target_qubit]) ^ int(x_stab[l, control_qubit])
829
917
  x_destab[l, target_qubit] = int(x_destab[l, target_qubit]) ^ int(x_destab[l, control_qubit])
830
918
  z_stab[l, control_qubit] = int(z_stab[l, control_qubit]) ^ int(z_stab[l, target_qubit])
@@ -838,15 +926,14 @@ def second_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
838
926
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
839
927
 
840
928
 
841
-
842
929
  def second_round_phase(tableau, phase_stabilizer, phase_destabilizer):
843
930
  """phase on all the qubits eliminates the Z_stabilizer to the Zero Matrix, additional phases set all the stabilizer
844
931
  phase bits to zero"""
845
932
  num_qubits = int(len(tableau[0, :]) / 2)
846
933
  x_destab = tableau[0:num_qubits, 0:num_qubits]
847
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
848
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
849
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
934
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
935
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
936
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
850
937
  bits_to_flip = []
851
938
  circ = []
852
939
 
@@ -859,9 +946,11 @@ def second_round_phase(tableau, phase_stabilizer, phase_destabilizer):
859
946
  circ.append(tq.gates.S(target_qubit))
860
947
  for i in range(num_qubits):
861
948
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
862
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
949
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
950
+ )
863
951
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
864
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
952
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
953
+ )
865
954
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
866
955
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
867
956
  # zeroing out remaining stabilizer phase bits
@@ -876,9 +965,11 @@ def second_round_phase(tableau, phase_stabilizer, phase_destabilizer):
876
965
  circ.append(tq.gates.S(target_qubit))
877
966
  for k in range(num_qubits):
878
967
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
879
- int(x_destab[k, target_qubit]) * int(z_destab[k, target_qubit]))
968
+ int(x_destab[k, target_qubit]) * int(z_destab[k, target_qubit])
969
+ )
880
970
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
881
- int(x_stab[k, target_qubit]) * int(z_stab[k, target_qubit]))
971
+ int(x_stab[k, target_qubit]) * int(z_stab[k, target_qubit])
972
+ )
882
973
  z_stab[k, target_qubit] = int(z_stab[k, target_qubit]) ^ int(x_stab[k, target_qubit])
883
974
  z_destab[k, target_qubit] = int(z_destab[k, target_qubit]) ^ int(x_destab[k, target_qubit])
884
975
  destabilizer = np.concatenate((x_destab, z_destab), axis=1)
@@ -891,9 +982,9 @@ def third_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
891
982
  """CNOT gates make the X stabilizer matrix the identity matrix"""
892
983
  num_qubits = int(len(tableau[0, :]) / 2)
893
984
  x_destab = tableau[0:num_qubits, 0:num_qubits]
894
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
895
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
896
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
985
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
986
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
987
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
897
988
  circ = []
898
989
 
899
990
  if is_canonical(tableau, phase_stabilizer, phase_destabilizer):
@@ -909,11 +1000,13 @@ def third_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
909
1000
  circ.append(tq.gates.CNOT(control_qubit, target_qubit))
910
1001
  for k in range(0, num_qubits):
911
1002
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
912
- (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit])) \
913
- * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1))
1003
+ (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit]))
1004
+ * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1)
1005
+ )
914
1006
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
915
- (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit])) \
916
- * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1))
1007
+ (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit]))
1008
+ * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1)
1009
+ )
917
1010
  x_stab[k, target_qubit] = int(x_stab[k, target_qubit]) ^ int(x_stab[k, control_qubit])
918
1011
  x_destab[k, target_qubit] = int(x_destab[k, target_qubit]) ^ int(x_destab[k, control_qubit])
919
1012
  z_stab[k, control_qubit] = int(z_stab[k, control_qubit]) ^ int(z_stab[k, target_qubit])
@@ -925,14 +1018,13 @@ def third_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
925
1018
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
926
1019
 
927
1020
 
928
-
929
1021
  def second_round_hadamard(tableau, phase_stabilizer, phase_destabilizer):
930
- """"Apply Hadmard on all the bits puts the stabilizer matrix into canonical form"""
1022
+ """ "Apply Hadmard on all the bits puts the stabilizer matrix into canonical form"""
931
1023
  num_qubits = int(len(tableau[0, :]) / 2)
932
1024
  x_destab = tableau[0:num_qubits, 0:num_qubits]
933
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
934
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
935
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
1025
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
1026
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
1027
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
936
1028
  bits_to_flip = []
937
1029
  circ = []
938
1030
 
@@ -945,11 +1037,15 @@ def second_round_hadamard(tableau, phase_stabilizer, phase_destabilizer):
945
1037
  circ.append(tq.gates.H(target=target_qubit))
946
1038
  for i in range(0, num_qubits):
947
1039
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
948
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
1040
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
1041
+ )
949
1042
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
950
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
951
- x_destab[i, target_qubit], z_destab[i, target_qubit] = z_destab[i, target_qubit], x_destab[
952
- i, target_qubit]
1043
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
1044
+ )
1045
+ x_destab[i, target_qubit], z_destab[i, target_qubit] = (
1046
+ z_destab[i, target_qubit],
1047
+ x_destab[i, target_qubit],
1048
+ )
953
1049
  z_stab[i, target_qubit], x_stab[i, target_qubit] = x_stab[i, target_qubit], z_stab[i, target_qubit]
954
1050
  destabilizer = np.concatenate((x_destab, z_destab), axis=1)
955
1051
  stabilizer = np.concatenate((x_stab, z_stab), axis=1)
@@ -957,14 +1053,13 @@ def second_round_hadamard(tableau, phase_stabilizer, phase_destabilizer):
957
1053
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
958
1054
 
959
1055
 
960
-
961
1056
  def third_round_phase(tableau, phase_stabilizer, phase_destabilizer):
962
1057
  """Adds a diagonal matrix to the Z destabilizer matrix such that Zd + D = M*M' for some invertible M"""
963
1058
  num_qubits = int(len(tableau[0, :]) / 2)
964
1059
  x_destab = tableau[0:num_qubits, 0:num_qubits]
965
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
966
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
967
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
1060
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
1061
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
1062
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
968
1063
  matrix = copy.deepcopy(z_destab)
969
1064
  M = np.identity(num_qubits)
970
1065
  circ = []
@@ -995,9 +1090,11 @@ def third_round_phase(tableau, phase_stabilizer, phase_destabilizer):
995
1090
  circ.append(tq.gates.S(target=target_qubit))
996
1091
  for i in range(0, num_qubits):
997
1092
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
998
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
1093
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
1094
+ )
999
1095
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
1000
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
1096
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
1097
+ )
1001
1098
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
1002
1099
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
1003
1100
  destabilizer = np.concatenate((x_destab, z_destab), axis=1)
@@ -1006,14 +1103,13 @@ def third_round_phase(tableau, phase_stabilizer, phase_destabilizer):
1006
1103
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
1007
1104
 
1008
1105
 
1009
-
1010
1106
  def fourth_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1011
- """"Performs a binary cholesky decomposition on the Z destabilizer matrix"""
1107
+ """ "Performs a binary cholesky decomposition on the Z destabilizer matrix"""
1012
1108
  num_qubits = int(len(tableau[0, :]) / 2)
1013
1109
  x_destab = tableau[0:num_qubits, 0:num_qubits]
1014
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
1015
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
1016
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
1110
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
1111
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
1112
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
1017
1113
  matrix = copy.deepcopy(z_destab)
1018
1114
  M = np.identity(num_qubits)
1019
1115
  circ = []
@@ -1041,11 +1137,13 @@ def fourth_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1041
1137
  if control_qubit != target_qubit:
1042
1138
  for l in range(0, num_qubits):
1043
1139
  phase_destabilizer[l] = int(phase_destabilizer[l]) ^ (
1044
- (int(x_destab[l, control_qubit]) * int(z_destab[l, target_qubit])) \
1045
- * (int(x_destab[l, target_qubit]) ^ int(z_destab[l, control_qubit]) ^ 1))
1140
+ (int(x_destab[l, control_qubit]) * int(z_destab[l, target_qubit]))
1141
+ * (int(x_destab[l, target_qubit]) ^ int(z_destab[l, control_qubit]) ^ 1)
1142
+ )
1046
1143
  phase_stabilizer[l] = int(phase_stabilizer[l]) ^ (
1047
- (int(x_stab[l, control_qubit]) * int(z_stab[l, target_qubit])) \
1048
- * (int(x_stab[l, target_qubit]) ^ int(z_stab[l, control_qubit]) ^ 1))
1144
+ (int(x_stab[l, control_qubit]) * int(z_stab[l, target_qubit]))
1145
+ * (int(x_stab[l, target_qubit]) ^ int(z_stab[l, control_qubit]) ^ 1)
1146
+ )
1049
1147
  x_stab[l, target_qubit] = int(x_stab[l, target_qubit]) ^ int(x_stab[l, control_qubit])
1050
1148
  x_destab[l, target_qubit] = int(x_destab[l, target_qubit]) ^ int(x_destab[l, control_qubit])
1051
1149
  z_stab[l, control_qubit] = int(z_stab[l, control_qubit]) ^ int(z_stab[l, target_qubit])
@@ -1059,15 +1157,14 @@ def fourth_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1059
1157
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
1060
1158
 
1061
1159
 
1062
-
1063
1160
  def fourth_round_phase(tableau, phase_stabilizer, phase_destabilizer):
1064
- """"Phase gates make the Z destabilizer the Zero matrix, additional phases set all the destabilizer
1161
+ """ "Phase gates make the Z destabilizer the Zero matrix, additional phases set all the destabilizer
1065
1162
  phase bits to 0"""
1066
1163
  num_qubits = int(len(tableau[0, :]) / 2)
1067
1164
  x_destab = tableau[0:num_qubits, 0:num_qubits]
1068
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
1069
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
1070
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
1165
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
1166
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
1167
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
1071
1168
  bits_to_flip = []
1072
1169
  circ = []
1073
1170
 
@@ -1081,9 +1178,11 @@ def fourth_round_phase(tableau, phase_stabilizer, phase_destabilizer):
1081
1178
  circ.append(tq.gates.S(target_qubit))
1082
1179
  for i in range(num_qubits):
1083
1180
  phase_destabilizer[i] = int(phase_destabilizer[i]) ^ (
1084
- int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit]))
1181
+ int(x_destab[i, target_qubit]) * int(z_destab[i, target_qubit])
1182
+ )
1085
1183
  phase_stabilizer[i] = int(phase_stabilizer[i]) ^ (
1086
- int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit]))
1184
+ int(x_stab[i, target_qubit]) * int(z_stab[i, target_qubit])
1185
+ )
1087
1186
  z_stab[i, target_qubit] = int(z_stab[i, target_qubit]) ^ int(x_stab[i, target_qubit])
1088
1187
  z_destab[i, target_qubit] = int(z_destab[i, target_qubit]) ^ int(x_destab[i, target_qubit])
1089
1188
 
@@ -1098,9 +1197,11 @@ def fourth_round_phase(tableau, phase_stabilizer, phase_destabilizer):
1098
1197
  circ.append(tq.gates.S(target_qubit))
1099
1198
  for k in range(num_qubits):
1100
1199
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
1101
- int(x_destab[k, target_qubit]) * int(z_destab[k, target_qubit]))
1200
+ int(x_destab[k, target_qubit]) * int(z_destab[k, target_qubit])
1201
+ )
1102
1202
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
1103
- int(x_stab[k, target_qubit]) * int(z_stab[k, target_qubit]))
1203
+ int(x_stab[k, target_qubit]) * int(z_stab[k, target_qubit])
1204
+ )
1104
1205
  z_stab[k, target_qubit] = int(z_stab[k, target_qubit]) ^ int(x_stab[k, target_qubit])
1105
1206
  z_destab[k, target_qubit] = int(z_destab[k, target_qubit]) ^ int(x_destab[k, target_qubit])
1106
1207
 
@@ -1110,15 +1211,14 @@ def fourth_round_phase(tableau, phase_stabilizer, phase_destabilizer):
1110
1211
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
1111
1212
 
1112
1213
 
1113
-
1114
1214
  def final_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1115
1215
  """Final round of CNOT gates puts the Tableau into canonical form: a 2n X 2n identity matrix with all phase
1116
1216
  bits zero"""
1117
1217
  num_qubits = int(len(tableau[0, :]) / 2)
1118
1218
  x_destab = tableau[0:num_qubits, 0:num_qubits]
1119
- z_destab = tableau[0:num_qubits, num_qubits:2 * num_qubits]
1120
- z_stab = tableau[num_qubits:2 * num_qubits, num_qubits:2 * num_qubits]
1121
- x_stab = tableau[num_qubits:2 * num_qubits, 0:num_qubits]
1219
+ z_destab = tableau[0:num_qubits, num_qubits : 2 * num_qubits]
1220
+ z_stab = tableau[num_qubits : 2 * num_qubits, num_qubits : 2 * num_qubits]
1221
+ x_stab = tableau[num_qubits : 2 * num_qubits, 0:num_qubits]
1122
1222
  circ = []
1123
1223
 
1124
1224
  if is_canonical(tableau, phase_stabilizer, phase_destabilizer):
@@ -1132,11 +1232,13 @@ def final_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1132
1232
  circ.append(tq.gates.CNOT(control_qubit, target_qubit))
1133
1233
  for k in range(0, num_qubits):
1134
1234
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
1135
- (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit])) \
1136
- * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1))
1235
+ (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit]))
1236
+ * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1)
1237
+ )
1137
1238
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
1138
- (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit])) \
1139
- * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1))
1239
+ (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit]))
1240
+ * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1)
1241
+ )
1140
1242
  x_stab[k, target_qubit] = int(x_stab[k, target_qubit]) ^ int(x_stab[k, control_qubit])
1141
1243
  x_destab[k, target_qubit] = int(x_destab[k, target_qubit]) ^ int(x_destab[k, control_qubit])
1142
1244
  z_stab[k, control_qubit] = int(z_stab[k, control_qubit]) ^ int(z_stab[k, target_qubit])
@@ -1147,17 +1249,18 @@ def final_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1147
1249
  circ.append(tq.gates.CNOT(control_qubit, target_qubit))
1148
1250
  for k in range(0, num_qubits):
1149
1251
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
1150
- (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit])) \
1151
- * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1))
1252
+ (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit]))
1253
+ * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1)
1254
+ )
1152
1255
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
1153
- (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit])) \
1154
- * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1))
1256
+ (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit]))
1257
+ * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1)
1258
+ )
1155
1259
  x_stab[k, target_qubit] = int(x_stab[k, target_qubit]) ^ int(x_stab[k, control_qubit])
1156
1260
  x_destab[k, target_qubit] = int(x_destab[k, target_qubit]) ^ int(x_destab[k, control_qubit])
1157
1261
  z_stab[k, control_qubit] = int(z_stab[k, control_qubit]) ^ int(z_stab[k, target_qubit])
1158
1262
  z_destab[k, control_qubit] = int(z_destab[k, control_qubit]) ^ int(z_destab[k, target_qubit])
1159
1263
 
1160
-
1161
1264
  if x_destab[i, i] == 1:
1162
1265
  ones = np.where(x_destab[i, :] == 1)[0]
1163
1266
  control_qubit = i
@@ -1167,11 +1270,13 @@ def final_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1167
1270
  circ.append(tq.gates.CNOT(control_qubit, target_qubit))
1168
1271
  for k in range(0, num_qubits):
1169
1272
  phase_destabilizer[k] = int(phase_destabilizer[k]) ^ (
1170
- (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit])) \
1171
- * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1))
1273
+ (int(x_destab[k, control_qubit]) * int(z_destab[k, target_qubit]))
1274
+ * (int(x_destab[k, target_qubit]) ^ int(z_destab[k, control_qubit]) ^ 1)
1275
+ )
1172
1276
  phase_stabilizer[k] = int(phase_stabilizer[k]) ^ (
1173
- (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit])) \
1174
- * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1))
1277
+ (int(x_stab[k, control_qubit]) * int(z_stab[k, target_qubit]))
1278
+ * (int(x_stab[k, target_qubit]) ^ int(z_stab[k, control_qubit]) ^ 1)
1279
+ )
1175
1280
  x_stab[k, target_qubit] = int(x_stab[k, target_qubit]) ^ int(x_stab[k, control_qubit])
1176
1281
  x_destab[k, target_qubit] = int(x_destab[k, target_qubit]) ^ int(x_destab[k, control_qubit])
1177
1282
  z_stab[k, control_qubit] = int(z_stab[k, control_qubit]) ^ int(z_stab[k, target_qubit])
@@ -1182,7 +1287,6 @@ def final_round_cnot(tableau, phase_stabilizer, phase_destabilizer):
1182
1287
  return (tableau, phase_stabilizer, phase_destabilizer, circ)
1183
1288
 
1184
1289
 
1185
-
1186
1290
  #
1187
1291
  def REF_binary(matrix):
1188
1292
  A = matrix
@@ -1210,7 +1314,7 @@ def REF_binary(matrix):
1210
1314
  for i in range(current_row, n_rows):
1211
1315
  if A[i, j] == 1:
1212
1316
  A[i] = (A[i] + A[pivot_row]) % 2
1213
- return (A)
1317
+ return A
1214
1318
 
1215
1319
 
1216
1320
  #