양자 게이트 및 회로: NOT 및 CNOT에서 Qiskit을 사용한 알고리즘까지
큐비트가 양자 컴퓨팅의 정보 단위라면, 양자 게이트 이는 그것을 변환하는 연산입니다. 이는 고전적인 부울 연산자와 동일합니다. 그러나 기존의 AND, OR, NOT과 달리 양자 게이트는 항상 거꾸로 할 수 있는 결정론적 이진 값이 아닌 상태 벡터 진폭에서 작동합니다.
이 기사에서 우리는 정문인 Hadamard, X, Z, CNOT에 대한 이해를 구축합니다. SWAP — 그리고 우리는 이를 사용하여 최초의 실제 양자 알고리즘인 Bell 상태를 구축합니다. 얽힘을 보여줍니다. 그런 다음 IBM Quantum을 통해 실제 IBM 하드웨어에서 회로를 실행합니다. 플랫폼.
무엇을 배울 것인가
- 1큐비트 게이트: Hadamard(H), X(NOT), Z, S, T 및 해당 행렬
- 2큐비트 게이트: CNOT, CZ, SWAP 및 Toffoli
- Qiskit QuantumCircuit으로 회로 구축
- 벨 상태(Bell State): 얽힘을 보여주는 기본 회로
- Qiskit Aer를 사용한 시뮬레이션 및 결과 시각화
- Sampler Primitive를 사용하여 실제 IBM 하드웨어에서 실행
- 변환: 논리 회로에서 기본 하드웨어 게이트까지
1 큐비트 게이트: 상태 벡터 변환
상태 벡터를 변환하는 1큐비트 게이트와 단위 2x2 행렬(U^† U = I)입니다. 단일성은 가역성을 보장합니다. 즉, 다음을 적용하여 언제든지 작업을 "실행 취소"할 수 있습니다. 문이 추가되었습니다.
# 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개의 큐비트 게이트: CNOT, CZ 및 SWAP
2큐비트 게이트는 큐비트 쌍에서 작동하며 얽힘을 생성하는 데 필요합니다. 가장 중요한 것은 CNOT (제어되지 않음):
# 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⟩
벨 스테이트: 최초의 완전한 서킷
벨 상태는 실제 얽힘을 보여주는 가장 간단한 회로입니다. 그것은 단지 필요합니다 Hadamard와 CNOT라는 두 개의 게이트가 있으며 많은 양자 알고리즘의 기초입니다.
# 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개의 벨 주
4개의 벨 상태가 있습니다. 이는 2큐비트의 4차원 힐베르트 공간의 기초입니다.
# 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}")
실제 IBM 하드웨어에서 실행
시뮬레이션하고 개발하는 데 유용하지만 실제 테스트 및 물리적 하드웨어입니다. 워크플로는 다음과 같습니다. 실제 IBM 프로세서에서 Bell 상태를 실행하기 위해 Qiskit v2가 포함되어 있습니다.
# 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
번역: 논리 회로에서 하드웨어까지
논리 회로는 추상 게이트(H, CNOT 등)를 사용하지만 모든 IBM 프로세서에는 일련의 추상 게이트가 있습니다. 다른 네이티브 게이트. 트랜스파일러는 논리 회로를 기본 명령어로 변환합니다. 특정 하드웨어의 라우팅도 최적화합니다(물리적 큐비트가 전부는 아닙니다). 서로 연결되어 있음).
# 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%
명심해야 할 중요한 제한 사항
- 하드웨어 소음: 실제 하드웨어의 결과에는 항상 오류가 포함됩니다. 결정론적 결과가 필요할 때 양자 하드웨어를 사용하지 말고 시뮬레이터를 사용하세요. 최종 검증을 위한 개발 및 하드웨어용
- 회로 깊이 제한: 게이트는 결어어긋남 전에 완료되어야 합니다. IBM Heron 2026에서는 최대 실제 깊이와 노이즈가 과도해지기 전 ~100-200개의 레이어
- 대기열 시간: 실제 하드웨어의 대기열 시간은 몇 분에서 몇 시간까지 다양합니다. 개발 워크플로우에 맞게 계획을 세우세요
- 게이트 보편성: H + CNOT(또는 Toffoli)는 보편적입니다. 고전적으로 계산 가능한 계산 및 이러한 게이트로 표현 가능
결론
양자 게이트는 수학적으로 상태 벡터에 대한 가역적 선형 변환입니다. 우아하고 계산적으로 강력합니다. Bell 상태는 2개의 게이트에서 자신에게 없는 것을 보여줍니다. 고전적 동등물: 얽힘. Qiskit v2 작업 흐름 — 회로 설계, 변환, Sampler Primitive — 실제 개발을 지원할 만큼 충분히 성숙되었습니다.
다음 기사에서는 이러한 빌딩 블록을 사용하여 첫 번째 양자 알고리즘을 구축합니다. 장점: 구조화되지 않은 데이터베이스에서 O(sqrt N) 2차 검색을 위한 Grover의 알고리즘.







