Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
noise.py
Go to the documentation of this file.
1 from qiskit import QuantumCircuit, transpile
2 from qiskit_aer import AerSimulator
3 from qiskit_aer.noise import NoiseModel, depolarizing_error, thermal_relaxation_error
4 from qiskit.visualization import plot_histogram
5 import matplotlib.pyplot as plt
6 
7 # Create a 3-qubit quantum circuit
8 qc = QuantumCircuit(3, 3)
9 
10 # Add some quantum gates
11 qc.h(0) # Hadamard on qubit 0
12 qc.cx(0, 1) # CNOT from qubit 0 to qubit 1
13 qc.cx(1, 2) # CNOT from qubit 1 to qubit 2
14 
15 # Add some more gates to make it interesting
16 qc.rx(0.5, 0) # Rotation around X on qubit 0
17 qc.ry(0.3, 1) # Rotation around Y on qubit 1
18 qc.rz(0.7, 2) # Rotation around Z on qubit 2
19 
20 # Measure all qubits
21 qc.measure([0, 1, 2], [0, 1, 2])
22 
23 print("Circuit:")
24 print(qc.draw())
25 
26 # ============ Create a Noise Model ============
27 
28 noise_model = NoiseModel()
29 
30 # 1. Depolarizing error on single-qubit gates
31 # This adds random Pauli errors (X, Y, Z) with some probability
32 single_qubit_error_rate = 0.01 # 1% error rate
33 single_qubit_error = depolarizing_error(single_qubit_error_rate, 1)
34 
35 # 2. Depolarizing error on two-qubit gates (typically higher)
36 two_qubit_error_rate = 0.05 # 5% error rate
37 two_qubit_error = depolarizing_error(two_qubit_error_rate, 2)
38 
39 # 3. Thermal relaxation error (T1/T2 decoherence)
40 # T1: relaxation time, T2: dephasing time, gate_time: how long the gate takes
41 t1 = 50e3 # 50 microseconds
42 t2 = 30e3 # 30 microseconds (must be <= 2*T1)
43 gate_time_1q = 50 # 50 ns for single-qubit gates
44 gate_time_2q = 300 # 300 ns for two-qubit gates
45 
46 thermal_error_1q = thermal_relaxation_error(t1, t2, gate_time_1q)
47 thermal_error_2q = thermal_relaxation_error(t1, t2, gate_time_2q).expand(
48  thermal_relaxation_error(t1, t2, gate_time_2q)
49 )
50 
51 # Add errors to specific gates
52 noise_model.add_all_qubit_quantum_error(
53  single_qubit_error, ['h', 'rx', 'ry', 'rz'])
54 noise_model.add_all_qubit_quantum_error(two_qubit_error, ['cx'])
55 
56 # Optionally add thermal relaxation errors too
57 # noise_model.add_all_qubit_quantum_error(thermal_error_1q, ['h', 'rx', 'ry', 'rz'])
58 # noise_model.add_all_qubit_quantum_error(thermal_error_2q, ['cx'])
59 
60 print("\nNoise Model:")
61 print(noise_model)
62 
63 # ============ Run Simulations ============
64 
65 shots = 4096
66 
67 # Ideal simulation (no noise)
68 ideal_simulator = AerSimulator()
69 transpiled_ideal = transpile(qc, ideal_simulator)
70 ideal_result = ideal_simulator.run(transpiled_ideal, shots=shots).result()
71 ideal_counts = ideal_result.get_counts()
72 
73 # Noisy simulation
74 noisy_simulator = AerSimulator(noise_model=noise_model)
75 transpiled_noisy = transpile(qc, noisy_simulator)
76 noisy_result = noisy_simulator.run(transpiled_noisy, shots=shots).result()
77 noisy_counts = noisy_result.get_counts()
78 
79 # ============ Display Results ============
80 
81 print("\n" + "="*50)
82 print("RESULTS COMPARISON")
83 print("="*50)
84 
85 print("\nIdeal (noiseless) counts:")
86 for state, count in sorted(ideal_counts.items(), key=lambda x: -x[1]):
87  print(f" |{state}>: {count} ({100*count/shots:.2f}%)")
88 
89 print("\nNoisy counts:")
90 for state, count in sorted(noisy_counts.items(), key=lambda x: -x[1]):
91  print(f" |{state}>: {count} ({100*count/shots:.2f}%)")
92 
93 # Plot histograms side by side
94 fig, axes = plt.subplots(1, 2, figsize=(14, 5))
95 
96 # Plot ideal results
97 ax1 = axes[0]
98 states = sorted(ideal_counts.keys())
99 ideal_values = [ideal_counts.get(s, 0) for s in states]
100 ax1.bar(states, ideal_values, color='steelblue')
101 ax1.set_title('Ideal (Noiseless) Simulation', fontsize=14)
102 ax1.set_xlabel('Quantum State', fontsize=12)
103 ax1.set_ylabel('Counts', fontsize=12)
104 ax1.tick_params(axis='x', rotation=45)
105 
106 # Plot noisy results
107 ax2 = axes[1]
108 all_states = sorted(set(ideal_counts.keys()) | set(noisy_counts.keys()))
109 noisy_values = [noisy_counts.get(s, 0) for s in all_states]
110 ax2.bar(all_states, noisy_values, color='coral')
111 ax2.set_title('Noisy Simulation', fontsize=14)
112 ax2.set_xlabel('Quantum State', fontsize=12)
113 ax2.set_ylabel('Counts', fontsize=12)
114 ax2.tick_params(axis='x', rotation=45)
115 
116 plt.tight_layout()
117 plt.savefig('noisy_simulation_results.png', dpi=150)
118 plt.show()
119 
120 print("\nPlot saved to 'noisy_simulation_results.png'")