Qubity, superpozice a zapletení: Kvantové základy bez kvantové fyziky
Zdá se, že každý úvod do kvantového počítání začíná kvantovou mechanikou, rovnicemi Schrodinger a dualita vlna-částice. Výsledkem je, že většina vývojářů ztratíte se ve fyzických detailech, než vůbec pochopíte, proč se kvantový počítač od jednoho liší klasický. Tento článek dělá opak: vysvětluje základní pojmy – qubity, superpozice, zapletení a dekoherence – pomocí dostupných matematických analogií a kódu Qiskit můžete běž teď.
Nebudete potřebovat znát kvantovou mechaniku. Budete potřebovat vektory a pravděpodobnosti.
Co se naučíte
- Co je qubit matematicky: vektor ve 2D Hilbertově prostoru
- Blochova koule: vizualizace stavu qubitu
- Superpozice: pravděpodobnost, ne magie
- Zapletení: kvantová korelace bez komunikace
- Dekoherence: proč je kvantové počítání obtížné
- Opatření: rozpad státu a jeho důsledky
- Veškerý kód Qiskit pro vizualizaci každého konceptu
Klasický bit vs Qubit
Klasický bit má právě jednu ze dvou hodnot: 0 nebo 1. Fyzicky je to tranzistor která vede nebo nevede proud. Neexistuje žádná nejednoznačnost: bit je vždy v definovaném stavu.
Qubit je matematicky popsán pomocí a vektor ve 2-hilbertově prostoru rozměry. Obecný stav qubitu je:
|ψ⟩ = α|0⟩ + β|1⟩
dove:
|0⟩ e il vettore [1, 0] (stato base "zero")
|1⟩ e il vettore [0, 1] (stato base "uno")
α e β sono numeri complessi (ampiezze)
con il vincolo: |α|² + |β|² = 1
La probabilita di misurare 0 e |α|²
La probabilita di misurare 1 e |β|²
Toto je kritický bod: α a β nejsou pravděpodobnosti – jsou to amplitudy. Pravděpodobnosti se získají umocněním velikosti amplitud. Toto rozlišení a zásadní, protože amplitudy se mohou vzájemně rušit (přidávat nebo rušit) jako vlny, zatímco klasické pravděpodobnosti nikoli.
# Visualizzare lo stato di un qubit con Qiskit
from qiskit import QuantumCircuit
from qiskit.visualization import plot_bloch_multivector, plot_histogram
from qiskit.quantum_info import Statevector
import numpy as np
# Stato |0⟩ — qubit "a zero"
qc_zero = QuantumCircuit(1)
sv_zero = Statevector.from_instruction(qc_zero)
print(f"Stato |0⟩: {sv_zero}")
# Statevector([1.+0.j, 0.+0.j], dims=(2,))
# probabilita di misurare 0: |1|^2 = 1.0 (100%)
# probabilita di misurare 1: |0|^2 = 0.0 (0%)
# Stato |1⟩ — applico gate X (equivalente al NOT classico)
qc_one = QuantumCircuit(1)
qc_one.x(0)
sv_one = Statevector.from_instruction(qc_one)
print(f"Stato |1⟩: {sv_one}")
# Statevector([0.+0.j, 1.+0.j], dims=(2,))
# Stato in superposizione — applico gate Hadamard
qc_plus = QuantumCircuit(1)
qc_plus.h(0) # Hadamard: |0⟩ -> (|0⟩ + |1⟩)/√2
sv_plus = Statevector.from_instruction(qc_plus)
print(f"Stato |+⟩ (superposizione): {sv_plus}")
# Statevector([0.707+0.j, 0.707+0.j], dims=(2,))
# probabilita 0: 0.707^2 = 0.5 (50%)
# probabilita 1: 0.707^2 = 0.5 (50%)
# Verifica le probabilita
probs = sv_plus.probabilities_dict()
print(f"Probabilita di misura: {probs}")
# {'0': 0.4999..., '1': 0.4999...}
Blochova koule: Vizualizace Qubita
Blochova koule je koule o poloměru 1, kde každý bod na povrchu představuje stav čisté kvantum (jeden qubit). Severní pól je |0⟩, jižní pól je |1⟩. Body na rovníku jsou to ekvipravděpodobné superpozice |0⟩ a |1⟩.
# Visualizzare vari stati sulla Bloch sphere
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_bloch_multivector
def show_state_on_bloch(circuit: QuantumCircuit, label: str) -> None:
sv = Statevector.from_instruction(circuit)
probs = sv.probabilities_dict()
print(f"\nStato: {label}")
print(f"Statevector: {sv.data}")
print(f"P(0)={probs.get('0', 0):.3f}, P(1)={probs.get('1', 0):.3f}")
# Polo Nord: |0⟩
qc_north = QuantumCircuit(1)
show_state_on_bloch(qc_north, "|0⟩ (polo nord)")
# Polo Sud: |1⟩
qc_south = QuantumCircuit(1)
qc_south.x(0)
show_state_on_bloch(qc_south, "|1⟩ (polo sud)")
# Equatore: |+⟩ = (|0⟩ + |1⟩)/√2 — Hadamard da |0⟩
qc_plus = QuantumCircuit(1)
qc_plus.h(0)
show_state_on_bloch(qc_plus, "|+⟩ (equatore, fase reale +)")
# Equatore: |−⟩ = (|0⟩ - |1⟩)/√2 — X poi Hadamard
qc_minus = QuantumCircuit(1)
qc_minus.x(0)
qc_minus.h(0)
show_state_on_bloch(qc_minus, "|−⟩ (equatore, fase reale -)")
# Stato arbitrario: rotazione di pi/4 attorno all'asse Y
qc_ry = QuantumCircuit(1)
qc_ry.ry(np.pi/4, 0) # Rotazione Y di 45 gradi
show_state_on_bloch(qc_ry, "RY(π/4)|0⟩ (stato intermedio)")
# P(0) ≈ 0.854, P(1) ≈ 0.146
Koncepční klíč: Hadamardova brána nedává qubit jakoby do superpozice nejednoznačná fyzická poloha. Otočí vektor stavu od severního pólu k rovníku Blochovy koule. "Superpozice" je jednoduše qubit ukazující jedním směrem odlišné od |0⟩ a |1⟩.
Interference: Skutečná síla kvanta
Samotná superpozice není užitečná – qubit v superpozici, který měříte sám náhodný kousek. Skutečná síla kvantového počítání pochází zrušení: amplitudy se mohou navzájem sčítat (konstruktivní interference) nebo rušit (destruktivní interference), umožňuje zesílit cesty, které vedou ke správné odpovědi, a potlačit ty špatné.
# Interferenza: l'Hadamard applicato due volte
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
# H applicato due volte torna allo stato iniziale (interferenza perfetta)
qc_hh = QuantumCircuit(1)
qc_hh.h(0) # Prima H: |0⟩ -> |+⟩ = (|0⟩+|1⟩)/√2
qc_hh.h(0) # Seconda H: le ampiezze interferiscono
sv = Statevector.from_instruction(qc_hh)
print(f"H|H|0⟩ = {sv.data}")
# [1.+0.j, 0.+0.j] — torna esattamente a |0⟩!
# Perche? La matematica:
# Prima H: [1/√2, 1/√2]
# Seconda H: il gate applica la matrice [[1/√2, 1/√2], [1/√2, -1/√2]]
# Risultato: [1/√2*1/√2 + 1/√2*1/√2, 1/√2*1/√2 - 1/√2*1/√2]
# = [1, 0] = |0⟩
# Il termine per |1⟩ si annulla (interferenza distruttiva)!
# Gli algoritmi quantum sfruttano questa interferenza:
# - Amplificano stati con la risposta giusta (interferenza costruttiva)
# - Sopprimono stati con risposte sbagliate (interferenza distruttiva)
Zapletení: kvantová korelace
Zapletení je druhý základní koncept. Dva zapletené qubity mají korelované stavy: měření jednoho okamžitě nezávisle určí výsledek měření druhého z dálky. Ale – a to je bod, ve kterém se mnoho článků mýlí – to není umožňuje komunikaci rychleji než světlo.
Stav Bell je nejjednodušším příkladem 2-qubitového zapletení:
# Creare e misurare il Bell State
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit_aer import AerSimulator
from qiskit import transpile
# Crea il Bell State |Φ+⟩ = (|00⟩ + |11⟩) / √2
qc_bell = QuantumCircuit(2, 2)
qc_bell.h(0) # Superposizione sul qubit 0
qc_bell.cx(0, 1) # CNOT: se qubit 0 e |1⟩, nega qubit 1
# Lo stato e: (|00⟩ + |11⟩) / √2
# NON e separabile: impossibile scrivere come |a⟩ ⊗ |b⟩
sv = Statevector.from_instruction(qc_bell)
print(f"Bell State: {sv.data}")
# [0.707, 0, 0, 0.707] -> 50% |00⟩, 50% |11⟩
# Misura
qc_bell.measure([0, 1], [0, 1])
simulator = AerSimulator()
compiled = transpile(qc_bell, simulator)
result = simulator.run(compiled, shots=10000).result()
counts = result.get_counts()
print(f"Risultati (10000 shots): {counts}")
# Solo '00' e '11' — MAI '01' o '10'!
# Se qubit 0 e 0, qubit 1 e sempre 0. Se qubit 0 e 1, qubit 1 e sempre 1.
# Questo e l'entanglement: non si manifesta come comunicazione
# ma come CORRELAZIONE perfetta nelle misure.
# "Misuro il qubit 0: ottengo 0. So con certezza che qubit 1 sara 0."
# La correlazione vale anche se i due qubit sono a chilometri di distanza.
# Einstein chiamava questo "spooky action at a distance" — e reale e verificato.
Protože zapletení neumožňuje komunikaci: když změříte svůj qubit, dostanete náhodný výsledek (0 nebo 1 s 50% pravděpodobností každý). Jen když komunikujete tento výsledek druhé osobě prostřednictvím klasického kanálu, rozumí tomu, co má. Kanál klasický — který je omezený rychlostí světla — je vždy nutný k extrakci informace užitečné.
Decoherence: The Enemy of Quantum Computing
Důvod, proč je budování kvantových počítačů tak obtížné, je dekoherence: qubity interagují s prostředím (tepelné fotony, magnetická pole, vibrace) a unikají jejich kvantové vlastnosti, kolabující do klasických stavů. Tento proces se děje v mikrosekundách na aktuálním hardwaru.
# Simulare l'effetto della decoerenza con noise model
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel, depolarizing_error
from qiskit import QuantumCircuit, transpile
# Noise model semplice: errore di depolarizzazione dopo ogni gate
noise_model = NoiseModel()
error_1qubit = depolarizing_error(0.01, 1) # 1% di errore per gate a 1 qubit
error_2qubit = depolarizing_error(0.05, 2) # 5% di errore per gate a 2 qubit
noise_model.add_all_qubit_quantum_error(error_1qubit, ['h', 'x', 'ry'])
noise_model.add_all_qubit_quantum_error(error_2qubit, ['cx'])
# Test: Bell state con e senza noise
def run_bell(shots: int, noisy: bool = False) -> dict:
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
if noisy:
sim = AerSimulator(noise_model=noise_model)
else:
sim = AerSimulator()
compiled = transpile(qc, sim)
result = sim.run(compiled, shots=shots).result()
return result.get_counts()
ideal = run_bell(10000, noisy=False)
noisy = run_bell(10000, noisy=True)
print("Senza noise:")
for state, count in sorted(ideal.items()):
print(f" |{state}⟩: {count/10000*100:.1f}%")
print("\nCon noise (1% per gate, 5% per CNOT):")
for state, count in sorted(noisy.items()):
print(f" |{state}⟩: {count/10000*100:.1f}%")
# Output tipico con noise:
# |00⟩: ~49%, |11⟩: ~49%, |01⟩: ~1%, |10⟩: ~1%
# Gli stati '01' e '10' compaiono a causa del noise — "bit flip errors"
Vývojářská analogie pro klíčové koncepty
- Qubits: proměnná, která může být 0, 1 nebo rozdělení pravděpodobnost přes {0,1} — ale když to "přečtete" (změříte), zhroutí se na 0 nebo 1
- Superpozice: proměnná je ve stavu „dosud neurčeno“. — jako slib před vyřešením(). Měření a řešení ()
- Zapletení: dvě proměnné se zaručenou dokonalou korelací — jako dva objekty, které sdílejí neměnnou referenci, ale neznají hodnotu až do "čtení"
- Rušení: Výpočetní cesty přidat/zrušit jako vlny — umožňuje zesílit správnou odpověď
- Dekoherence: kvantová bitová hniloba — systém ztrácí své vlastnosti kvantová zásahem do prostředí
Měření a kolaps
Měření a operace, které extrahují klasické informace z kvantového stavu – např nenapravitelně ničí stát. A základní omezení kvantového počítání: nemůžete "číst" mezistav výpočtu, aniž byste jej zničili.
# Il collasso della misura: dimostrazione pratica
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
# Crea superposizione
qc = QuantumCircuit(1)
qc.h(0)
sv_before = Statevector.from_instruction(qc)
print(f"Prima della misura: {sv_before.data}")
# [0.707+0j, 0.707+0j] — superposizione
# Misura (simulata 1000 volte)
qc_measure = QuantumCircuit(1, 1)
qc_measure.h(0)
qc_measure.measure(0, 0)
from qiskit_aer import AerSimulator
from qiskit import transpile
sim = AerSimulator()
compiled = transpile(qc_measure, sim)
result = sim.run(compiled, shots=1000).result()
print(f"Dopo 1000 misure: {result.get_counts()}")
# {'0': ~500, '1': ~500}
# Punto critico: ogni singola misura collassa il qubit
# Non puoi misurare |+⟩ e poi continuare a lavorarci
# Devi preparare di nuovo lo stato dall'inizio
# Questo e perche no-cloning theorem: non puoi copiare uno stato sconosciuto
Závěry
Základní koncepty kvantového počítání — qubits, superpozice, zapletení a dekoherence — všechny jsou popsatelné lineární algebrou a pravděpodobností, bez esoterické fyziky. Bloch koule a stavové vektory Qiskit jsou konkrétními nástroji pro vizualizaci a práci s nimi.
Následující článek staví na těchto základech: kvantové brány jako transformace lineární, konstrukce prvního skutečného algoritmu (stav Bell) a provádění na hardwaru IBM.







