メインコンテンツへスキップ

Qiskit 2でDiVincenzo基準をハンズオンで学ぶ

はじめに

物理学者David DiVincentoは、量子コンピュータのあらゆる物理実装に必要な5つの主要な要件と、量子通信のための2つの追加基準を概説しました。このノートブックでは、Qiskitの実践的なデモンストレーションを通じて、各DiVincenzo基準を体験します。理論を深く掘り下げるのではなく、各セクションでは1つの基準を簡潔に説明した上で、Qiskit 2を使ったコード演習を提供します。シミュレーターや実際のIBM Quantum・デバイスでCircuitを実行し、各原理をハンズオンで探求します

DiVincentoの量子計算のための5つの基準

  1. 適切に特性評価されたQubitを持つ、スケーラブルな物理システム。
  2. Qubitを単純な基準状態(例:|00…0〉)に初期化する能力。
  3. 長いデコヒーレンス時間(Qubitのコヒーレンスがゲート操作時間よりもはるかに長いこと)。
  4. 量子Gateの普遍的なセット(任意のユニタリ演算を実行できること)。
  5. Qubit固有の測定機能(各Qubitの状態を読み出すこと)。

(DiVincentoは量子通信のための2つの基準も説明しています:静止型Qubitと「飛行」Qubitを相互変換する能力、および飛行Qubitを拠点間で忠実に転送する能力です。これらはこのノートブックの末尾の推奨アクティビティに含まれています。)

以降の各セクションは1つの基準に対応しています。Qiskitを使って、コードとインタラクティブな実験でその概念を説明します。例えば、Qubitの数とCircuitの深さを増やすと結果にどのような影響を与えるか(基準1)、Qubitの状態をリセットして準備する方法(基準2)、シミュレーターと実デバイスでQubitを測定する方法(基準4)、Qiskitがどのように普遍的なGateを構成するか(基準3)、そして有限のコヒーレンス時間(T₁、T₂)が計算に与える影響(基準5)を確認します。最終的に、各DiVincenzo基準が実際に何を意味するか、そしてQiskitがそれらを実験するためにどのように機能するかについて、より深い直感が得られるでしょう。

# Added by doQumentation — required packages for this notebook
!pip install -q numpy
# Install necessary packages
!pip install qiskit[visualization] qiskit-ibm-runtime qiskit-aer qiskit_ibm_runtime

1. 基準1 – スケーラブルで適切に特性評価されたQubit

基準1: 「適切に特性評価されたQubitを持つ、スケーラブルな物理システム。」 これは、Qubitの数を増やしながらも確実に制御できる量子ハードウェア・プラットフォームが必要であることを意味します。各Qubitの特性(エネルギー準位、エラー率、接続性など)は十分に理解されている必要があります。基本的には、システムが破綻することなくより大きなCircuitを構築したいのです。実際には、Qubitの数やCircuitの深さをスケールアップするにつれて、エラーとデコヒーレンスが蓄積されるため、スケーラビリティのデモンストレーションは、サイズの増加がパフォーマンスにどのような影響を与えるかを理解することも意味します。

デモの目標: Qiskitを使用して、Circuitのスケールアップ(Qubitの数またはGateの深さ)が出力の忠実度に与える影響を示します。理想的なシナリオとノイズがある場合のシナリオをシミュレートし、大きなシステムや深いCircuitがデコヒーレンスやエラーにどのように悩まされるかを確認します。

まず、3つのQubitで小さなエンタングル状態(GHZ状態)を構築し、次に5つのQubitで大きな状態を構築して、単純なスケーリングテストを行います。n 個のQubitのGHZ状態は 12(0...0+1...1)\frac{1}{\sqrt{2}}(|0...0\rangle + |1...1\rangle) です。理想的なシミュレーションでは、n-QubitのGHZを測定すると、等しい確率で2つの結果のみ(すべて0またはすべて1)が得られます。nやCircuitの深さを増やすにつれて、理想的な出力ノイズのある出力を比較します。

from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import SamplerV2 as Sampler

# 3-qubit GHZ circuit
qc3 = QuantumCircuit(3, 3)
qc3.h(0)
qc3.cx(0, 1)
qc3.cx(1, 2)
qc3.measure([0, 1, 2], [0, 1, 2])

# 5-qubit GHZ circuit (scaling up the number of qubits)
qc5 = QuantumCircuit(5, 5)
qc5.h(0)
qc5.cx(0, range(1, 5)) # entangle qubit 0 with all others
qc5.measure(range(5), range(5))

# Transpile for a simulator backend
sim_backend = AerSimulator()
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc3 = pm.run(qc3)
isa_qc5 = pm.run(qc5)

# Run ideal simulations (no noise)
sampler = Sampler(mode=sim_backend)

job3 = sampler.run([isa_qc3], shots=1024)
result3 = job3.result()
counts3 = result3[0].data.c.get_counts()

job5 = sampler.run([isa_qc5], shots=1024)
result5 = job5.result()
counts5 = result5[0].data.c.get_counts()

print("3-qubit GHZ counts (ideal):", counts3)
plot_histogram(counts3, legend=['3-qubit ideal'], figsize=(6,4))
3-qubit GHZ counts (ideal): {'000': 531, '111': 493}

Quantum circuit diagram

print("5-qubit GHZ counts (ideal):", counts5)
plot_histogram(counts5, legend=['5-qubit ideal'], figsize=(6,4))
5-qubit GHZ counts (ideal): {'11111': 535, '00000': 489}

Code output

期待される結果(理想的な場合): 3-QubitのGHZは理想的には、カウントで約50%の000と50%の111が得られます。5-QubitのGHZは約50%の00000と50%の11111が得られます。状態が理想的に完全にコヒーレントでエンタングルされているため、他のビット列は現れません。各Circuitのヒストグラムにはすべてゼロとすべて1の結果に対応する2つの高いバーが表示されるはずです。

次に、ノイズのある環境ではどうなるかを見てみましょう。Qiskit AerのノイズModel機能を使用して、実デバイスのエラーを模倣します。例えば、IBMのBackendの特性を取得して、Gate・エラー、有限のGate時間、Qubitの緩和(T₁)、脱位相(T₂)、および読み出しエラーを含むノイズModelを作成できます。ここでは、IBM Quantum Brisbaneデバイスを表すフェイクBackendを使用してノイズModelを生成し、そのモデルでGHZ Circuitを再実行します。

演習1a:ノイズありのシミュレーション

以下のコードを完成させて、FakeBrisbane Backendに基づくノイズありのシミュレーターでGHZ Circuitをシミュレートしてください。これにより、現実的なノイズ環境でシステムがスケールするにつれてパフォーマンスがどのように低下するかがわかります。

from qiskit_ibm_runtime.fake_provider import FakeBrisbane

# We will reuse the ideal circuits qc3 and qc5 and their results from the previous cell.

# --- YOUR CODE HERE ---

# 1. Create a fake backend for IBM Quantum Brisbane
###brisbane_backend = ...

# 2. Create a noisy AerSimulator from the fake backend's properties
###noisy_sim = ...

# 3. Transpile the circuits for the noisy simulator (this adapts them to the device's specific gates and connectivity)
###pm = ...

###isa_qc3_noisy = ...

###isa_qc5_noisy = ...

# 4. Run the noisy simulations using the Sampler and get the counts
###sampler = ...

###job3 = ...

###result3_noisy = ...

###counts3_noisy = ...

###job5 = ...

###result5_noisy = ...

###counts5_noisy = ...

# --- END YOUR CODE ---

# This part is done for you to print and plot the results:
print("3-qubit GHZ counts (noisy):", counts3_noisy)
plot_histogram(counts3_noisy, legend=['3-qubit noisy'], figsize=(6,4))
print("5-qubit GHZ counts (noisy):", counts5_noisy)
plot_histogram(counts5_noisy, legend=['5-qubit noisy'], figsize=(6,4))

演習1b:実際のIBM Quantum・コンピューターで実行する

以下のコードは、実際のIBM Quantum・コンピューターでGHZ Circuitを実行します。これにより、実デバイスでパフォーマンスがどのように低下するかがわかります。

# your_api_key = "deleteThisAndPasteYourAPIKeyHere"
# your_crn = "deleteThisAndPasteYourCRNHere"

# QiskitRuntimeService.save_account(
# channel="ibm_quantum_platform",
# token=your_api_key,
# instance=your_crn,
# name="fallfest-2025",
# )

# Check that the account has been saved properly
# service = QiskitRuntimeService(name="fallfest-2025")
# print(service.saved_accounts())

# We will reuse the ideal circuits qc3 and qc5 and their results from the previous cell.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService(name="fallfest-2025")
real_backend = service.least_busy(operational=True, simulator=False)
print("Running on " + real_backend.name)

pm = generate_preset_pass_manager(backend=real_backend, optimization_level=1)
isa_qc3r = pm.run(qc3)
isa_qc5r = pm.run(qc5)

sampler = Sampler(mode=real_backend)

job3r = sampler.run([isa_qc3r], shots=1024)
result3r = job3r.result()
counts3r = result3r[0].data.c.get_counts()

job5r = sampler.run([isa_qc5r], shots=1024)
result5r = job5r.result()
counts5r = result5r[0].data.c.get_counts()

print("3-qubit GHZ counts (real):", counts3r)
plot_histogram(counts3r, legend=['3-qubit real'], figsize=(6,4))
print("5-qubit GHZ counts (real):", counts5r)
plot_histogram(counts5r, legend=['5-qubit real'], figsize=(6,4))

期待される結果(ノイズありと理想的な場合の比較): ノイズがある場合、シミュレートされた場合でも実デバイスでの場合でも、GHZ状態は完全ではありません。すべて0とすべて1以外の結果が現れます。3つのQubitの場合、000/111で100%となる代わりに、Gate・エラーやデコヒーレンスによっていくつかのQubitが反転するため、確率の一部が他のビット列(例:001010など)にも漏れます。5つのQubitの場合、効果はさらに顕著です。より大きなCircuit(より多くのQubitとCNOT Gate)はより多くのエラーを蓄積するため、すべて0とすべて1のピークが低くなり、他の多くの結果が現れます。この傾向はスケーラビリティの課題を示しています:スケールアップするにつれて、エラー訂正なしに高い忠実度を維持することがより困難になります。

洞察: スケーラブルな量子コンピューターは、システムが成長するにつれて量子相関を保持する必要があります。私たちの例は、ノイズが存在する場合にQubitの数やGateの深さを増やすと、結果の忠実度がどのように低下するかを示しています。残りの基準は、スケールアップしてもそれらのQubitが適切に動作するようにすること(低エラー、初期化可能など)に対処します。

2. 基準2 – Qubitの初期化

基準2: 「|000…〉などの単純な基準状態にQubitの状態を初期化する能力。」 すべてのQubitは確実に既知の基準状態(通常、各Qubitの基底状態|0〉)から始まる必要があります。初期化は、アルゴリズムがクリーンな状態から始まるために不可欠です。実際には、IBM Quantum・デバイスでは各Qubitは各Circuit実行の開始時に自動的に|0〉にリセットされます。Qiskitは、計算中にQubitをリセットしたりカスタム状態を準備したりする命令も提供しています。

デモの目標: Qiskitで開始時と途中でのQubitの初期化方法を示します。reset命令と状態準備メソッドの使用を実演します。

演習2:特定の状態を準備する

以下のコードブロックで、状態 10|10\rangle を準備するためのQuantumCircuitを完成させてください。これは、Qubit 0が状態 0|0\rangle にあり、Qubit 1が状態 1|1\rangle にあることを意味します。これを達成するために適切なGateと命令を使用してください。

from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator

# Create a circuit to initialize qubits to |10> and verify by measurement
qc_init = QuantumCircuit(2, 2)

# --- YOUR CODE HERE ---

# 1. Set qubit 1 to the |1> state

# 2. Explicitly reset qubit 0 to the |0> state

# --- END YOUR CODE ---

qc_init.measure([0, 1], [0, 1])
qc_init.draw('mpl')
# Run the circuit and check the outcome
sim_backend = AerSimulator()
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc_init = pm.run(qc_init)

sampler = Sampler(mode=sim_backend)

job = sampler.run([isa_qc_init], shots=1024)
result = job.result()
counts = result[0].data.c.get_counts()

print("Outcome of |10> state measured in Z-basis:", counts)
plot_histogram(counts)

シミュレーションから、10(qubit1=1、qubit0=0の2進数)が100%の確率で表示されるはずです。これは、Qubit 1が|1〉に、Qubit 0が|0〉に正常に準備されたことを意味します。

より一般的な状態準備のために、Qiskitはinitializeメソッドを使用して任意の状態への初期化を可能にします。例えば、重ね合わせ状態である +=(0+1)/2|+\rangle = (|0\rangle+|1\rangle)/\sqrt{2} にQubitを準備し、Bell状態 (00+11)/2(|00\rangle+|11\rangle)/\sqrt{2} に2つのQubitのペアを準備してみましょう:

import numpy as np

# Initialize a single qubit in |+> state and measure in Z-basis
qc_plus = QuantumCircuit(1, 1)
state_plus = [1/np.sqrt(2), 1/np.sqrt(2)] # amplitude for |0> and |1>
qc_plus.initialize(state_plus, 0)
qc_plus.measure(0, 0)

# Initialize two qubits in a Bell state manually
qc_bell = QuantumCircuit(2, 2)
bell_state = [1/np.sqrt(2), 0, 0, 1/np.sqrt(2)] # amplitudes for |00>,|01>,|10>,|11>
qc_bell.initialize(bell_state, [0, 1])
qc_bell.measure([0, 1], [0, 1])

# Transpile and run the initialization circuits
isa_qc_plus = pm.run(qc_plus)
job_plus = sampler.run([isa_qc_plus], shots=1024)
result_plus = job_plus.result()
counts_plus = result_plus[0].data.c.get_counts()

print("Outcome of |+> state measured in Z-basis:", counts_plus)

isa_qc_bell = pm.run(qc_bell)
job_bell = sampler.run([isa_qc_bell], shots=1024)
result_bell = job_bell.result()
counts_bell = result_bell[0].data.c.get_counts()

print("Outcome of Bell state measured in Z-basis:", counts_bell)
Outcome of |+> state measured in Z-basis: {'1': 499, '0': 525}
Outcome of Bell state measured in Z-basis: {'00': 508, '11': 516}

期待される結果: 単一Qubitの|+〉状態は、測定するとそれぞれ約50%の確率で01が得られます。Bell状態の測定では約50%の00と50%の11が得られるはずです。これらが表示されれば、それらの状態への初期化が成功したことが確認されます。

途中での初期化: QiskitのresetはCircuitの途中で使用し、Qubitをその場で|0〉に再初期化することができます。例えば、エラー訂正コードや反復アルゴリズムでは、Qubitを測定してから再利用のためにリセットすることがよくあります。reset操作は決定論的です。既存の状態を破棄し、Qubitを基底状態に冷却します。

デバイスの例: ibmq_brisbane(127 Qubit)や他のIBMデバイスのようなハードウェアでは、ジョブが実行されるとすべてのQubitがデフォルトで|0〉から始まります。異なる初期状態が必要な場合は、最初にGateを適用します(|1〉を得るためにXを使用したように)。(量子エラー訂正のための)継続的な再初期化は活発な研究テーマです。なぜなら、それを迅速に行うことが難しいからです。ありがたいことに、基本的な使用では|0…0〉からの新鮮なスタートが利用可能であり、他の望ましい初期状態の実現方法も示しました。

3. 基準3 – 長いコヒーレンス時間(デコヒーレンスとGate時間)

基準3: 「ゲート操作時間よりも十分に長い、関連するデコヒーレンス時間。」 これは、必要な操作を実行するために十分な時間、Qubitが量子状態を維持する必要性を示しています。各Qubitには T₁時間(エネルギー緩和時間:|1〉が|0〉に崩壊するまでの速さ)と T₂時間(位相緩和時間:相対的な位相コヒーレンスが失われるまでの速さ)があります。量子コンピュータが正しく動作するためには、これらの時間スケールがゲート操作の持続時間を大幅に超えている必要があります。

デモの目標: Qiskitで量子コヒーレンスを調査し、実行時間が長くなるにつれてデコヒーレンスがCircuitの結果に与える影響を示します。既知のT1/T2時間を持つフェイクBackendを使用して、この効果をシミュレートします。

有限コヒーレンスの影響を示すために、T1崩壊実験をシミュレートします。Qubitを|1〉状態に準備し、delay命令を使用して一定時間待機してから測定します。遅延が増加するにつれて|1〉を測定する確率が減少することが期待されます。

# This part is done for you. We are creating a list of circuits,
# each with a different delay time.

time_delays_ns = [0, 50000, 100000, 150000, 200000, 250000, 300000] # delay durations in ns

decay_expts = []
for delay in time_delays_ns:
qc = QuantumCircuit(1, 1)
qc.x(0) # initialize qubit to |1>
if delay > 0:
qc.delay(delay, 0, unit='ns') # wait 'delay' nanoseconds
qc.measure(0, 0)
decay_expts.append(qc)

decay_expts[1].draw('mpl') # Visualize one of the circuits

Quantum circuit diagram

演習3:T1崩壊実験のシミュレート

次に、FakeVigo(T1時間が約50〜100 µs)に基づくノイズありシミュレータを使用して、これらのCircuitを実行してください。シミュレータはdelay命令の実行中にT1/T2エラーを自動的に適用します。このBackendに向けてCircuitをトランスパイルし、実行してください。

from qiskit_ibm_runtime.fake_provider import FakeVigoV2 as FakeVigo
from qiskit_aer import AerSimulator

# --- YOUR CODE HERE ---

# 1. Create a noisy simulator from the FakeVigo backend
###sim_vigo = ...

# 2. Transpile the list of circuits for this simulator
###pm = ...

###isa_decay_expts = ...

# 3. Use the Sampler to run all the transpiled circuits in a single job
###sampler = ...

###job = ...

###result = ...

# --- END YOUR CODE ---

# This part is done for you to analyze and print the results.
for idx, (delay, qc) in enumerate(zip(time_delays_ns, isa_decay_expts)):
counts = result[idx].data.c.get_counts()
p1 = counts.get('1', 0) / 1000 # Assuming 1000 shots
print(f"Delay {delay} ns: P(qubit=1) = {p1:.3f}")

4. 基準4 – 量子Gateの普遍集合

基準4: 「量子Gateの『普遍的な』集合。」 これは、ハードウェアが有限個の基本Gateを組み合わせることで任意の量子計算を実行できる必要があることを意味します。古典コンピューティングではNANDが普遍的であるように、量子の世界では普遍的なGate集合の選択肢が多数あります(例:{H, T, CNOT}、または特定のマシンのネイティブGate)。たとえばIBMデバイスには、特定のQubit間の任意の1Qubit回転とCNOTなど、普遍的なネイティブ操作のセットがあります。Qiskitの役割の一つは、高レベルのGateをこれらの基底Gateにコンパイルすることです。

デモの目標: QiskitがGateを分解する様子を示すことで、Gate普遍性を説明します。非ネイティブGate(3Qubit Toffoli Gate(CCX)など)を取り上げ、デバイスの基底Gateへの分解方法を確認します。これにより、提供されたGate集合が普遍的であることが示されます。つまり、より複雑な操作を実現できます。

まず、典型的なIBM BackendのベースGateを確認しましょう。デバイス(またはそのフェイク版)の設定を照会します。たとえば、ibmq_brisbaneの基底Gateは以下の通りです。

遅延時間が増加するにつれてP(qubit=1)が減少し、T1緩和を特徴とする指数関数的な崩壊曲線に従うことが確認できるはずです。これにより、有限のコヒーレンス時間がCircuitの実行時間が長すぎる場合に計算エラーを引き起こすことが直接示されます。

アルゴリズムへの影響: より長いアルゴリズム(多くの連続したGate)を試みると、総実行時間がT2に近づくか超えてしまい、終了前に状態がコヒーレンスを失う可能性があります。そのため、コヒーレンス時間の改善とGateの高速化は、量子ハードウェア研究において最も重要な目標の2つです。

from qiskit_ibm_runtime.fake_provider import FakeBrisbane
fake_brisbane = FakeBrisbane()
print("Basis gates for ibmq_brisbane:", fake_brisbane.configuration().basis_gates)
Basis gates for ibmq_brisbane: ['ecr', 'id', 'rz', 'sx', 'x']

これにより、['id', 'rz', 'sx', 'x', 'ecr']のような出力が得られるかもしれません。これらはハードウェアがネイティブにサポートするプリミティブな操作です(Identity/ノーオップ、RZ回転、sqrt(X) Gate、X Gate、制御X)。その他のGateはすべてこれらから構成する必要があります。このセットは量子コンピューティングにとって普遍的であることが知られており(基本的に1Qubit回転と2Qubitエンタングリングゲートの組み合わせが普遍集合を形成します)。

次に、Toffoli(CCX)Gateをテストケースとして取り上げます。CCXは2つの制御Qubitがどちらも1のときのみターゲットQubitを反転させます。これはIBMハードウェアのネイティブGateではありません。Qiskitはccx命令を提供していますが、内部的に分解が行われます。

演習4:Toffoli Gateの分解

以下のコードを完成させて、Toffoli(CCX)Gateを含むCircuitを構築し、FakeBrisbane BackendのネイティブベースGateへQiskitで分解してください。

from qiskit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeBrisbane

# The fake_brisbane backend from the previous cell is reused here.

# --- YOUR CODE HERE ---

# 1. Create a circuit that can accommodate a Toffoli gate
###qc_toffoli = ...

# Apply a CCX gate with controls on qubits 0, 1 and target on qubit 2

# 2. Transpile the circuit to the fake Brisbane backend
###pm = ...

###isa_qc_toffoli = ...

# --- END YOUR CODE ---

print("Toffoli circuit before decomposition:")
print(qc_toffoli)

print("\nToffoli circuit after transpiling to Brisbane basis:")
# The .draw() method will now show the decomposed circuit
print(isa_qc_toffoli.draw(fold=120))

トランスパイル後の出力では、CCXがrzsxecrなどのより基本的なGateのシーケンスに置き換えられているはずです。これにより、ネイティブGateでToffoliを表現するのに十分であることが証明されます。

実践における普遍性: 上記の演習では、複雑な3QubitのGateがより単純なGateから構成されることを示しました。一般的に、任意のマルチQubitユニタリーは1Qubitおよび2QubitのGateから構成できます。Transpilerは量子ソフトウェアスタックの重要なコンポーネントであり、実行したい抽象的なアルゴリズムと特定の量子デバイスが実際に実行できる物理的な操作との間のギャップを橋渡しします。

デバイスの例: ibmq_brisbane デバイスはEagleアーキテクチャを使用し、上記の基底Gateを備えています。つまり、これらのマシンに送られるアルゴリズムはすべて、これらの操作のシーケンスに変換されます。この基準は本質的に制御可能性に関するものです。つまり、Qubitに必要な任意の操作を実行するための十分な制御手段を備えているということです。

5. 基準5 – Qubit測定

基準5: 「Qubit固有の測定能力。」 各Qubitの状態は測定可能である必要があります(通常、計算基底|0〉または|1〉で)。つまり、量子Circuitを実行した後、各Qubitを0/1の古典ビットとして読み出す必要があります。この基準は、各Qubitの信頼できる検出器を備えることと、どのQubitを測定するかを選択できることを意味します。

デモの目標: Qiskitでシミュレータと実機でどのように測定を行うかを示し、その違い(測定ノイズなど)を強調します。さまざまな状態のいくつかのQubitを測定し、結果を調べます。また、シミュレータとハードウェアの結果を比較することで、読み出しエラーがどのように現れるかを示します。

まず、簡単な測定の例を示します。

qc_measure = QuantumCircuit(2, 2)
qc_measure.x(0) # qubit 0 -> |1>, qubit 1 stays |0>
qc_measure.measure([0, 1], [0, 1])
qc_measure.draw('mpl')

Quantum circuit diagram

sim_backend = AerSimulator()
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc_measure = pm.run(qc_measure)
job = sampler.run([isa_qc_measure], shots=1000)
result = job.result()
counts = result[0].data.c.get_counts()

print("Simulator measurement counts:", counts)
Simulator measurement counts: {'01': 1000}

シミュレータでは01が1000回カウントされることが期待されます。次に、測定エラーをシミュレートして実際に確認してみましょう。Aerシミュレータに読み出しエラーを追加できます。Qiskit AerではReadoutErrorを定義し、ノイズモデルのQubitに付加することができます。

演習5:読み出しエラーのシミュレート

各Qubitが誤って測定される確率が2%(0が1と読み取られる、または1が0と読み取られる)となる簡単な読み出しエラーモデルを定義するコードを完成させてください。次に、このノイズモデルで測定Circuitを実行してください。

from qiskit_aer.noise import NoiseModel, ReadoutError

# --- YOUR CODE HERE ---

# 1. Define a 2% readout error for each single qubit.
# The format is a list of lists of probabilities: [[P(0|0), P(1|0)], [P(0|1), P(1|1)]]
# P(A|B) is the probability of measuring A given the state was |B>.
###ro_error = ...

# 2. Create a new noise model
###noise_model_ro = ...

# 3. Add the readout error to all qubits in the noise model
... # Hint: Use the add_all_qubit_readout_error method

# --- END YOUR CODE ---

sim_backend.set_options(noise_model=noise_model_ro)
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc_measure = pm.run(qc_measure)

# Run the measurement circuit with readout noise
sampler = Sampler(mode=sim_backend)

job = sampler.run([isa_qc_measure], shots=1024)
result = job.result()
counts = result[0].data.c.get_counts()

print("Simulation with 2% readout error:", counts)

このシミュレート出力では、実際のハードウェアが生成するものと同様に、誤ったカウント(110010など)が表示され、不完全な測定の影響が示されます。

デバイスの例: ibmq_brisbaneのような実機では、同じCircuitを実行すると、不正確な結果に対して同様のゼロでないカウントが表示される可能性が高いです。デバイスのキャリブレーションデータには各Qubitの読み出しエラーがリストされています。特定のQubitをターゲットにして読み出せることは非常に重要であり、そのエラー特性を理解することが意味のある結果を得るための鍵となります。実機での実行は演習1b:実際のIBM Quantum コンピュータでの実行で示しました。

量子通信基準(フライングQubit)

DiVincenzoは、ネットワーク化された量子コンピュータの構築に重要な、量子通信に特有の2つの基準も挙げています。

  1. 静止Qubitとフライング(飛行)Qubitの相互変換能力。(例:プロセッサ内のQubitを移動できる光子にマッピングする。)
  2. 位置間でフライングQubitを忠実に転送する能力。(例:量子情報を失わずに光子Qubitをファイバーで送信する。)

これらはQiskitの標準的な使用範囲を超えており、Qiskitは主にチップ上の静止Qubitを扱います。ただし、量子テレポーテーションという簡単な例でこれらの基準の概念を説明できます。テレポーテーションは、静止Qubitの状態を、もつれたペア(「フライング」部分)が運ぶ情報と古典通信に変換し、それを使って別の場所の別の静止Qubitで状態を再構築することを示しています。

Dr. Katie McCormickによるQiskit in Classrooms Quantum Teleportationモジュールでは、量子情報における最も魅力的なプロトコルの一つである量子テレポーテーションを段階的に解説します。量子状態(Qubit)がエンタングルメントとわずか2つの古典ビットを使ってアリスからボブに送られる仕組みを学べます。エンタングルされたBellペアの準備方法、アリス側でのBell基底測定の実行、古典的な結果の送信、そして元の状態を完全に回復するためのボブのQubitへの正しい量子Gateの適用という、テレポーテーション手順の全体を学びます。途中では、Qubitの情報をテレポートすることがno-cloning定理に違反したり光速を超えたりしない理由も探求します。IBM Quantum ハードウェアまたはシミュレータを使ったハンズオン演習を通じて、実際の測定、エンタングルメント、フィードフォワード制御の実践的な理解を深めます。

量子テレポーテーションをマスターすることで、異なるノード間で量子情報をエンコード、送信、回復する方法を理解し、量子ネットワーク、中継器システム、安全な通信スキーム、およびスケーラブルなモジュール式量子コンピューティングの基盤を築くことができます。

基準6と7との関連性: 実際の量子ネットワークでは、共有されたエンタングルペアは、アリスとボブの場所の間に「フライング」Qubit(光子など)を分配することで作成されます(基準7:忠実な転送)。テレポーテーションプロトコル自体は、アリスの静止Qubitの状態をエンタングルペアの彼女の半分にマッピングし、実質的にボブへ「送信」する方法として機能します(基準6:相互変換)。Qiskitはプロトコルのロジックを完全にシミュレートでき、通信アーキテクチャにおけるこれらの基準がどのように満たされるかの概念モデルを提供します。

まとめと結論

Qiskitを使用してDiVincenzo基準を説明するための、コードに焦点を当てた一連の演習を設計しました。これらのハンズオン例を通じて、実際の量子コンピューティングプラットフォームが各要件をどのように満たすかを探求しました。

  • スケーラビリティ:より多くのQubitでCircuitを構築し、ノイズのスケーリングを理解する。
  • 初期化:リセットと状態準備を使用して、既知の状態から計算を確実に開始する。
  • 普遍的なGate:複雑な操作をマシンの基底Gateにトランスパイルし、任意の計算が実行可能であることを証明する。
  • 測定:Qubitを読み出し、現実的な読み出しエラーに対処する。
  • コヒーレンス:有限のT₁、T₂がアルゴリズムの忠実度に与える影響と、デコヒーレンスに対して操作を高速に行う必要性を確認する。

完全性のために、Qiskit in Classrooms Quantum Teleportationモジュールを通じて量子通信の側面にも触れ、最後の2つの基準(フライングQubit)とつなげました。

最後に、これらの基準がIBMのような実際の量子コンピュータでどのように統合されているかを指摘しておく価値があります。ibmq_brisbaneのようなデバイスは、127個の超伝導Qubit(基準1)を備え、各Qubitは|0〉から始まり(基準2)、普遍性のためにキャリブレートされたGate集合とコンパイラを持ち(基準4)、各Qubitのマイクロ波読み出し共振器を備え(基準5)、ナノ秒オーダーの操作に対してコヒーレンス時間は数百マイクロ秒のオーダーです(基準3)。量子ネットワーキング実験では、IBMやその他の企業がフライングQubitのためのマイクロ波・光学変換や、遠隔Qubit間のエンタングルメント(基準6と7)を探求しており、これらは現在進行中の研究領域です。

このノートブックの演習を完了することで、DiVincenzo基準の定義を確認しただけでなく、コードを通じてそれらを体験しました。各要件が実際の量子ハードウェアとアルゴリズムにとって何を意味するかについての直感を深め、ぜひこれらの実験を拡張して、量子コンピューティングを楽しんでください!