Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
circuits.py
Go to the documentation of this file.
1 """
2 Shared Test Circuits: SQUANDER vs Qiskit
3 
4 Contains DualBuilder class and circuit factory functions for use in both
5 validation and benchmarking scripts.
6 
7 Test circuits:
8 - 1 qubit: 5 mixed ops, 5 gates (no noise)
9 - 2 qubits: 5/7/10 mixed ops, 5/7/10 gates (no noise)
10 - 3 qubits: 5/10/15/20/25 mixed ops
11 - 4 qubits: 15/20/25 mixed ops
12 - 5 qubits: 30 mixed ops (commented out - slow with Qiskit)
13 """
14 
15 import numpy as np
16 from qiskit import QuantumCircuit
17 from qiskit_aer import AerSimulator
18 from qiskit_aer.noise import (
19  amplitude_damping_error,
20  depolarizing_error,
21  phase_damping_error,
22 )
23 
24 from squander.density_matrix import DensityMatrix, NoisyCircuit
25 
26 
28  """Build identical circuits in both SQUANDER and Qiskit frameworks."""
29 
30  def __init__(self, n_qubits):
31  self.n = n_qubits
32  self.sq = NoisyCircuit(n_qubits)
33  self.qk = QuantumCircuit(n_qubits)
34  self.ops = []
35  self.params = []
36 
37  # === Single-qubit gates ===
38  def H(self, t):
39  self.sq.add_H(t)
40  self.qk.h(t)
41  self.ops.append(f"H({t})")
42 
43  def X(self, t):
44  self.sq.add_X(t)
45  self.qk.x(t)
46  self.ops.append(f"X({t})")
47 
48  def Y(self, t):
49  self.sq.add_Y(t)
50  self.qk.y(t)
51  self.ops.append(f"Y({t})")
52 
53  def Z(self, t):
54  self.sq.add_Z(t)
55  self.qk.z(t)
56  self.ops.append(f"Z({t})")
57 
58  def S(self, t):
59  self.sq.add_S(t)
60  self.qk.s(t)
61  self.ops.append(f"S({t})")
62 
63  def T(self, t):
64  self.sq.add_T(t)
65  self.qk.t(t)
66  self.ops.append(f"T({t})")
67 
68  def Sdg(self, t):
69  self.sq.add_Sdg(t)
70  self.qk.sdg(t)
71  self.ops.append(f"Sdg({t})")
72 
73  def Tdg(self, t):
74  self.sq.add_Tdg(t)
75  self.qk.tdg(t)
76  self.ops.append(f"Tdg({t})")
77 
78  def SX(self, t):
79  self.sq.add_SX(t)
80  self.qk.sx(t)
81  self.ops.append(f"SX({t})")
82 
83  def U3(self, t, theta, phi, lam):
84  self.sq.add_U3(t)
85  qiskit_theta = np.fmod(2.0 * theta, 4.0 * np.pi)
86  qiskit_phi = np.fmod(phi, 2.0 * np.pi)
87  qiskit_lambda = np.fmod(lam, 2.0 * np.pi)
88  self.qk.u(qiskit_theta, qiskit_phi, qiskit_lambda, t)
89  self.params.extend([theta, phi, lam])
90  self.ops.append(f"U3({t},{theta},{phi},{lam})")
91 
92  # === Two-qubit gates ===
93  def CNOT(self, tgt, ctrl):
94  self.sq.add_CNOT(tgt, ctrl)
95  self.qk.cx(ctrl, tgt)
96  self.ops.append(f"CNOT({ctrl}->{tgt})")
97 
98  def CZ(self, tgt, ctrl):
99  self.sq.add_CZ(tgt, ctrl)
100  self.qk.cz(ctrl, tgt)
101  self.ops.append(f"CZ({ctrl},{tgt})")
102 
103  # === Noise channels ===
104  def depolarizing(self, p):
105  self.sq.add_depolarizing(self.n, error_rate=p)
106  self.qk.append(depolarizing_error(p, self.n), list(range(self.n)))
107  self.ops.append(f"Depol({p})")
108 
109  def local_depolarizing(self, t, p):
110  self.sq.add_local_depolarizing(t, error_rate=p)
111  self.qk.append(depolarizing_error(p, 1), [t])
112  self.ops.append(f"LocalDepol({t},{p})")
113 
114  def amp_damp(self, t, gamma):
115  self.sq.add_amplitude_damping(t, gamma=gamma)
116  self.qk.append(amplitude_damping_error(gamma), [t])
117  self.ops.append(f"AD({t},{gamma})")
118 
119  def phase_damp(self, t, lam):
120  self.sq.add_phase_damping(t, lambda_param=lam)
121  self.qk.append(phase_damping_error(lam), [t])
122  self.ops.append(f"PD({t},{lam})")
123 
124  # === Execution methods ===
125  def run(self):
126  """Execute both and return density matrices as numpy arrays."""
127  sq_rho = self.run_squander()
128  qk_rho = self.run_qiskit()
129 
130  # Alternative way to run Qiskit only:
131  # from qiskit.quantum_info import DensityMatrix as QiskitDensityMatrix
132  # qk_rho = QiskitDensityMatrix.from_label(
133  # '0' * self.n).evolve(self.qk).data
134  return sq_rho.to_numpy(), qk_rho
135 
136  def run_squander(self):
137  """Execute SQUANDER only."""
138  sq_rho = DensityMatrix(self.n)
139  self.sq.apply_to(np.asarray(self.params, dtype=np.float64), sq_rho)
140  return sq_rho
141 
142  def run_qiskit(self):
143  """Execute Qiskit only using optimal Aer density matrix simulation.
144 
145  Uses AerSimulator with method='density_matrix' which:
146  - Directly simulates the density matrix evolution
147  - Natively handles QuantumError noise channels (depolarizing, amplitude/phase damping)
148  - Is more efficient than qiskit.quantum_info.DensityMatrix.evolve() for noisy circuits
149  """
150  # Create circuit copy with density matrix save instruction
151  qc = self.qk.copy()
152  qc.save_density_matrix()
153 
154  # Use AerSimulator with density_matrix method - optimal for noisy circuits
155  # This backend directly evolves the density matrix through all operations
156  # including noise channels, without needing to sample or use Kraus operators
157  simulator = AerSimulator(method="density_matrix")
158 
159  # Run with shots=1 since density matrix simulation is deterministic
160  result = simulator.run(qc, shots=1).result()
161 
162  return result.data()["density_matrix"]
163 
165  """Return the numeric parameter vector used for parametric operations."""
166  return np.asarray(self.params, dtype=np.float64)
167 
168 
169 # ===================================================================
170 # 1-QUBIT CIRCUITS
171 # ===================================================================
172 
173 
175  """1 qubit, 5 mixed operations."""
176  b = DualBuilder(1)
177  b.H(0)
178  b.depolarizing(0.05)
179  b.X(0)
180  b.amp_damp(0, 0.03)
181  b.S(0)
182  return b
183 
184 
186  """1 qubit, 5 gate operations (no noise)."""
187  b = DualBuilder(1)
188  b.H(0)
189  b.X(0)
190  b.S(0)
191  b.T(0)
192  b.H(0)
193  return b
194 
195 
196 # ===================================================================
197 # 2-QUBIT CIRCUITS - MIXED
198 # ===================================================================
199 
200 
202  """2 qubits, 5 mixed operations."""
203  b = DualBuilder(2)
204  b.H(0)
205  b.CNOT(1, 0)
206  b.depolarizing(0.04)
207  b.S(1)
208  b.amp_damp(0, 0.02)
209  return b
210 
211 
213  """2 qubits, 7 mixed operations."""
214  b = DualBuilder(2)
215  b.H(0)
216  b.H(1)
217  b.CNOT(1, 0)
218  b.depolarizing(0.05)
219  b.X(0)
220  b.phase_damp(1, 0.03)
221  b.CZ(0, 1)
222  return b
223 
224 
226  """2 qubits, 10 mixed operations."""
227  b = DualBuilder(2)
228  b.H(0)
229  b.H(1)
230  b.CNOT(1, 0)
231  b.depolarizing(0.03)
232  b.S(0)
233  b.T(1)
234  b.amp_damp(0, 0.02)
235  b.CNOT(0, 1)
236  b.phase_damp(1, 0.025)
237  b.H(0)
238  return b
239 
240 
241 # ===================================================================
242 # 2-QUBIT CIRCUITS - GATES ONLY (NO NOISE)
243 # ===================================================================
244 
245 
247  """2 qubits, 5 gate operations (no noise)."""
248  b = DualBuilder(2)
249  b.H(0)
250  b.CNOT(1, 0)
251  b.S(1)
252  b.T(0)
253  b.H(1)
254  return b
255 
256 
258  """2 qubits, 7 gate operations (no noise)."""
259  b = DualBuilder(2)
260  b.H(0)
261  b.H(1)
262  b.CNOT(1, 0)
263  b.S(0)
264  b.T(1)
265  b.CNOT(0, 1)
266  b.H(0)
267  return b
268 
269 
271  """2 qubits, 10 gate operations (no noise)."""
272  b = DualBuilder(2)
273  b.H(0)
274  b.H(1)
275  b.CNOT(1, 0)
276  b.S(0)
277  b.T(1)
278  b.X(0)
279  b.Z(1)
280  b.CNOT(0, 1)
281  b.Sdg(0)
282  b.H(1)
283  return b
284 
285 
286 # ===================================================================
287 # 3-QUBIT CIRCUITS - MIXED
288 # ===================================================================
289 
290 
292  """3 qubits, 5 mixed operations."""
293  b = DualBuilder(3)
294  b.H(0)
295  b.CNOT(1, 0)
296  b.depolarizing(0.04)
297  b.S(2)
298  b.amp_damp(0, 0.02)
299  return b
300 
301 
303  """3 qubits, 10 mixed operations."""
304  b = DualBuilder(3)
305  b.H(0)
306  b.H(1)
307  b.CNOT(1, 0)
308  b.depolarizing(0.05)
309  b.S(2)
310  b.CNOT(2, 1)
311  b.amp_damp(0, 0.03)
312  b.T(1)
313  b.phase_damp(2, 0.02)
314  b.H(2)
315  return b
316 
317 
319  """3 qubits, 15 mixed operations."""
320  b = DualBuilder(3)
321  b.H(0)
322  b.H(1)
323  b.H(2)
324  b.CNOT(1, 0)
325  b.depolarizing(0.04)
326  b.CNOT(2, 1)
327  b.amp_damp(0, 0.025)
328  b.S(0)
329  b.T(1)
330  b.phase_damp(2, 0.02)
331  b.CNOT(0, 2)
332  b.depolarizing(0.03)
333  b.X(1)
334  b.amp_damp(2, 0.02)
335  b.H(0)
336  return b
337 
338 
340  """3 qubits, 20 mixed operations."""
341  b = DualBuilder(3)
342  b.H(0)
343  b.H(1)
344  b.H(2)
345  b.CNOT(1, 0)
346  b.CNOT(2, 1)
347  b.depolarizing(0.04)
348  b.S(0)
349  b.T(1)
350  b.Sdg(2)
351  b.amp_damp(0, 0.02)
352  b.CNOT(0, 2)
353  b.phase_damp(1, 0.025)
354  b.X(0)
355  b.Y(1)
356  b.Z(2)
357  b.depolarizing(0.03)
358  b.CNOT(2, 0)
359  b.amp_damp(1, 0.015)
360  b.H(2)
361  b.phase_damp(0, 0.02)
362  return b
363 
364 
366  """3 qubits, 25 mixed operations."""
367  b = DualBuilder(3)
368  b.H(0)
369  b.H(1)
370  b.H(2)
371  b.CNOT(1, 0)
372  b.CNOT(2, 1)
373  b.depolarizing(0.035)
374  b.S(0)
375  b.T(1)
376  b.SX(2)
377  b.amp_damp(0, 0.02)
378  b.CNOT(0, 2)
379  b.phase_damp(1, 0.02)
380  b.X(0)
381  b.Y(1)
382  b.Z(2)
383  b.depolarizing(0.025)
384  b.CNOT(2, 0)
385  b.amp_damp(1, 0.015)
386  b.Tdg(0)
387  b.Sdg(1)
388  b.phase_damp(2, 0.018)
389  b.CNOT(1, 2)
390  b.depolarizing(0.02)
391  b.H(0)
392  b.H(1)
393  return b
394 
395 
396 # ===================================================================
397 # 4-QUBIT CIRCUITS - MIXED
398 # ===================================================================
399 
400 
402  """4 qubits, 15 mixed operations."""
403  b = DualBuilder(4)
404  b.H(0)
405  b.H(1)
406  b.H(2)
407  b.H(3)
408  b.CNOT(1, 0)
409  b.CNOT(3, 2)
410  b.depolarizing(0.03)
411  b.S(0)
412  b.T(1)
413  b.amp_damp(2, 0.02)
414  b.CNOT(2, 1)
415  b.phase_damp(3, 0.025)
416  b.X(0)
417  b.depolarizing(0.02)
418  b.H(3)
419  return b
420 
421 
423  """4 qubits, 20 mixed operations."""
424  b = DualBuilder(4)
425  b.H(0)
426  b.H(1)
427  b.H(2)
428  b.H(3)
429  b.CNOT(1, 0)
430  b.CNOT(3, 2)
431  b.depolarizing(0.03)
432  b.S(0)
433  b.T(1)
434  b.Sdg(2)
435  b.amp_damp(3, 0.02)
436  b.CNOT(2, 1)
437  b.CNOT(0, 3)
438  b.phase_damp(1, 0.02)
439  b.X(0)
440  b.Y(2)
441  b.depolarizing(0.025)
442  b.amp_damp(0, 0.015)
443  b.H(3)
444  b.phase_damp(2, 0.018)
445  return b
446 
447 
449  """4 qubits, 25 mixed operations."""
450  b = DualBuilder(4)
451  b.H(0)
452  b.H(1)
453  b.H(2)
454  b.H(3)
455  b.CNOT(1, 0)
456  b.CNOT(3, 2)
457  b.depolarizing(0.025)
458  b.S(0)
459  b.T(1)
460  b.SX(2)
461  b.Tdg(3)
462  b.amp_damp(0, 0.02)
463  b.CNOT(2, 1)
464  b.CNOT(0, 3)
465  b.phase_damp(1, 0.018)
466  b.X(0)
467  b.Y(2)
468  b.Z(3)
469  b.depolarizing(0.02)
470  b.CNOT(3, 0)
471  b.amp_damp(2, 0.015)
472  b.phase_damp(3, 0.015)
473  b.Sdg(1)
474  b.H(0)
475  b.H(2)
476  return b
477 
478 
479 # ===================================================================
480 # 5-QUBIT CIRCUITS - MIXED
481 # ===================================================================
482 
483 
485  """5 qubits, 30 mixed operations."""
486  b = DualBuilder(5)
487  # Layer 1: Initial superposition (5 ops)
488  b.H(0)
489  b.H(1)
490  b.H(2)
491  b.H(3)
492  b.H(4)
493  # Layer 2: Entanglement + noise (5 ops)
494  b.CNOT(1, 0)
495  b.CNOT(2, 1)
496  b.CNOT(3, 2)
497  b.CNOT(4, 3)
498  b.depolarizing(0.02)
499  # Layer 3: Single-qubit + noise (5 ops)
500  b.S(0)
501  b.T(1)
502  b.amp_damp(2, 0.025)
503  b.X(3)
504  b.Z(4)
505  # Layer 4: Cross-entanglement + noise (5 ops)
506  b.CNOT(0, 2)
507  b.CNOT(1, 3)
508  b.phase_damp(4, 0.02)
509  b.CNOT(2, 4)
510  b.depolarizing(0.015)
511  # Layer 5: More gates + noise (5 ops)
512  b.H(0)
513  b.H(2)
514  b.amp_damp(1, 0.018)
515  b.Sdg(3)
516  b.Tdg(4)
517  # Layer 6: Final layer + noise (5 ops)
518  b.CNOT(3, 1)
519  b.CNOT(4, 0)
520  b.phase_damp(2, 0.015)
521  b.H(4)
522  b.depolarizing(0.01)
523  return b
524 
525 
526 # ===================================================================
527 # Circuit registry for easy access
528 # ===================================================================
529 
530 # All circuits for validation (name, builder_func)
531 ALL_CIRCUITS = [
532  ("1q/5ops mixed", build_1q_5ops_mixed),
533  ("1q/5ops gates", build_1q_5ops_gates),
534  ("2q/5ops mixed", build_2q_5ops_mixed),
535  ("2q/7ops mixed", build_2q_7ops_mixed),
536  ("2q/10ops mixed", build_2q_10ops_mixed),
537  ("2q/5ops gates", build_2q_5ops_gates),
538  ("2q/7ops gates", build_2q_7ops_gates),
539  ("2q/10ops gates", build_2q_10ops_gates),
540  ("3q/5ops mixed", build_3q_5ops_mixed),
541  ("3q/10ops mixed", build_3q_10ops_mixed),
542  ("3q/15ops mixed", build_3q_15ops_mixed),
543  ("3q/20ops mixed", build_3q_20ops_mixed),
544  ("3q/25ops mixed", build_3q_25ops_mixed),
545  ("4q/15ops mixed", build_4q_15ops_mixed),
546  ("4q/20ops mixed", build_4q_20ops_mixed),
547  ("4q/25ops mixed", build_4q_25ops_mixed),
548  (
549  "5q/30ops mixed",
550  build_5q_30ops_mixed,
551  ), # Slow with Qiskit but works with AerSimulator
552 ]
553 
554 # Subset for benchmarking (representative circuits)
555 BENCHMARK_CIRCUITS = [
556  ("1q/5ops mixed", build_1q_5ops_mixed),
557  ("1q/5ops gates", build_1q_5ops_gates),
558  ("2q/5ops mixed", build_2q_5ops_mixed),
559  ("2q/10ops mixed", build_2q_10ops_mixed),
560  ("3q/10ops mixed", build_3q_10ops_mixed),
561  ("3q/25ops mixed", build_3q_25ops_mixed),
562  ("4q/15ops mixed", build_4q_15ops_mixed),
563  ("4q/25ops mixed", build_4q_25ops_mixed),
564  (
565  "5q/30ops mixed",
566  build_5q_30ops_mixed,
567  ), # Slow with Qiskit but works with AerSimulator
568 ]
569 
570 # Grouped by qubit count for organized output
571 CIRCUITS_BY_QUBITS = {
572  1: [
573  ("1q/5ops mixed", build_1q_5ops_mixed),
574  ("1q/5ops gates", build_1q_5ops_gates),
575  ],
576  2: [
577  ("2q/5ops mixed", build_2q_5ops_mixed),
578  ("2q/7ops mixed", build_2q_7ops_mixed),
579  ("2q/10ops mixed", build_2q_10ops_mixed),
580  ("2q/5ops gates", build_2q_5ops_gates),
581  ("2q/7ops gates", build_2q_7ops_gates),
582  ("2q/10ops gates", build_2q_10ops_gates),
583  ],
584  3: [
585  ("3q/5ops mixed", build_3q_5ops_mixed),
586  ("3q/10ops mixed", build_3q_10ops_mixed),
587  ("3q/15ops mixed", build_3q_15ops_mixed),
588  ("3q/20ops mixed", build_3q_20ops_mixed),
589  ("3q/25ops mixed", build_3q_25ops_mixed),
590  ],
591  4: [
592  ("4q/15ops mixed", build_4q_15ops_mixed),
593  ("4q/20ops mixed", build_4q_20ops_mixed),
594  ("4q/25ops mixed", build_4q_25ops_mixed),
595  ],
596  5: [ # Slow with Qiskit but works with AerSimulator
597  ("5q/30ops mixed", build_5q_30ops_mixed),
598  ],
599 }
600 
601 
602 PAULI_MATRICES = {
603  "I": np.eye(2, dtype=complex),
604  "X": np.array([[0, 1], [1, 0]], dtype=complex),
605  "Y": np.array([[0, -1j], [1j, 0]], dtype=complex),
606  "Z": np.array([[1, 0], [0, -1]], dtype=complex),
607 }
608 
609 
610 def _pauli_string_matrix(pauli_string):
611  matrix = np.array([[1.0 + 0.0j]])
612  for symbol in pauli_string:
613  matrix = np.kron(matrix, PAULI_MATRICES[symbol])
614  return matrix
615 
616 
618  qbit_num = len(term_specs[0][1])
619  matrix = np.zeros((2**qbit_num, 2**qbit_num), dtype=complex)
620  for coeff, pauli_string in term_specs:
621  matrix += coeff * _pauli_string_matrix(pauli_string)
622  return matrix
623 
624 
626  return {
627  "terms": [
628  {"coeff": float(coeff), "pauli_string": pauli_string}
629  for coeff, pauli_string in term_specs
630  ]
631  }
632 
633 
634 def _make_microcase(
635  *,
636  case_name,
637  qbit_num,
638  builder_fn,
639  required_gate_family,
640  required_noise_models,
641  case_kind,
642  purpose,
643  term_specs,
644 ):
645  return {
646  "case_name": case_name,
647  "qbit_num": qbit_num,
648  "builder_fn": builder_fn,
649  "required_gate_family": list(required_gate_family),
650  "required_noise_models": list(required_noise_models),
651  "case_kind": case_kind,
652  "purpose": purpose,
653  "hamiltonian_matrix": _build_microcase_hamiltonian(term_specs),
654  "hamiltonian_metadata": _build_microcase_hamiltonian_metadata(term_specs),
655  }
656 
657 
659  b = DualBuilder(1)
660  b.U3(0, 0.73, -0.41, 0.19)
661  b.local_depolarizing(0, 0.08)
662  return b
663 
664 
666  b = DualBuilder(1)
667  b.U3(0, 1.11, 0.37, -0.52)
668  b.amp_damp(0, 0.14)
669  return b
670 
671 
673  b = DualBuilder(1)
674  b.U3(0, 0.92, -0.63, 0.28)
675  b.phase_damp(0, 0.12)
676  return b
677 
678 
680  b = DualBuilder(2)
681  b.U3(0, 0.61, -0.22, 0.47)
682  b.U3(1, 0.35, 0.18, -0.41)
683  b.CNOT(1, 0)
684  b.local_depolarizing(0, 0.07)
685  return b
686 
687 
689  b = DualBuilder(2)
690  b.U3(0, 0.84, 0.12, -0.33)
691  b.U3(1, 0.56, -0.48, 0.25)
692  b.CNOT(0, 1)
693  b.amp_damp(1, 0.10)
694  return b
695 
696 
698  b = DualBuilder(2)
699  b.U3(0, 0.49, -0.31, 0.67)
700  b.U3(1, 0.71, 0.42, -0.28)
701  b.CNOT(1, 0)
702  b.phase_damp(0, 0.09)
703  return b
704 
705 
707  b = DualBuilder(3)
708  b.U3(0, 0.58, -0.27, 0.44)
709  b.U3(1, 0.93, 0.21, -0.36)
710  b.CNOT(1, 0)
711  b.local_depolarizing(0, 0.05)
712  b.U3(2, 0.67, -0.39, 0.16)
713  b.CNOT(2, 1)
714  b.amp_damp(1, 0.08)
715  b.phase_damp(2, 0.06)
716  return b
717 
718 
719 MANDATORY_MICROCASES = [
721  case_name="micro_validation_1q_u3_local_depolarizing",
722  qbit_num=1,
723  builder_fn=build_1q_u3_local_depolarizing_microcase,
724  required_gate_family=["U3"],
725  required_noise_models=["local_depolarizing"],
726  case_kind="individual_noise",
727  purpose="Validate U3 plus local single-qubit depolarizing on the 1-qubit microcase floor.",
728  term_specs=[(0.60, "Z"), (-0.35, "X")],
729  ),
731  case_name="micro_validation_1q_u3_amplitude_damping",
732  qbit_num=1,
733  builder_fn=build_1q_u3_amplitude_damping_microcase,
734  required_gate_family=["U3"],
735  required_noise_models=["amplitude_damping"],
736  case_kind="individual_noise",
737  purpose="Validate U3 plus local amplitude damping on the 1-qubit microcase floor.",
738  term_specs=[(0.45, "Z"), (0.30, "X")],
739  ),
741  case_name="micro_validation_1q_u3_phase_damping",
742  qbit_num=1,
743  builder_fn=build_1q_u3_phase_damping_microcase,
744  required_gate_family=["U3"],
745  required_noise_models=["phase_damping"],
746  case_kind="individual_noise",
747  purpose="Validate U3 plus local phase damping on the 1-qubit microcase floor.",
748  term_specs=[(-0.40, "Z"), (0.25, "Y")],
749  ),
751  case_name="micro_validation_2q_u3_cnot_local_depolarizing",
752  qbit_num=2,
753  builder_fn=build_2q_u3_cnot_local_depolarizing_microcase,
754  required_gate_family=["U3", "CNOT"],
755  required_noise_models=["local_depolarizing"],
756  case_kind="individual_noise",
757  purpose="Validate the required U3/CNOT bridge with local single-qubit depolarizing.",
758  term_specs=[(0.55, "ZI"), (-0.20, "IZ"), (0.18, "XX")],
759  ),
761  case_name="micro_validation_2q_u3_cnot_amplitude_damping",
762  qbit_num=2,
763  builder_fn=build_2q_u3_cnot_amplitude_damping_microcase,
764  required_gate_family=["U3", "CNOT"],
765  required_noise_models=["amplitude_damping"],
766  case_kind="individual_noise",
767  purpose="Validate the required U3/CNOT bridge with local amplitude damping.",
768  term_specs=[(0.35, "ZI"), (0.22, "IX"), (-0.16, "YY")],
769  ),
771  case_name="micro_validation_2q_u3_cnot_phase_damping",
772  qbit_num=2,
773  builder_fn=build_2q_u3_cnot_phase_damping_microcase,
774  required_gate_family=["U3", "CNOT"],
775  required_noise_models=["phase_damping"],
776  case_kind="individual_noise",
777  purpose="Validate the required U3/CNOT bridge with local phase damping.",
778  term_specs=[(-0.48, "ZZ"), (0.17, "XI"), (0.14, "IY")],
779  ),
781  case_name="micro_validation_3q_u3_cnot_mixed_local_noise",
782  qbit_num=3,
783  builder_fn=build_3q_u3_cnot_mixed_local_noise_microcase,
784  required_gate_family=["U3", "CNOT"],
785  required_noise_models=[
786  "local_depolarizing",
787  "amplitude_damping",
788  "phase_damping",
789  ],
790  case_kind="mixed_sequence",
791  purpose="Validate the mixed-sequence micro-validation path with all required local noise models in one 3-qubit case.",
792  term_specs=[
793  (-0.30, "ZII"),
794  (0.24, "IZI"),
795  (0.16, "IIX"),
796  (0.18, "XXI"),
797  (-0.12, "IYY"),
798  ],
799  ),
800 ]
801 
802 
803 MANDATORY_MICROCASES_BY_QUBITS = {
804  qbit_num: [
805  case for case in MANDATORY_MICROCASES if case["qbit_num"] == qbit_num
806  ]
807  for qbit_num in sorted({case["qbit_num"] for case in MANDATORY_MICROCASES})
808 }
def build_2q_7ops_gates()
Definition: circuits.py:257
def Sdg(self, t)
Definition: circuits.py:68
def build_1q_u3_amplitude_damping_microcase()
Definition: circuits.py:665
def build_2q_10ops_mixed()
Definition: circuits.py:225
def build_2q_5ops_mixed()
Definition: circuits.py:201
def get_parameter_vector(self)
Definition: circuits.py:164
def build_1q_5ops_gates()
Definition: circuits.py:185
def X(self, t)
Definition: circuits.py:43
def run_qiskit(self)
Definition: circuits.py:142
def Y(self, t)
Definition: circuits.py:48
def build_2q_10ops_gates()
Definition: circuits.py:270
def build_4q_15ops_mixed()
Definition: circuits.py:401
def Z(self, t)
Definition: circuits.py:53
def build_3q_15ops_mixed()
Definition: circuits.py:318
def build_2q_u3_cnot_amplitude_damping_microcase()
Definition: circuits.py:688
def amp_damp(self, t, gamma)
Definition: circuits.py:114
def build_3q_10ops_mixed()
Definition: circuits.py:302
def SX(self, t)
Definition: circuits.py:78
def _pauli_string_matrix(pauli_string)
Definition: circuits.py:610
def __init__(self, n_qubits)
Definition: circuits.py:30
def _make_microcase(case_name, qbit_num, builder_fn, required_gate_family, required_noise_models, case_kind, purpose, term_specs)
Definition: circuits.py:644
def build_4q_20ops_mixed()
Definition: circuits.py:422
def local_depolarizing(self, t, p)
Definition: circuits.py:109
def _build_microcase_hamiltonian_metadata(term_specs)
Definition: circuits.py:625
def T(self, t)
Definition: circuits.py:63
def run_squander(self)
Definition: circuits.py:136
def build_1q_5ops_mixed()
Definition: circuits.py:174
def H(self, t)
Definition: circuits.py:38
def depolarizing(self, p)
Definition: circuits.py:104
def build_5q_30ops_mixed()
Definition: circuits.py:484
def U3(self, t, theta, phi, lam)
Definition: circuits.py:83
def build_2q_u3_cnot_phase_damping_microcase()
Definition: circuits.py:697
def build_2q_5ops_gates()
Definition: circuits.py:246
def phase_damp(self, t, lam)
Definition: circuits.py:119
def CNOT(self, tgt, ctrl)
Definition: circuits.py:93
def build_2q_7ops_mixed()
Definition: circuits.py:212
def build_3q_u3_cnot_mixed_local_noise_microcase()
Definition: circuits.py:706
def build_1q_u3_phase_damping_microcase()
Definition: circuits.py:672
def build_4q_25ops_mixed()
Definition: circuits.py:448
def S(self, t)
Definition: circuits.py:58
def build_2q_u3_cnot_local_depolarizing_microcase()
Definition: circuits.py:679
def _build_microcase_hamiltonian(term_specs)
Definition: circuits.py:617
def build_3q_5ops_mixed()
Definition: circuits.py:291
def build_3q_20ops_mixed()
Definition: circuits.py:339
def CZ(self, tgt, ctrl)
Definition: circuits.py:98
def Tdg(self, t)
Definition: circuits.py:73
def build_3q_25ops_mixed()
Definition: circuits.py:365
def build_1q_u3_local_depolarizing_microcase()
Definition: circuits.py:658