Skip to main content
IBM Quantum Platform

CHSH 부등식

예상 소요 시간: Heron r3 프로세서에서 2분 (참고: 이는 단지 추정치일 뿐입니다.) (실행 시간은 다를 수 있습니다.)


학습 성과

  • 매개변수화된 벨 상태 CHSH 회로를 구성하고, CHSH 증인을 구성하는 네 가지 기대값을 측정하는 방법.
  • 프라이머리 함수를 EstimatorV2 한 번 호출하여 매개변수 스윕 시 여러 관측량의 기대값을 계산하는 방법.
  • 하드웨어에 제출하기 전에 잡음이 있는 로컬 시뮬레이터에서 양자 워크플로우를 검증하는 방법. AerSimulator.from_backend
  • IBM Quantum® 하드웨어에서 다수의 독립적인 벨 쌍을 병렬로 실행하여 CHSH 실험을 장치 전체에 걸친 얽힘 벤치마크로 확장하는 방법.

전제조건


배경

이 튜토리얼에서는 양자 컴퓨터에서 실험을 실행하여 추정기 프리미티브가 CHSH 부등식을 위반하는 것을 증명합니다.

클라우저(Clauser), 호른(Horne), 시모니(Shimony), 홀트(Holt)의 이름을 딴 CHSH 부등식은 벨의 정리(1969)를 실험적으로 검증하는 데 사용된다. 이 정리는 국소적 숨은 변수 이론으로는 양자역학에서 얽힘이 초래하는 일부 결과를 설명할 수 없다고 주장한다. CHSH 부등식의 위반을 입증하는 것은 양자역학이 국소적 숨은 변수 이론과 양립할 수 없음을 보여주는 것으로, 이는 양자역학을 이해하는 데 있어 기초가 되는 실험이다.

2022년 노벨 물리학상은 알랭 아스펙트, 존 클라우저, 안톤 자이링거에게 수여되었는데, 이는 부분적으로 양자 정보 과학 분야의 선구적인 업적, 특히 얽힌 광자를 이용한 실험을 통해 벨 부등식의 위반을 입증한 공로를 인정받은 결과이다.

이번 실험에서는 얽힘 쌍을 생성한 뒤, 각 큐비트를 서로 다른 두 가지 기저에서 측정할 것입니다. 첫 번째 큐비트의 기저를 AAaa 로, 두 번째 큐비트의 기저를 BBbb 로 표기하겠습니다. 이를 통해 CHSH 양 S1S_1 을 계산할 수 있습니다:

S1=A(Bb)+a(B+b).S_1 = A(B-b) + a(B+b).

각 관측값은 +1+1 또는 1-1 중 하나입니다. 분명히, B±bB\pm b 중 한 항은 00 이어야 하고, 다른 한 항은 ±2\pm 2 이어야 합니다. 따라서, S1=±2S_1 = \pm 2 입니다. S1S_1 의 평균값은 다음 부등식을 만족해야 합니다:

S12.|\langle S_1 \rangle|\leq 2.

S1S_1AA, aa, BB, bb 에 대해 전개하면 다음과 같습니다:

S1=ABAb+aB+ab2.|\langle S_1 \rangle| = |\langle AB \rangle - \langle Ab \rangle + \langle aB \rangle + \langle ab \rangle| \leq 2.

다른 CHSH 수량을 정의할 수 있습니다 S2S_2 :

S2=A(B+b)a(Bb),S_2 = A(B+b) - a(B-b),

이로 인해 또 다른 부등식이 도출되는데:

S2=AB+AbaB+ab2.|\langle S_2 \rangle| = |\langle AB \rangle + \langle Ab \rangle - \langle aB \rangle + \langle ab \rangle| \leq 2.

만약 양자역학이 국소적 숨은 변수 이론으로 설명될 수 있다면, 이러한 부등식은 항상 성립할 것이다. 이 튜토리얼에서 보여준 바와 같이, 양자 컴퓨터에서는 이러한 원리가 위반될 수 있으므로, 양자역학은 국소 숨겨진 변수 이론과 양립할 수 없다.

우리는 벨 상태 Φ+=00+112|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}} 를 준비하여 얽힌 쌍을 생성합니다. ‘Estimator’ 기본 기능을 사용하여, 원시 계수값으로부터 재구성할 필요 없이 기대값 AB,Ab,aB\langle AB \rangle, \langle Ab \rangle, \langle aB \rangleab\langle ab \rangle 를 직접 구합니다. 우리는 ZZXX 기저에서 두 번째 큐비트를 측정합니다. 첫 번째 큐비트 역시 직교 기저에서 측정되지만, 회전 각도 θ\theta002π2\pi 사이에서 스윕합니다. Estimator 프리미티브는 이 매개변수 스윕을 단일 프리미티브 통합 블록( PUB ) 에서 평가합니다.


요구사항

이 튜토리얼을 시작하기 전에 다음 항목이 설치되어 있는지 확인하십시오:

  • Qiskit SDK v2.0 또는 그 이후 버전, 시각화 기능 지원
  • Qiskit Runtime v0.40 또는 그 이후 (pip install qiskit-ibm-runtime)
  • Qiskit Aer v0.17 이상 (pip install qiskit-aer)

설정

# General
import numpy as np

# Qiskit imports
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

# `qiskit-ibm-runtime` imports
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

# Qiskit Aer for local noisy simulation
from qiskit_aer import AerSimulator

# Plotting routines
import matplotlib.pyplot as plt
import matplotlib.ticker as tck
# Select an IBM Quantum backend.
service = QiskitRuntimeService()
backend = service.least_busy(
    min_num_qubits=127, operational=True, simulator=False
)
backend.name

Output:

'ibm_pittsburgh'

소규모 시뮬레이터 예시

하드웨어 작업을 제출하기 전에, 로컬의 노이즈가 포함된 시뮬레이터에서 전체 워크플로를 검증합니다. 우리는 를 AerSimulator.from_backend(backend) 사용하여 사용자가 선택한 백엔드의 노이즈 모델과 커플링 맵을 상속하는 시뮬레이터를 구축하므로, 시뮬레이터의 응답은 하드웨어에서 예상되는 결과와 질적으로 유사합니다.

1단계: 고전적 입력을 양자 문제에 매핑하기

CHSH 회로는 단일 매개변수 θ\theta 로 표현되며, 이 매개변수는 첫 번째 큐비트의 측정 기저를 훑어 나갑니다. 이 Estimator 프리미티브는 분석을 단순화합니다. 관측 가능한 변수의 기대값을 직접 반환하며, 단 한 번의 호출로 다양한 매개변수 값에 대해 매개변수화된 회로를 평가할 수 있습니다.

theta = Parameter(r"$\theta$")

chsh_circuit = QuantumCircuit(2)
chsh_circuit.h(0)
chsh_circuit.cx(0, 1)
chsh_circuit.ry(theta, 0)
chsh_circuit.draw(output="mpl", idle_wires=False, style="iqp")

Output:

Output of the previous code cell

다음으로, 매개변수화된 회로( 00, 0.1π0.1\pi, 0.2π0.2\pi,..., 1.9π1.9\pi, 2π2\pi )를 평가할 00 부터 2π2\pi 까지의 21개 위상 값 목록을 생성합니다.

number_of_phases = 21
phases = np.linspace(0, 2 * np.pi, number_of_phases)
# Phases need to be expressed as a list of lists for the Estimator PUB
individual_phases = [[ph] for ph in phases]

마지막으로 관측량을 정의합니다. 첫 번째 큐비트는 θ\theta 로 회전된 축을 따라 측정되며, 두 번째 큐비트는 ZZXX 에서 측정됩니다. 이러한 선택을 바탕으로, 네 개의 CHSH 상관함수는 파울리 연산자 ZZZZ, ZXZX, XZXZXXXX 에 대응됩니다:

S1=ZZZX+XZ+XX,\langle S_1 \rangle = \langle ZZ \rangle - \langle ZX \rangle + \langle XZ \rangle + \langle XX \rangle, S2=ZZ+ZXXZ+XX.\langle S_2 \rangle = \langle ZZ \rangle + \langle ZX \rangle - \langle XZ \rangle + \langle XX \rangle.
# <S_1> = <ZZ> - <ZX> + <XZ> + <XX>
observable1 = SparsePauliOp.from_list(
    [("ZZ", 1), ("ZX", -1), ("XZ", 1), ("XX", 1)]
)

# <S_2> = <ZZ> + <ZX> - <XZ> + <XX>
observable2 = SparsePauliOp.from_list(
    [("ZZ", 1), ("ZX", 1), ("XZ", -1), ("XX", 1)]
)

2단계: 양자 하드웨어 실행을 위한 문제 최적화

V2 프리미티브는 대상 시스템이 지원하는 명령어 및 연결 방식(명령어 집합 아키텍처, 즉 ISA, 회로 및 관측 가능 변수)에 부합하는 회로와 관측 가능 변수만 허용합니다. 우리는 백엔드에서 를 AerSimulator 빌드하고 시뮬레이터의 대상 환경에 맞춰 트랜스파일링하여, 동일한 패스 매니저가 엔드투엔드 방식으로 실행되도록 합니다.

# Build a noisy simulator from the ibm_pittsburgh backend
aer_sim = AerSimulator.from_backend(backend)

pm = generate_preset_pass_manager(target=aer_sim.target, optimization_level=3)
chsh_isa_circuit = pm.run(chsh_circuit)
chsh_isa_circuit.draw(output="mpl", idle_wires=False, style="iqp")

Output:

Output of the previous code cell

SparsePauliOp.apply_layout또한,.를 사용하여 관측 가능한 양을 트랜스파일된 회로의 큐비트 배열에 맞게 변환합니다.

isa_observable1 = observable1.apply_layout(layout=chsh_isa_circuit.layout)
isa_observable2 = observable2.apply_layout(layout=chsh_isa_circuit.layout)

3단계: Qiskit primitives 명령어로 실행합니다

모드에서 aer_sim``EstimatorV2 매개변수 스윕을 실행합니다. Estimator run() 메서드는 PUB의 반복 가능한 객체를 매개변수로 받습니다. (circuit, observables, parameter_values, precision)각 PUB 파일은 다음과 같은 형식을 갖습니다. 두 관측 변수를 함께 전달하여 동일한 매개변수 스윕을 공유하도록 합니다.

# Use the AerSimulator-backed Estimator to validate the workflow locally
estimator_sim = Estimator(mode=aer_sim)

pub = (
    chsh_isa_circuit,  # ISA circuit
    [[isa_observable1], [isa_observable2]],  # ISA observables
    individual_phases,  # Parameter values
)

sim_result = estimator_sim.run(pubs=[pub]).result()

4단계: 후처리 수행 및 원하는 클래식 형식으로 결과 반환

Estimator는 두 관측 가능 변수에 대한 기대값을 반환합니다. 이 값들을 θ\theta 에 그래프로 표시하고, 여기에 고전적 상한( ±2\pm 2 )과 치렐슨 상한( ±22\pm 2\sqrt{2} )을 함께 표시했습니다. 회색 음영 처리된 영역은 이 두 상한 사이의 차이를 나타냅니다. 이 대역 안에 있는 점들은 CHSH 부등식을 위반한다.

chsh1_sim = sim_result[0].data.evs[0]
chsh2_sim = sim_result[0].data.evs[1]


def plot_chsh(phases, chsh1, chsh2, title):
    fig, ax = plt.subplots(figsize=(10, 6))

    ax.plot(
        phases / np.pi, chsh1, "o-", label=r"$\langle S_1 \rangle$", zorder=3
    )
    ax.plot(
        phases / np.pi, chsh2, "o-", label=r"$\langle S_2 \rangle$", zorder=3
    )

    # classical bound +-2
    ax.axhline(y=2, color="0.9", linestyle="--")
    ax.axhline(y=-2, color="0.9", linestyle="--")

    # quantum bound, +-2*sqrt(2)
    ax.axhline(y=np.sqrt(2) * 2, color="0.9", linestyle="-.")
    ax.axhline(y=-np.sqrt(2) * 2, color="0.9", linestyle="-.")
    ax.fill_between(phases / np.pi, 2, 2 * np.sqrt(2), color="0.6", alpha=0.7)
    ax.fill_between(
        phases / np.pi, -2, -2 * np.sqrt(2), color="0.6", alpha=0.7
    )

    ax.xaxis.set_major_formatter(tck.FormatStrFormatter("%g $\\pi$"))
    ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))

    ax.set_xlabel(r"$\theta$")
    ax.set_ylabel("CHSH witness")
    ax.set_title(title)
    ax.legend()
    plt.show()


plot_chsh(
    phases,
    chsh1_sim,
    chsh2_sim,
    "CHSH witnesses from AerSimulator (ibm_pittsburgh noise model)",
)

Output:

Output of the previous code cell

이 시뮬레이터의 CHSH 증인은, 백엔드의 잡음 모델을 적용한 상태에서도 θ\theta 의 여러 값에서 이미 고전적 한계인 ±2\pm 2 를 초과하고 있다. 시뮬레이션된 소자 잡음으로 인해 피크 값은 Tsirelson 상한 ±22\pm 2\sqrt{2} 에 약간 미치지 못합니다. 워크플로우 검증이 완료되었으므로, 이제 실제 하드웨어 단계로 넘어갑니다.


대규모 하드웨어 예시

CHSH 검정은 본질적으로 2-큐비트 실험이므로, 회로 하나를 더 크게 만든다고 해서 확장성이 향상되지는 않습니다. 대신, 여러 테스트를 병렬로 실행함으로써 확장성을 확보합니다. 여기서는 연결성이 허용하는 한도 내에서 백엔드를 서로 겹치지 않는 벨 쌍으로 최대한 많이 타일링하고(결합 맵의 매칭 ), 각 쌍에 대해 독립적인 CHSH 하위 회로를 실행하며, 이 모든 과정을 단일 작업 내에서 수행합니다.

이를 통해 CHSH는 장치 전체를 아우르는 얽힘 품질 벤치마크로 기능하게 됩니다. 즉, 개별적으로 선별된 단일 쌍이 아닌, 칩의 상당 부분에 걸쳐 얽힘을 한 번에 테스트하며, 모든 쌍이 인접 쌍의 크로스톡 및 병렬 게이트 오류와 경쟁하는 현실적인 조건 하에서 수행됩니다. 모든 쌍에 대해 불평등 조건을 동시에 위반하는 것은 장치의 모든 곳에서 진정한 얽힘이 존재함을 입증한다.

# -------------------------Step 1: Map classical inputs to a quantum problem-------------------------
# A CHSH test is bipartite, so we scale up by running one independent CHSH
# experiment on every disjoint Bell pair the device can host. A greedy
# matching of the coupling map gives a set of edges that share no qubits.
num_qubits = backend.num_qubits
used = set()
pairs = []
for qa, qb in backend.coupling_map.get_edges():
    if qa not in used and qb not in used:
        pairs.append((qa, qb))
        used.update((qa, qb))
num_pairs = len(pairs)
print(
    f"Tiling {backend.name} with {num_pairs} parallel Bell pairs "
    f"({2 * num_pairs} of {num_qubits} qubits)"
)

# One parameterized CHSH sub-circuit per pair, all sharing the angle theta
theta = Parameter(r"$\theta$")
chsh_circuit = QuantumCircuit(num_qubits)
for qa, qb in pairs:
    chsh_circuit.h(qa)
    chsh_circuit.cx(qa, qb)
    chsh_circuit.ry(theta, qa)

# Embed the two CHSH observables onto each pair's qubits (identity elsewhere)
obs1 = SparsePauliOp.from_list([("ZZ", 1), ("ZX", -1), ("XZ", 1), ("XX", 1)])
obs2 = SparsePauliOp.from_list([("ZZ", 1), ("ZX", 1), ("XZ", -1), ("XX", 1)])
observables = []
for qa, qb in pairs:
    observables.append([obs1.apply_layout([qa, qb], num_qubits)])
    observables.append([obs2.apply_layout([qa, qb], num_qubits)])

number_of_phases = 21
phases = np.linspace(0, 2 * np.pi, number_of_phases)
individual_phases = [[ph] for ph in phases]

# -------------------------Step 2: Optimize problem for quantum hardware execution-------------------------
pm = generate_preset_pass_manager(target=backend.target, optimization_level=3)
chsh_isa_circuit = pm.run(chsh_circuit)
isa_observables = [
    [o[0].apply_layout(chsh_isa_circuit.layout)] for o in observables
]

# -------------------------Step 3: Execute using Qiskit primitives-------------------------
estimator_hw = Estimator(mode=backend)
estimator_hw.options.environment.job_tags = ["TUT_CI"]

pub = (chsh_isa_circuit, isa_observables, individual_phases)
job = estimator_hw.run(pubs=[pub])
print(f"Job ID: {job.job_id()}")
hw_result = job.result()

# -------------------------Step 4: Post-process and return result in desired classical format-------------------------
# evs has shape (2 * num_pairs, number_of_phases); rows alternate S1, S2
evs = np.asarray(hw_result[0].data.evs)
chsh1_all = evs[0::2]
chsh2_all = evs[1::2]

# A pair "violates" CHSH if its strongest witness exceeds the classical bound
peak = np.maximum(
    np.abs(chsh1_all).max(axis=1), np.abs(chsh2_all).max(axis=1)
)
n_violate = int(np.sum(peak > 2))
print(
    f"{n_violate}/{num_pairs} Bell pairs violated the CHSH inequality "
    f"(mean peak witness {peak.mean():.2f}, classical bound 2)"
)

fig, ax = plt.subplots(figsize=(10, 6))

# Faint individual per-pair curves
for row in chsh1_all:
    ax.plot(phases / np.pi, row, color="#1f77b4", alpha=0.2, lw=1)
for row in chsh2_all:
    ax.plot(phases / np.pi, row, color="#ff7f0e", alpha=0.2, lw=1)

# Bold mean curves across all pairs
ax.plot(
    phases / np.pi,
    chsh1_all.mean(axis=0),
    color="#1f77b4",
    lw=2.5,
    label=r"$\langle S_1 \rangle$ (mean)",
)
ax.plot(
    phases / np.pi,
    chsh2_all.mean(axis=0),
    color="#ff7f0e",
    lw=2.5,
    label=r"$\langle S_2 \rangle$ (mean)",
)

# classical bound +-2 and Tsirelson bound +-2*sqrt(2)
ax.axhline(y=2, color="0.9", linestyle="--")
ax.axhline(y=-2, color="0.9", linestyle="--")
ax.axhline(y=np.sqrt(2) * 2, color="0.9", linestyle="-.")
ax.axhline(y=-np.sqrt(2) * 2, color="0.9", linestyle="-.")
ax.fill_between(phases / np.pi, 2, 2 * np.sqrt(2), color="0.6", alpha=0.7)
ax.fill_between(phases / np.pi, -2, -2 * np.sqrt(2), color="0.6", alpha=0.7)

ax.xaxis.set_major_formatter(tck.FormatStrFormatter("%g $\\pi$"))
ax.xaxis.set_major_locator(tck.MultipleLocator(base=0.5))
ax.set_xlabel(r"$\theta$")
ax.set_ylabel("CHSH witness")
ax.set_title(
    f"CHSH witnesses for {num_pairs} parallel Bell pairs on {backend.name}"
)
ax.legend()
plt.show()

Output:

Tiling ibm_pittsburgh with 64 parallel Bell pairs (128 of 156 qubits)
Job ID: d86efd5g7okc73el0rp0
63/64 Bell pairs violated the CHSH inequality (mean peak witness 2.75, classical bound 2)
Output of the previous code cell

희미한 곡선들은 개별 벨 쌍을 나타내며, 굵은 곡선들은 장치 전체에 걸친 이들의 평균값을 나타냅니다. 모든 쌍은 양자역학이 예측한 것과 동일한 사인 곡선을 그리며, 희미한 곡선들 사이의 편차는 쌍마다 다른 잡음의 변동을 반영한다. 곡선이 회색 띠 영역에 들어가는 지점마다, 그 곡선은 ±2\pm 2 의 고전적 경계를 넘어선 것이며, 인쇄된 요약본을 보면 사실상 모든 쌍이 동시에 CHSH 부등식을 위반한다는 사실이 확인된다.

피크는 소자 잡음으로 인해 치렐슨 상한 ±22\pm 2\sqrt{2} 에는 미치지 못하지만, 결론은 분명하다. 즉, 백엔드는 단순히 미리 선정된 한 쌍의 입자뿐만 아니라 칩 전체에 걸쳐 동시에 진정한 얽힘 상태를 유지한다는 것이다. CHSH 실험이 “확장”되는 것은 바로 이러한 의미에서입니다. 즉, 하나의 더 큰 회로가 아니라, 모든 곳에서 동시에 얽힘을 검증하는 병렬 벤치마크로서 확장되는 것입니다.


다음 단계

권장사항

이 글이 흥미로웠다면, 다음 자료도 참고해 보시기 바랍니다:

이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.