量子コイン — 重ね合わせと干渉についてのモジュール
このQiskit in Classroomsモジュールを実行するには、以下のパッケージがインストールされた動作するPython環境が必要です。
qiskitv2.1.0 以降qiskit-ibm-runtimev0.40.1 以降qiskit-aerv0.17.0 以降qiskit.visualizationnumpypylatexenc
上記パッケージのセットアップとインストールについては、Qiskitのインストールガイドを参照してください。 実際の量子コンピューターでジョブを実行するには、IBM Cloudアカウントのセットアップガイドの手順に従い、IBM Quantum®のアカウントを作成する必要があります。
このモジュールはテスト済みで、QPU時間を47秒使用しました。これはあくまで目安であり、実際の使用量は異なる場合があります。
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'
以下でDr. Katie McCormickによるモジュールウォークスルー動画をご覧いただくか、こちらからYouTubeでご覧ください。
はじめに
このモジュールでは、量子論の中心にある基本原理の一つである「重ね合わせ(superposition)」を探求します。私たちの日常的な経験では、物体は常に明確な特性を持っています。その位置、大きさ、形、色——物体に関するあらゆることは、私たち観測者がまだ測定していなくても、定まっていて確かなものです。しかし量子の世界では、必ずしもそうではありません。量子オブジェクトは、古典的に許容される複数の状態の「重ね合わせ」と呼ばれるものに存在できます。重ね合わせ状態が測定されると、それらの状態のうちの一つにランダムに「収縮」します。
ある意味では、重ね合わせ状態を測定することはコインを投げることに似ています。どちらに着地するかを事前に知る方法はありません。この根本的な不確定性は、アインシュタインでさえ受け入れがたかった量子力学の側面です。彼はこのランダム性について「神はサイコロを振らない」と言ったことで有名です。しかし、これから見ていくように、神は実際にサイコロを振り、コインも投げるのです。
私たちは古典的なコイン投げを重ね合わせ状態の測定への類推として考えます。そして、QiskitとIBM®の量子プロセッサー上のQubitを使って「量子コイン」で遊ぶことで、その類推の限界をすぐに発見するでしょう。
古典的なコイン
まず古典的なコインから始めましょう。コインを投げると、50%の確率で表か裏のどちらかになります。原理的には、コインの正確な初期条件と投げる力・回転力がわかれば、どちらの面が出るかを計算できますが、実際にはコインがどちらに着地するかを事前に知ることはできません。そのためコイン投げは、結果が本質的にランダムな古典的確率状態の代表的な例として使われます。この50/50の確率を反映させて、着地前のコインの状態を次のように書けます。
ここで、2つの項は投げた結果として起こりうる2つの結果を表し、その係数はそれぞれの結果の確率を表します。通常、「」(「ket(ケット)」と呼ばれます)は量子状態を表すために使われますが、ここでは古典的な確率状態について述べていることに注意してください。古典情報と量子情報の表現方法の詳細については、「量子情報の基礎」コースのレッスン1:単一システムを参照してください。
コインを1000回投げて表と裏の回数を記録すると、次のようなグラフが得られます。
# import necessary packages:
import numpy as np
import matplotlib.pyplot as plt
import random
nflips = 1000
fliplist = [random.randint(0, 1) for f in range(nflips)]
# bar plots using get_gaussian_probs function
plt.hist(fliplist)
plt.show()
量子コイン
量子コンピューター上のQubitを使って、同様の確率状態を作ることができます。コイン投げと同様に、Qubitもとの2つの状態で測定されます。状態から始め、Hadamard Gateと呼ばれるものをQubitに適用することで、この確率的な「重ね合わせ」状態を作ります。これにより、Qubitはとの等しい重ね合わせに置かれます。この重ね合わせ状態は、一見するとコインと同じように見えて振る舞うかもしれませんが、まもなくそれ以上のものがあることがわかります。このモジュールの目的は、重ね合わせが古典的なコイン投げと同じではないことを示すことです。
つまり、Qubitは0と1の等しい重ね合わせにあるため、測定するとが測定される確率50%、が測定される確率50%となります。この状態は、後で明らかになる理由から、古典的な確率的ケースとは少し異なる書き方をします。
ここで、各状態を測定する確率は、上の古典的確率状態の場合とは異なり、もはや係数と等しくありません。代わりに、係数の二乗が確率を与えます。そして各係数は今や複素数、つまり実部と虚部の両方を持つことができます。
しかしこれらの違いにもかかわらず、この状態を測定した結果はコインを投げることと本質的に同じです。
from qiskit import QuantumCircuit
qcoin = QuantumCircuit(1)
qcoin.h(0)
qcoin.measure_all()
qcoin.draw("mpl")
つまり、Hadamard Gateを適用することはコインを投げることに相当します。そして、コインを1000回投げて表裏の統計を調べたのと同様に、Qiskitの「量子コイン」で同じことができます。SamplerというQiskit primitiveを使って、Circuitを何度も繰り返し実行し、結果として得られる状態の統計をサンプリングすることができます。
まず、Qiskit Runtimeサービスとprimitiveをロードし、次にCircuitを実行するBackendを選択します。
以下のコードには、初回使用時に認証情報を保存するためのコードが含まれています。認証情報を環境に保存した後は、ノートブックからその情報を必ず削除してください。ノートブックを共有する際に認証情報が誤って共有されないようにするためです。詳細については、IBM Cloudアカウントのセットアップおよび信頼されていない環境でのサービス初期化を参照してください。
# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService
# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')
# Load saved credentials
service = QiskitRuntimeService()
# Load the Runtime primitive and session
from qiskit_ibm_runtime import (
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)
# Use the least busy backend
backend = service.least_busy()
print(backend.name)
ibm_kingston
アカウントの利用可能時間が残っていない場合は、代わりにシミュレーターで実行することもできます。以下のセルのコードのコメントを外して実行してください。
## Use a local simulator
# from qiskit_aer import AerSimulator
## Generate a simulator that mimics the real quantum system
# backend_sim = AerSimulator.from_backend(backend)
## Import an estimator, this time from qiskit (we will import from Runtime for real hardware)
# from qiskit.primitives import BackendSamplerV2
# sampler_sim = BackendSamplerV2(backend = backend_sim)
# from qiskit.primitives import BackendEstimatorV2
# estimator_sim = BackendEstimatorV2(backend = backend_sim)
## Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qcoin)
## Execute
# On real hardware:
sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs, shots=1000)
res = job.result()
counts = res[0].data.meas.get_counts()
# or with Aer simulator with noise model from real backend
# job = sampler_sim.run([qc_isa])
# counts=job.result()[0].data.meas.get_counts()
## Analysis
from qiskit.visualization import plot_histogram
plot_histogram(counts)
上記のCircuitを1000回サンプリングすると、統計的な揺らぎを除いて、古典的なコインのヒストグラムと基本的に同一のものが得られます。
量子コインの統計をサンプリングするだけでなく、Estimatorと呼ばれる別のQiskit primitiveを使って、状態の観測量の期待値を測定することもできます。この期待値が何を意味するかを説明するために、古典的なコインを例として使いましょう。コインを使って賭けをするとします。コインを投げて「表」が出るたびに1ドル勝ち、「裏」が出るたびに1ドル負けるとします。1回の投げで得られる金額の期待値(観測量「お金」の期待値)を計算したい場合、次のように計算します。
1ドル勝つ確率と1ドル負ける確率が等しいため、期待値は0ドルです。
同様に、量子状態では観測量「Z」の期待値を計算できます。ZはPauli行列であり、状態とにそれぞれ+1と-1の値を持ちます。
from qiskit.quantum_info import Pauli
qcoin = QuantumCircuit(1)
qcoin.h(0)
# for Estimator, we do not apply the measurement to the circuit
<qiskit.circuit.instructionset.InstructionSet at 0x136df1ba0>
## Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
obs = Pauli("Z")
qc_isa = pm.run(qcoin)
obs_isa = obs.apply_layout(layout=qc_isa.layout)
## Execute
# On real hardware:
estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run([[qc_isa, obs_isa]])
res = job.result()
# On a simulator:
# job = estimator_sim.run([[qc_isa, obs_isa]])
# res=job.result()
print(res[0].data.evs)
-0.014799284701239441
期待通り(笑)、期待値として0が得られました。これは、0と1を測定する確率が等しいことを確認するもう一つの方法であり、コイン投げのように振る舞うことを示しています。
この時点では、「量子コイン」は古典的なコインとまったく同じように見えます。しかし次のセクションでは、両者の根本的な違いを明らかにする実験を行います。
量子の本質が明らかに:3次元での実験
思考実験をしてみましょう。コインを空中に投げ、地面に落とす代わりに、コインが両手の間を通過するタイミングで手を叩いて、両手のひらの間にコインを挟みます。こうすると、コインは表が上か下かではなく、表が左か右かになります。
理解度チェック
以下の問いを読んで答えを考えてから、三角形をクリックして解答を表示してください。
表が左か表が右か、それぞれの結果の確率はどのくらいですか?
答え:
確率は依然として50-50です。コイン投げの結果をどの次元に沿って測定するかは、確率に影響を与えるべきではありません。
おそらく、表が左か右かになる確率はやはり50-50だとお答えいただけたと思います。コイン投げを測定する次元は、結果の確率に影響を与えるべきではありません。
では、量子コインではどのように違いが現れるでしょうか?確認してみましょう。
前回と同じように、Hadamard Gateを使って量子重ね合わせを作ることができます。量子コインで「表が左か右か」を測定するには、古典的なコインと同じ ことができます。つまり、異なる軸に沿って測定するのです。量子コンピューターでの標準的な測定は垂直軸(Z軸)に沿ったものであり、これは古典的なコインの通常の「表が上か下か」の測定に相当します。しかし、量子コインに「表が左か右か」を尋ねることもできます。言い換えれば、軸を向いているまたはの状態にあるかどうかを確認できます。Samplerは測定基底Zでのみサンプリングしますが、Estimatorを使ってXの期待値を求めることができます。Xの値は、状態に対して+1、に対して-1です。
理解度チェック
以下の問いを読んで答えを考えてから、三角形をクリックして解答を表示してください。
量子コインがこの場合に古典的なコインと同じように振る舞うとすれば、状態がとに測定される確率は50-50になります。その場合、Estimatorが返すXの期待値はいくつになると予想されますか?
Estimatorが返すXの期待値はいくつになると予想されますか?答え:
状態にXを適用すると値+1が得られ、状態に適用すると-1が得られます。したがって、50-50の分布であれば、期待値は0になるでしょう。
# Step 1: map problem
qcoin_lr = QuantumCircuit(1)
qcoin_lr.h(0)
obs = Pauli("X")
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qcoin_lr)
obs_isa = obs.apply_layout(layout=qc_isa.layout)
# Step 3: Run the circuit on a real quantum computer
estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run([[qc_isa, obs_isa]])
res = job.result()
# Run the job on the Aer simulator with noise model from real backend
# job = estimator_sim.run([[qc_isa,obs_isa]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print(res[0].data.evs)
0.9985207100591716
この状態のXの期待値は1です。つまり、とを測定する確率は50-50ではありません。
理解度チェック
以下の質問を読んで答えを考えてから、三角形をクリックして解答を確認してください。