Kuantum Kapıları ve Devreler: NOT ve CNOT'tan Qiskit ile Algoritmalara
Eğer kubit kuantum hesaplamanın bilgi birimi ise, kuantum kapıları bunlar onu dönüştüren işlemlerdir; klasik Boolean operatörlerinin eşdeğeridir. Ancak klasik VE, VEYA ve DEĞİL'den farklı olarak kuantum kapıları her zaman geri dönüşümlü ve deterministik ikili değerlerle değil, durum vektörü genlikleri üzerinde çalışırlar.
Bu makalede ana kapıların (Hadamard, X, Z, CNOT) anlaşılmasını sağlıyoruz. SWAP - ve bunları ilk gerçek kuantum algoritmasını oluşturmak için kullanıyoruz: Bell durumu. dolaşıklığı gösterir. Daha sonra devreyi IBM Quantum aracılığıyla gerçek IBM donanımı üzerinde çalıştırıyoruz. Platform.
Ne Öğreneceksiniz
- 1 kübit kapılar: Hadamard (H), X (NOT), Z, S, T ve matrisleri
- 2 kübitlik kapılar: CNOT, CZ, SWAP ve Toffoli
- Qiskit QuantumCircuit ile devreler oluşturun
- Çan Durumu: Dolanıklığı gösteren temel devre
- Qiskit Aer ile simülasyon ve sonuçların görselleştirilmesi
- Sampler Primitive ile gerçek IBM donanımı üzerinde çalışma
- Transpilasyon: mantık devresinden yerel donanım kapılarına
1 Qubit Kapısı: Durum Vektör Dönüşümleri
Durum vektörünü dönüştüren 1 kübitlik bir geçit ve birim 2x2'lik bir matris (U^† U = I). Birlik, tersine çevrilebilirliği garanti eder; işlemi her zaman aşağıdaki komutu uygulayarak "geri alabilirsiniz": kapı eklendi.
# Porte a 1 qubit: definizione matematica e Qiskit
import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import Operator, Statevector
# Gate X (Pauli-X) — il NOT quantistico
# Matrice: [[0, 1], [1, 0]]
# Effetto: |0⟩ -> |1⟩, |1⟩ -> |0⟩
print("Gate X (NOT):")
print(Operator.from_label('X').data)
qc_x = QuantumCircuit(1)
qc_x.x(0)
print(f"X|0⟩ = {Statevector.from_instruction(qc_x).data}")
# [0.+0.j, 1.+0.j] = |1⟩
# Gate Hadamard (H) — crea superposizione
# Matrice: [[1/√2, 1/√2], [1/√2, -1/√2]]
# Effetto: |0⟩ -> |+⟩, |1⟩ -> |−⟩
print("\nGate H (Hadamard):")
qc_h = QuantumCircuit(1)
qc_h.h(0)
print(f"H|0⟩ = {Statevector.from_instruction(qc_h).data}")
# [0.707+0.j, 0.707+0.j] = |+⟩ = (|0⟩+|1⟩)/√2
# Gate Z (Pauli-Z) — phase flip
# Matrice: [[1, 0], [0, -1]]
# Effetto: |0⟩ -> |0⟩, |1⟩ -> -|1⟩ (cambia la fase di |1⟩)
print("\nGate Z (Phase Flip):")
print(f"Z|+⟩ = ?")
qc_z = QuantumCircuit(1)
qc_z.h(0) # prima crea |+⟩
qc_z.z(0) # poi applica Z
print(f"Z|+⟩ = {Statevector.from_instruction(qc_z).data}")
# [0.707+0.j, -0.707+0.j] = |−⟩
# Gate S e T — rotazioni di fase piu fini
# S = [[1,0],[0,i]]: rotazione di π/2 attorno asse Z
# T = [[1,0],[0,e^{iπ/4}]]: rotazione di π/4 attorno asse Z
qc_st = QuantumCircuit(1)
qc_st.h(0)
qc_st.s(0)
qc_st.t(0)
print(f"\nT(S|+⟩) = {Statevector.from_instruction(qc_st).data}")
2 Qubit kapısı: CNOT, CZ ve SWAP
2 kübitlik kapılar kübit çiftleri üzerinde çalışır ve dolanıklık yaratmak için gereklidir. En önemlisi CNOT (Kontrollü-DEĞİL):
# Porte a 2 qubit
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
# CNOT (CX): se qubit control e |1⟩, flip il qubit target
# Matrice 4x4: [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]]
print("CNOT truth table:")
for control_state, target_state in [(0,0), (0,1), (1,0), (1,1)]:
qc = QuantumCircuit(2)
if control_state == 1:
qc.x(0)
if target_state == 1:
qc.x(1)
qc.cx(0, 1) # qubit 0 = control, qubit 1 = target
sv = Statevector.from_instruction(qc)
result_probs = sv.probabilities_dict()
result = max(result_probs, key=result_probs.get)
print(f" CNOT|{control_state}{target_state}⟩ = |{result}⟩")
# CNOT|00⟩ = |00⟩
# CNOT|01⟩ = |01⟩
# CNOT|10⟩ = |11⟩ <- target si inverte quando control e 1
# CNOT|11⟩ = |10⟩ <- target si inverte quando control e 1
# SWAP: scambia gli stati dei due qubit
qc_swap = QuantumCircuit(2)
qc_swap.x(0) # qubit 0 = |1⟩, qubit 1 = |0⟩
qc_swap.swap(0, 1)
sv_swap = Statevector.from_instruction(qc_swap)
print(f"\nSWAP|10⟩ = {max(sv_swap.probabilities_dict(), key=sv_swap.probabilities_dict().get)}")
# SWAP|10⟩ = |01⟩
# Toffoli (CCX): CNOT con 2 qubit di controllo
# Il gate universale per computazione classica reversibile
qc_toffoli = QuantumCircuit(3)
qc_toffoli.x(0) # control 1 = |1⟩
qc_toffoli.x(1) # control 2 = |1⟩
qc_toffoli.ccx(0, 1, 2) # flip target solo se entrambi i control sono |1⟩
sv_t = Statevector.from_instruction(qc_toffoli)
print(f"Toffoli|110⟩ = {max(sv_t.probabilities_dict(), key=sv_t.probabilities_dict().get)}")
# Toffoli|110⟩ = |111⟩
Bell Durumu: İlk Tam Devre
Bell durumu gerçek dolaşıklığı gösteren en basit devredir. Sadece gerektirir iki kapı - Hadamard ve CNOT - ve birçok kuantum algoritmasının temelidir:
# Bell State: costruzione, simulazione e analisi
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector, DensityMatrix
from qiskit_aer import AerSimulator
from qiskit import transpile
# Costruzione del circuito Bell State |Φ+⟩
qc_bell = QuantumCircuit(2, 2, name='Bell State')
# Passo 1: Hadamard su qubit 0
# Stato: (|00⟩ + |10⟩) / √2
qc_bell.h(0)
# Passo 2: CNOT con qubit 0 come control, qubit 1 come target
# Stato: (|00⟩ + |11⟩) / √2 <- Bell state!
qc_bell.cx(0, 1)
# Visualizza il circuito
print("Circuito Bell State:")
print(qc_bell.draw('text'))
print()
# Analisi statevector (senza misura)
sv = Statevector.from_instruction(qc_bell)
print(f"Statevector: {sv.data}")
# [0.707, 0, 0, 0.707] -> 50% |00⟩, 50% |11⟩
print(f"Probabilita: {sv.probabilities_dict()}")
# {'00': 0.5, '11': 0.5} <- nessuna probabilita per '01' e '10'
# Aggiungi misura e simula
qc_bell.measure([0, 1], [0, 1])
sim = AerSimulator()
compiled = transpile(qc_bell, sim)
result = sim.run(compiled, shots=10000).result()
counts = result.get_counts()
print(f"\nRisultati simulazione (10000 shots): {counts}")
# {'00': ~5000, '11': ~5000} — MAI '01' o '10'
# Verifica entanglement: calcola concurrence
dm = DensityMatrix.from_instruction(QuantumCircuit(2).compose(
QuantumCircuit(2).compose(QuantumCircuit(2))
))
# (entanglement misurabile con partial trace e reduced density matrix)
4 Çan Durumu
2 kubitlik 4 boyutlu Hilbert uzayının temeli olan 4 Bell durumu vardır:
# Tutti e 4 i Bell States
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
def create_bell_state(phi_plus=True, psi=False) -> QuantumCircuit:
"""
|Φ+⟩ = (|00⟩ + |11⟩)/√2 (phi_plus=True, psi=False)
|Φ-⟩ = (|00⟩ - |11⟩)/√2 (phi_plus=False, psi=False)
|Ψ+⟩ = (|01⟩ + |10⟩)/√2 (phi_plus=True, psi=True)
|Ψ-⟩ = (|01⟩ - |10⟩)/√2 (phi_plus=False, psi=True)
"""
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
if psi:
qc.x(1) # Flip target: |00⟩ e |11⟩ diventano |01⟩ e |10⟩
if not phi_plus:
qc.z(0) # Phase flip: + diventa -
return qc
bell_states = {
'|Φ+⟩': create_bell_state(True, False),
'|Φ-⟩': create_bell_state(False, False),
'|Ψ+⟩': create_bell_state(True, True),
'|Ψ-⟩': create_bell_state(False, True),
}
for name, qc in bell_states.items():
sv = Statevector.from_instruction(qc)
probs = {k: round(v, 3) for k, v in sv.probabilities_dict().items() if v > 0.01}
print(f"{name}: probabilita = {probs}")
Gerçek IBM Donanımında Çalıştırma
Simülasyonu ve geliştirilmesi faydalıdır, ancak gerçek test ve fiziksel donanımdır. İşte iş akışı Bell durumunu gerçek bir IBM işlemcide çalıştırmak için Qiskit v2 ile tamamlandı:
# Esecuzione su hardware IBM reale con Qiskit v2 Primitives
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
# Autenticazione
service = QiskitRuntimeService(channel='ibm_quantum')
# Seleziona il backend meno occupato (per account gratuito)
backend = service.least_busy(
operational=True,
simulator=False,
min_num_qubits=2
)
print(f"Backend: {backend.name}")
print(f"Qubit disponibili: {backend.num_qubits}")
print(f"Job in coda: {backend.status().pending_jobs}")
# Crea il circuito Bell State
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
# NUOVO in Qiskit v2: transpile ottimizzato per l'hardware specifico
# 83x piu veloce rispetto a Qiskit 0.x per circuiti complessi
pass_manager = generate_preset_pass_manager(
backend=backend,
optimization_level=1 # 0=veloce, 1=bilanciato, 2=lento ma ottimale
)
isa_circuit = pass_manager.run(qc)
print(f"\nGate originali: {qc.count_ops()}")
print(f"Gate dopo transpilation: {isa_circuit.count_ops()}")
# Il transpiler aggiunge swap gates perche l'hardware ha connettivita limitata
# Esegui con SamplerV2 Primitive
sampler = Sampler(backend)
job = sampler.run([isa_circuit], shots=4096)
print(f"\nJob ID: {job.job_id()}")
print("Attendere risultati dall'hardware quantistico...")
print("(tipicamente 1-5 minuti in coda + 30 secondi di esecuzione)")
result = job.result()
counts = result[0].data.c.get_counts()
print(f"\nRisultati hardware reale (4096 shots):")
for state, count in sorted(counts.items()):
print(f" |{state}⟩: {count} ({count/4096*100:.1f}%)")
# Output tipico su hardware reale (con noise):
# |00⟩: ~1850 (45.2%) <- meno di 50% a causa del noise
# |11⟩: ~1920 (46.9%)
# |01⟩: ~150 (3.7%) <- errori da gate noise
# |10⟩: ~176 (4.3%) <- errori da gate noise
Transpilasyon: Mantık Devresinden Donanıma
Bir mantık devresi soyut kapıları (H, CNOT, vb.) kullanır, ancak her IBM işlemcisinin bir dizi kapısı vardır. farklı yerel kapılar. Transpiler mantık devresini yerel talimatlara dönüştürür Belirli bir donanımın yönlendirilmesi de optimize edilir (fiziksel kübitlerin hepsi birbirine bağlı).
# Analisi della transpilation
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
service = QiskitRuntimeService(channel='ibm_quantum')
backend = service.least_busy(operational=True, simulator=False)
# Circuito di esempio: 3 qubit, multiple gate
qc = QuantumCircuit(3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.rx(0.5, 0)
qc.ry(1.0, 1)
# Transpilation a diversi livelli di ottimizzazione
for opt_level in [0, 1, 2]:
pm = generate_preset_pass_manager(backend=backend, optimization_level=opt_level)
transpiled = pm.run(qc)
ops = transpiled.count_ops()
total_gates = sum(ops.values())
print(f"Optimization level {opt_level}: {total_gates} gates totali, ops={ops}")
# L'IBM Heron ha come native gates: CZ, RZ, SX, X
# Il transpiler decompone ogni gate logico in queste native gate
# Ottimizzazione level 2 riduce tipicamente il circuit depth del 20-40%
Akılda Tutulması Gereken Önemli Sınırlamalar
- Donanım gürültüsü: Gerçek donanımdaki sonuçlar her zaman hatalar içerir. Belirleyici sonuçlara ihtiyacınız olduğunda kuantum donanımını kullanmayın; simülatörü kullanın nihai doğrulama için geliştirme ve donanım için
- Devre derinliği sınırları: Eşevresizlikten önce geçitlerin tamamlanması gerekir. IBM Heron 2026'da gürültü aşırı olmadan önce maksimum pratik derinlik ve ~100-200 katman
- Kuyruk süresi: Gerçek donanımdaki kuyruk süresi dakikalardan saatlere kadar değişebilir. Geliştirme iş akışlarını buna göre planlayın
- Kapı evrenselliği: H + CNOT (veya Toffoli) evrenseldir — herhangi biri klasik olarak hesaplanabilir hesaplama ve bu kapılarla ifade edilebilir
Sonuçlar
Kuantum kapıları, durum vektörü üzerinde matematiksel olarak tersinir doğrusal dönüşümlerdir zarif ve hesaplama açısından güçlü. Bell durumu 2 kapıda sahip olmadığı bir şeyi gösteriyor klasik eşdeğeri: dolaşma. Qiskit v2 iş akışı — devre tasarımı, aktarma, Sampler İlkel — ve gerçek gelişimi destekleyecek kadar olgun.
Sonraki makale ilk kuantum algoritmasını oluşturmak için bu yapı taşlarını kullanıyor avantajı: Yapılandırılmamış veritabanlarında O(sqrt N) ikinci dereceden arama için Grover'ın algoritması.







