2727
2828
2929def demonstrate_classical_bits ():
30- """Demonstrate classical bit behavior and limitations."""
30+ """
31+ Demonstrate classical bit behavior and limitations.
32+
33+ Mathematical Foundation:
34+ ------------------------
35+ A classical bit is the fundamental unit of classical information theory.
36+ It can exist in exactly one of two states at any given time:
37+ - State 0: represents "false" or "off"
38+ - State 1: represents "true" or "on"
39+
40+ Mathematically, a classical bit can be represented as:
41+ - b ∈ {0, 1}
42+
43+ For n classical bits, there are 2^n possible distinct states,
44+ but the system can only be in ONE of these states at a time.
45+ For example, 8 bits (1 byte) can represent 2^8 = 256 different values.
46+
47+ Key Limitations:
48+ ---------------
49+ 1. Binary nature: only two discrete states possible
50+ 2. No superposition: cannot be "partially 0 and partially 1"
51+ 3. Deterministic: reading the bit doesn't change its state
52+ 4. No entanglement: bits are independent of each other
53+
54+ Returns:
55+ list: A classical byte (8 bits) as a demonstration
56+ """
3157 print ("=== CLASSICAL BITS ===" )
3258 print ()
3359
34- # Classical bit can only be 0 or 1
60+ # Classical bit can only be 0 or 1 - this is deterministic
61+ # Unlike quantum bits, there is no probability involved
3562 classical_bit = 0
3663 print (f"Classical bit value: { classical_bit } " )
3764 print ("Possible states: 0 or 1" )
@@ -41,7 +68,9 @@ def demonstrate_classical_bits():
4168 print ("- Independent: multiple bits don't influence each other" )
4269 print ()
4370
44- # Multiple classical bits
71+ # Multiple classical bits store information in binary
72+ # Each bit position represents a power of 2: 2^0, 2^1, 2^2, ..., 2^7
73+ # Total value = Σ(bit_i × 2^i) for i from 0 to 7
4574 classical_byte = [0 , 1 , 1 , 0 , 1 , 0 , 0 , 1 ]
4675 print (f"Classical byte: { classical_byte } " )
4776 print (
@@ -53,64 +82,159 @@ def demonstrate_classical_bits():
5382
5483
5584def demonstrate_quantum_bits ():
56- """Demonstrate quantum bit (qubit) behavior and capabilities."""
85+ """
86+ Demonstrate quantum bit (qubit) behavior and capabilities.
87+
88+ Mathematical Foundation:
89+ ------------------------
90+ A qubit is the fundamental unit of quantum information. Unlike classical bits,
91+ a qubit can exist in a superposition of states |0⟩ and |1⟩.
92+
93+ General qubit state representation:
94+ |ψ⟩ = α|0⟩ + β|1⟩
95+
96+ where:
97+ - |ψ⟩ (psi) is the quantum state vector (using Dirac "ket" notation)
98+ - α (alpha) is the complex probability amplitude for state |0⟩
99+ - β (beta) is the complex probability amplitude for state |1⟩
100+ - α, β ∈ ℂ (complex numbers)
101+
102+ Normalization Constraint:
103+ -------------------------
104+ The total probability must equal 1, so:
105+ |α|² + |β|² = 1
106+
107+ where |α|² is the probability of measuring 0, and |β|² is the probability of measuring 1.
108+
109+ Important Quantum States:
110+ -------------------------
111+ 1. |0⟩ = [1, 0]ᵀ - computational basis state (like classical 0)
112+ 2. |1⟩ = [0, 1]ᵀ - computational basis state (like classical 1)
113+ 3. |+⟩ = (|0⟩ + |1⟩)/√2 - equal superposition (50% chance of 0 or 1)
114+ 4. |-⟩ = (|0⟩ - |1⟩)/√2 - equal superposition with negative phase
115+ 5. |i⟩ = (|0⟩ + i|1⟩)/√2 - superposition with imaginary phase
116+
117+ The factor 1/√2 ensures normalization: (1/√2)² + (1/√2)² = 1/2 + 1/2 = 1
118+
119+ Returns:
120+ dict: Dictionary of quantum circuits demonstrating different qubit states
121+ """
57122 print ("=== QUANTUM BITS (QUBITS) ===" )
58123 print ()
59124
60125 # Create quantum circuits for different qubit states
61126 circuits = {}
62127
63- # |0⟩ state (classical-like)
128+ # |0⟩ state (computational basis state)
129+ # Statevector: [1, 0]ᵀ means 100% probability of measuring 0
130+ # This is equivalent to a classical bit with value 0
64131 qc_0 = QuantumCircuit (1 )
65132 circuits ["|0⟩" ] = qc_0
66133
67- # |1⟩ state (classical-like)
134+ # |1⟩ state (computational basis state)
135+ # The X gate is a quantum NOT gate that flips |0⟩ to |1⟩
136+ # Matrix representation: X = [[0, 1], [1, 0]]
137+ # X|0⟩ = |1⟩, giving statevector [0, 1]ᵀ (100% probability of measuring 1)
68138 qc_1 = QuantumCircuit (1 )
69139 qc_1 .x (0 ) # Apply X gate to flip |0⟩ to |1⟩
70140 circuits ["|1⟩" ] = qc_1
71141
72- # |+⟩ state (superposition)
142+ # |+⟩ state (equal superposition - positive phase)
143+ # The Hadamard gate (H) creates equal superposition from |0⟩
144+ # H|0⟩ = (|0⟩ + |1⟩)/√2
145+ # Matrix: H = (1/√2)[[1, 1], [1, -1]]
146+ # Measurement gives 50% chance of 0 and 50% chance of 1
73147 qc_plus = QuantumCircuit (1 )
74148 qc_plus .h (0 ) # Apply Hadamard gate to create superposition
75149 circuits ["|+⟩ = (|0⟩ + |1⟩)/√2" ] = qc_plus
76150
77- # |-⟩ state (superposition)
151+ # |-⟩ state (equal superposition - negative phase)
152+ # Created by X then H: H(X|0⟩) = H|1⟩ = (|0⟩ - |1⟩)/√2
153+ # The minus sign is a relative phase between |0⟩ and |1⟩
154+ # Measurement still gives 50/50, but phase matters for interference
78155 qc_minus = QuantumCircuit (1 )
79156 qc_minus .x (0 )
80157 qc_minus .h (0 )
81158 circuits ["|-⟩ = (|0⟩ - |1⟩)/√2" ] = qc_minus
82159
83- # |i⟩ state (complex superposition)
160+ # |i⟩ state (complex superposition with imaginary phase)
161+ # The S gate adds a 90° phase rotation
162+ # S = [[1, 0], [0, i]] where i = √(-1)
163+ # S(H|0⟩) = S((|0⟩ + |1⟩)/√2) = (|0⟩ + i|1⟩)/√2
164+ # The 'i' represents a complex phase - a purely quantum property!
84165 qc_i = QuantumCircuit (1 )
85166 qc_i .h (0 )
86- qc_i .s (0 ) # Apply S gate to add phase
167+ qc_i .s (0 ) # Apply S gate to add π/2 phase
87168 circuits ["|i⟩ = (|0⟩ + i|1⟩)/√2" ] = qc_i
88169
89170 return circuits
90171
91172
92173def visualize_qubit_states (circuits , verbose = False ):
93- """Visualize qubit states on the Bloch sphere."""
174+ """
175+ Visualize qubit states on the Bloch sphere.
176+
177+ Mathematical Foundation - The Bloch Sphere:
178+ -------------------------------------------
179+ The Bloch sphere is a geometrical representation of a single qubit state.
180+ Any pure qubit state can be represented as a point on the surface of a unit sphere.
181+
182+ Parametric representation:
183+ |ψ⟩ = cos(θ/2)|0⟩ + e^(iφ) sin(θ/2)|1⟩
184+
185+ where:
186+ - θ (theta) ∈ [0, π] is the polar angle (latitude)
187+ - φ (phi) ∈ [0, 2π) is the azimuthal angle (longitude)
188+
189+ Geometric Interpretation:
190+ -------------------------
191+ - North pole (θ=0): |0⟩ state
192+ - South pole (θ=π): |1⟩ state
193+ - Equator (θ=π/2): Equal superposition states like |+⟩, |-⟩, |i⟩, etc.
194+ - X-axis (θ=π/2, φ=0): |+⟩ = (|0⟩ + |1⟩)/√2
195+ - Y-axis (θ=π/2, φ=π/2): |i⟩ = (|0⟩ + i|1⟩)/√2
196+ - Z-axis: measures computational basis (|0⟩/|1⟩)
197+
198+ Probability Calculation:
199+ ------------------------
200+ For a state |ψ⟩ = α|0⟩ + β|1⟩:
201+ - Probability of measuring |0⟩: P(0) = |α|² = (α × α*)
202+ - Probability of measuring |1⟩: P(1) = |β|² = (β × β*)
203+ where α* denotes the complex conjugate of α
204+
205+ Note: P(0) + P(1) = 1 (normalization)
206+
207+ Args:
208+ circuits (dict): Dictionary of quantum circuits to visualize
209+ verbose (bool): If True, print detailed state information
210+
211+ Returns:
212+ dict: Dictionary of statevectors for each circuit
213+ """
94214 print ("=== QUBIT STATE VISUALIZATION ===" )
95215 print ()
96216
97217 states = {}
98218 bloch_figures = []
99219
100220 for i , (label , circuit ) in enumerate (circuits .items ()):
101- # Get the statevector
221+ # Get the statevector representation of the quantum state
222+ # Statevector is a complex vector [α, β] where |ψ⟩ = α|0⟩ + β|1⟩
102223 state = Statevector .from_instruction (circuit )
103224 states [label ] = state
104225
105226 if verbose :
106227 print (f"State { label } :" )
107228 print (f" Statevector: { state } " )
229+ # Calculate measurement probabilities using Born rule: P = |amplitude|²
230+ # This is computed as amplitude × complex_conjugate(amplitude)
108231 print (
109232 f" Probabilities: |0⟩: { abs (state [0 ])** 2 :.3f} , |1⟩: { abs (state [1 ])** 2 :.3f} "
110233 )
111234 print ()
112235
113236 # Plot individual Bloch sphere (Qiskit 2.x doesn't support ax parameter)
237+ # The Bloch sphere visualization shows where this state lies on the unit sphere
114238 try :
115239 bloch_fig = plot_bloch_multivector (state , title = f"Qubit State: { label } " )
116240 bloch_figures .append (bloch_fig )
@@ -130,7 +254,49 @@ def visualize_qubit_states(circuits, verbose=False):
130254
131255
132256def measure_qubits (circuits , shots = 1000 ):
133- """Demonstrate measurement of different qubit states."""
257+ """
258+ Demonstrate measurement of different qubit states.
259+
260+ Mathematical Foundation - Quantum Measurement (Born Rule):
261+ ----------------------------------------------------------
262+ When we measure a qubit in state |ψ⟩ = α|0⟩ + β|1⟩ in the computational basis:
263+
264+ - Probability of outcome 0: P(0) = |α|²
265+ - Probability of outcome 1: P(1) = |β|²
266+
267+ where |α|² means α × α* (amplitude times its complex conjugate).
268+
269+ Key Properties of Quantum Measurement:
270+ --------------------------------------
271+ 1. Probabilistic: Cannot predict individual outcome, only probabilities
272+ 2. Irreversible: Measurement destroys the superposition (wave function collapse)
273+ 3. Post-measurement state: After measuring outcome k, state becomes |k⟩
274+ 4. Born Rule: Probability is the squared magnitude of the amplitude
275+
276+ Why Multiple Shots?
277+ -------------------
278+ Since measurement is probabilistic, we need many repetitions (shots) to
279+ estimate the true probability distribution. With N shots:
280+ - Expected count for outcome k ≈ N × P(k)
281+ - Statistical error decreases as 1/√N
282+
283+ Example: For |+⟩ = (|0⟩ + |1⟩)/√2:
284+ - |α|² = |(1/√2)|² = 1/2 = 50% chance of measuring 0
285+ - |β|² = |(1/√2)|² = 1/2 = 50% chance of measuring 1
286+ - With 1000 shots, expect ~500 zeros and ~500 ones
287+
288+ Measurement Basis:
289+ ------------------
290+ This function measures in the computational (Z) basis {|0⟩, |1⟩}.
291+ Other bases are possible (X-basis, Y-basis) and give different results!
292+
293+ Args:
294+ circuits (dict): Dictionary of quantum circuits to measure
295+ shots (int): Number of times to repeat each measurement
296+
297+ Returns:
298+ dict: Dictionary of measurement counts for each circuit
299+ """
134300 print ("=== MEASUREMENT RESULTS ===" )
135301 print ()
136302
@@ -145,14 +311,20 @@ def measure_qubits(circuits, shots=1000):
145311
146312 for i , (label , circuit ) in enumerate (circuits .items ()):
147313 # Create measurement circuit with proper classical register
314+ # Classical register stores measurement outcomes (0 or 1)
148315 qc_measure = QuantumCircuit (circuit .num_qubits , circuit .num_qubits )
149316 qc_measure = qc_measure .compose (circuit )
317+ # measure_all() performs computational basis measurement on all qubits
150318 qc_measure .measure_all ()
151319
152320 # Run simulation
321+ # Each "shot" represents one complete experiment: prepare state → measure
322+ # We need multiple shots because quantum measurement is probabilistic
153323 try :
154324 job = simulator .run (transpile (qc_measure , simulator ), shots = shots )
155325 result = job .result ()
326+ # counts is a dictionary: {'0': count_0, '1': count_1}
327+ # The counts should follow the Born rule probabilities
156328 counts = result .get_counts ()
157329 results [label ] = counts
158330
@@ -170,7 +342,7 @@ def measure_qubits(circuits, shots=1000):
170342 results [label ] = {}
171343 continue
172344
173- # Print results
345+ # Print results - compare empirical frequencies to theoretical probabilities
174346 if label in results and results [label ]:
175347 print (f"State { label } measured { shots } times:" )
176348 for outcome , count in results [label ].items ():
0 commit comments