不確実性の探求
このQiskit in Classroomsモジュールでは、以下のパッケージがインストールされた Python 環境が必要です:
qiskitv2.1.0 または新しいqiskit-ibm-runtimev0.40.1 または新しいqiskit-aerv0.17.0 または新しいqiskit.visualizationnumpypylatexenc
上記のパッケージをセットアップしてインストールするには、 Qiskitのインストールガイドをご覧ください。 実際の量子コンピュータでジョブを実行するには、 IBM Quantum® のアカウントを設定する必要があります。 IBM Cloud アカウントの設定ガイドの手順に従ってください。
このモジュールはテストされ、8分のQPU時間を使用した。 これはあくまでも目安である。 実際の使用状況とは異なる場合があります。 時間のかかる2つの計算は、ヘッダーコメントにそのように記されており、QPUの時間が足りない場合はシミュレーターで行うことができる。 これらを取り除くと、このモジュールに必要なQPU時間はわずか30秒になります。
# 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'ケイティ博士( McCormick )によるモジュールのウォークスルーを以下でご覧いただくか、 こちらをクリックして YouTube でご覧ください。
概要
物理の授業以外でも、不確定性原理という言葉を聞いたことがあるだろう。 不確実性についての一般的な口語表現は、"何かを見ることによって、それに影響を与える "というものだ 確かにその通りだ。 しかし、より物理的な不確かさの表現方法としては、ある種の物理的な観測値があり、それらは同時に任意の精度で知ることができない非互換性を持っているということである。 多くの生徒が最初に出会うのは、 と という相容れない変数のペアである。これはそれぞれ、 -軸と呼ばれる1つの軸に沿った位置と、その方向に沿った直線運動量を意味する。 これらの変数に対する不確実性の制約は次のようになる。 ここで、 は「 の不確実性」と呼ばれ、統計学における標準偏差と同じ定義を持っており、次のように定義できる。 も同様に定義される。 ここでは、この不確定性関係を導出するのではなく、それが古典的波動に対する我々の理解と一致していることを指摘する。 つまり、完全な周波数( )と波長( )を持つ波は、完全な正弦波として永遠に続くことになる。 量子力学的には、これはド・ブロイの仮説に従って運動量を完全に知ることに相当する。 。しかし、波のような粒子の位置( )を知るためには、その粒子を記述する波が、例えば非常に狭いガウスのように、空間においてより鋭く尖ったものにならなければならない。 私たちは、このような鋭く尖った波動関数を含むあらゆる連続関数を、波長の異なる正弦波関数のフーリエ級数として表現できることを知っている。 しかし、波動関数がより鋭くピークを持つようになると(そして位置がよりよく知られるようになると)、フーリエ級数により多くの項が必要となり、より多くの波長の混合が必要となる(したがって、量子力学的には、より多くの運動量の値が必要となる)。
もっと簡単に言えば、運動量が明確に定義された状態(空間上の完全な正弦波)は、位置が非常に不確かである。 明確な位置を持つ状態(ディラック・デルタ分布のような)は、非常に不確かな運動量を持つ。
このような相性の悪さを示す変数は他にもある。 例えば、粒子のスピンはある軸に沿って明確に投影されるかもしれないが、直交する軸の投影については何もわからない。 例えば、状態 (量子ビットまたは spin-1/2 粒子の場合)は、 (量子ビットの場合は1、 spin-1/2 粒子の場合は )軸に沿った明確な投影を持つ。 しかし、この状態は2つの状態の重ね合わせとして書くことができ、それぞれの状態は : あるいは等価的に は、 と同様に、 へのよく定義された射影を持つ。したがって、 軸に沿った状態の投影を指定しても、 軸に沿った投影はわからない。 また、 軸への投影を指定した場合、 に沿った投影はわかりません。スピンの文脈と量子ビットの文脈でこれを議論する場合、細かい違いがあります。 しかし、一般的に言えば、パウリ行列の固有状態には興味深い関係があり、それを探ることができる。 このレッスンでは、これらの相容れない変数の不確定性についての直観を実験的にチェックし、 IBM® 量子コンピュータ上で不確定性関係が成り立つことを検証する。
直感の簡単な確認
この最初の実験とモジュール全体を通して、私たちは「Qiskitパターン」として知られる量子コンピューティングのフレームワークを使用する:
- ステップ1:古典的入力を量子問題にマップする
- ステップ2:量子実行のための問題の最適化
- ステップ 3:
IBM Quantumプリミティブを使用して実行する - ステップ4:後処理と古典的分析
私たちは通常、これらのステップに従うが、必ずしも明示的にラベルを貼るとは限らない。
まず、ランタイム・プリミティブを含む必要なパッケージをロードすることから始めよう。 また、利用可能な量子コンピュータの中で最も暇なものを選ぶ。
初回使用時に認証情報を保存するためのコードが以下にあります。 ノートブックを自分の環境に保存した後、必ずこの情報をノートブックから削除してください。そうすれば、ノートブックを共有するときにあなたの認証情報が誤って共有されることはありません。 詳しいガイダンスについては、 IBM Cloud アカウントの設定および信頼できない環境でのサービスの初期化を参照してください。
from numpy import pi
# Load IBM Quantum Compute 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 (
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)
# Use the least busy backend
backend = service.least_busy(min_num_qubits=127)
print(backend.name)Output:
ibm_sherbrooke
もし生徒がレッスン中に量子コンピュータの計算時間を使い果たした場合、以下の行はコメントなしで、上記で選択した量子コンピュータのノイズ動作を部分的に模倣したシミュレータをセットアップするために使用することができます。
# Import an estimator, this time from qiskit (we will import from Runtime for real hardware)
from qiskit_aer.primitives import SamplerV2, EstimatorV2
from qiskit_aer.noise import NoiseModel
# Generate the noise model from the backend properties
noise_model = NoiseModel.from_backend(backend)
noisy_sampler = SamplerV2(options={"backend_options": {"noise_model": noise_model}})
noisy_estimator = EstimatorV2(options={"backend_options": {"noise_model": noise_model}})ある作用素Zの固有状態は、別の作用素Xの固有状態ではないことを思い出してほしい。 、 の軸に沿って測定を行い、実験的にそれを観察する。 IBM 量子コンピュータは、 に沿って測定する構造になっているため、 に沿った測定には、単純に qc.measure () を使用する。しかし、 に沿って測定するためには、システムを回転させ、 の軸を測定する方向まで効果的に移動させる必要がある。 これはハダマードゲートで達成される。 に沿った測定にも同様のステップが必要である。ここでは便宜上、必要なステップをまとめた:
- に沿って測定する:
qc.measure() - :
qc.h()に沿って測定する。qc.measure() - :
qc.sdg()、qc.h()、qc.s。qc.measure()
ステップ1:古典的な入力を量子問題にマッピングする
この場合、マッピングのステップは、上述の測定と回転を量子回路で表現するだけである:
# Step 1: Map
# Import some general packages
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)
# Add a first measurement
qc.measure(qr, cr[0])
qc.barrier()
# Change basis so that measurements made on quantum computer which normally tell us about z,
# now tell us about x.
qc.h(qr)
# Add a second measurement
qc.measure(qr, cr[1])
qc.draw("mpl")Output:
ステップ2:量子実行のための問題最適化
このステップでは、私たちが実行したいオペレーションを、特定の量子コンピュータの機能の観点から表現する。 また、我々の問題を量子コンピューターのレイアウトにマッピングすることもできる。
# Step 2: 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(qc)ステップ 3: IBM Quantum プリミティブを使用して実行する
サンプラーを使用して、測定値に関する統計データを収集することができます。 . mode = backendを使用して、実際の量子コンピュータ上で動作するSamplerプリミティブを構築します。 ワークフローに応じて他にもモードがありますが、以下ではそのうちの1つを使用します。 Samplerは、「pubs」(プリミティブ・ユニファイド・ブロック)のリストを引数としてrun()メソッドを呼び出すことで使用されます。 各パブには最大3つの値が含まれており、これらが組み合わさって、推定器が完了すべき計算単位を定義します。具体的には、回路、観測可能変数、パラメータです。 回路の一覧、観測可能変数の一覧、およびパラメータの一覧を指定することもできます。 詳細については、「 PUBの概要 」をご覧ください
私たちは本物の量子コンピューター上で動作させ、本物の量子物理学の実験を実施したい。 実際の量子コンピューターで割り当てられた時間を使い果たした場合は、以下の量子コンピューター用のコードをコメントアウトし、シミュレーター上で実行するためのコードをコメントアウトしないようにすればよい。
# Step 3: Run the job on a real quantum computer
sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()
counts = res[0].data.c.get_counts()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()ステップ4:後処理
これは特にシンプルな後処理のケースで、単純にカウント数を視覚化する。
Qiskitは、量子ビット、測定値、その他のものを、番号の小さいものを最後/右側に並べるという、「リトルエンディアン」と呼ばれる慣例があることに注意してください。 つまり、以下の「10」と書かれた列は、1回目の測定で「0」、2回目の測定で「1」が得られたカウントを指している。
# Step 4: Post-process
from qiskit.visualization import plot_histogram
plot_histogram(counts)Output:
この慣例に魅力を感じない場合は、 marginal_counts 、各測定結果を個別に視覚化することができる:
from qiskit.result import marginal_counts
plot_histogram(
marginal_counts(counts, indices=[0]), title="Counts after first measurement"
)Output:
plot_histogram(
marginal_counts(counts, indices=[1]), title="Counts after second measurement"
)Output:
デフォルトでは、Qiskitの状態は 状態に初期化されます。 だから、最初の測定のほとんどすべてが 。しかし、2回目の測定( への状態の投影に関する情報を与えるもの)では、ほぼ均等に分かれたことに注意してほしい。この状態は、 に沿った測定では非常に予測可能な結果を与えるが、 に沿った測定では非常に予測不可能な結果を与えるようだ。これを探ってみよう。
逆の順序で測定したらどうなるか? まず、ハダマードゲートを使って、 が で測定される確率の統計を取ることから始める。次に、2回目の測定では、2回目のハダマードゲートを使って 。
# Step 1:
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)
# Change basis to measure along x.
qc.h(qr)
qc.measure(qr, cr[0])
qc.barrier()
# Change our basis back to z and make a second measurement
qc.h(qr)
qc.measure(qr, cr[1])
qc.draw("mpl")Output:
# Step 2: Transpile the circuit for running on a quantum computer
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)# Step 3: Run the job on a real quantum computer
sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()
counts = res[0].data.c.get_counts()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()# Step 4: Post-process
from qiskit.visualization import plot_histogram
plot_histogram(counts)Output:
ここでは、予測可能性はさらに低いようだ! 以前は、少なくとも最初の測定でどのような結果が出るかわかっていた。 なぜこのようなことが起きたのか、その理由を理解するのはそれほど難しいことではない。 と を半々で混ぜたものである。 したがって、最初の測定で+または-の状態(チャートでは0と1にマップされている)を得る確率は、明らかに等しいはずである。 に沿った測定は、状態を固有状態 か固有状態 のどちらかに崩壊させる。これらの状態はそれぞれ、 と の50対50の混合物である。 したがって、系が の固有状態にあるとき、 に沿って測定すると、 と の両方が得られ、ほぼ等しい確率で得られることは明らかである。 つまり、最初の例では、州によっては、ある測定結果については非常に予測しやすいが、他の測定結果については予測不可能であることが示された。 今回の例は、それよりももっと悪いことができることを示している。 測定の順番を入れ替えただけでも、両方の測定で予測不可能な結果が得られる状態がある。 ある量について、ある状態がどの程度確かなのか、あるいは不確かなのかを調べてみよう。
不確実性の計算
これを定量化するには、不確実性(分散)を用いる。 不確かさ」はしばしば分布の「分散」の平方根と定義される。 すなわち、ある観測値 の不確かさを と表し、次式で与えられる
パウリ行列の場合、 、これは次のようになる
これを具体的な例に当てはめてみよう。 状態 、その状態における観測可能な の不確かさを決定することから始めよう。
理解度チェック
の状態 の不確かさを手計算する。
与えられた状態では、こうなる:
qc.initialize() を使って任意の初期状態を作ることができる。 なお、ここでの虚数単位のシンタックスは である。
# Step 1: Map the problem into a quantum circuit
from qiskit.quantum_info import SparsePauliOp
import numpy as np
obs = SparsePauliOp("X")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Initialize the state
qc.initialize([1, 1j] / np.sqrt(2))
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
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 = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print(res[0].data.evs)Output:
-0.02408454165642664
上の式によれば 同じ状態にこだわって、 の期待値を求めてみよう:
# Step 1: Map the problem into a quantum circuit
obs = SparsePauliOp("Z")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Initialize the state to |+>_y
qc.initialize([1, 1j] / np.sqrt(2))
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
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(pubs)
res = job.result()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print(res[0].data.evs)Output:
0.04958271968581247
先ほどと同じ計算ができるが、分散は再び 1.0 に非常に近いことがわかるだろう。 と結論づけることができる。実際、我々が選んだ状態では、これはほぼ正しい。 しかし、我々はもっとうまくやれるだろうか? それとももっと悪い?
一方向に沿った位置、 と同じ方向に沿った運動量、 の間に不確定性関係があることを思い出してほしい。 これしか覚えていないと、 と も不確かさについてこのような基本的な限界を持っているのではないかと考えたくなるかもしれない。 もしかしたら、 、ゼロになることは不可能なのだろうか? 別の州を試してみて、これが成り立つかどうか見てみよう。 今回は を使ってみよう。 以下のコードでは、estimatorは同じジョブ投入で2組の回路と観測値を受け取ることができる。
# Step 1: Map the problem into a quantum circuit
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Z")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Initialize the state
qc.initialize([1, 1] / np.sqrt(2))
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
# Step 3: Run the circuit on a real quantum computer
with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, obs1_isa), (qc_isa, obs2_isa)]
job = estimator.run(pubs)
res = job.result()
batch.close()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc,obs1],[qc,obs2]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print("The expectation value of the first observable is: ", res[0].data.evs)
print("The expectation value of the second observable is: ", res[1].data.evs)Output:
The expectation value of the first observable is: 1.0011036174126302
The expectation value of the second observable is: 0.0029429797670141016
の期待値は 1.0 に近いが、 1.0 を超えてはならない。 1.0 をごく少量上回ったとしても気にする必要はない。 これはノイズや読み出しエラーなどの要因によるものである。 これは非常に重要なテーマだが、今は無視してもいいだろう。
我々は、 1.0 に非常に近い の期待値を得た( の分散が非常に低いことに対応する)。これにより、2つの分散の積はかなり低くなる:
これは正確にはゼロではないが、この値はパウリ作用素の固有値( )に比べて小さくなっている。さて、線形位置と運動量の間の不確定性関係は、演算子 と の間の転置関係を用いて、別の書き方ができることを思い出してほしい:
ここで
は、 と のコミュテーターである。
これはパウリ作用素に最も簡単に拡張できる形式である。 一般に、2つの演算子 と 、
また、パウリ行列の場合、 と を計算するためには、 が必要である
ここではこれを示し、同様の計算は練習として読者に委ねる:
これは完全に受け入れられる答えだが、もう一歩踏み込むとこうなる
したがって、不確定性関係は次のようになる
理解度チェック
と を決定する。これを用いて、 & 、 & の間の不確定性関係を書き出す。
一般的な不確定性関係と組み合わせると、次のようになる
一貫性検査
次に進む前に、これが前回の発見と一致していることを確認しておこう。 そして、 、この積が以下の値以上であることがわかった
確かにそうだ、
以下の質問を使って、これらの調査結果に対する直感を養ってください:
理解度チェック
以下の項目をセットで答えなさい:
(a) 、不確かさがゼロになると予想される状態は?
(b) 、不確かさがゼロになると予想される状態は?
(c) どのような状態でゼロ期待値 が得られるか?
(d) 上記の質問に対する回答は、ケース( )と一致しているか?
(e) 推定子を用いてこれを明示的にチェックするコードを書く。
(a)我々は、 オペレータの固有状態が、 の不確かさをゼロにすることを期待するかもしれない。実際、 を使うと、次のようになる。
(b)私たちは、 オペレータの固有状態が、 の不確かさをゼロにすることを期待するかもしれない。実際、 を使うと、次のようになる。
(c)どのような状態であれ、測定したときに、 、負の投影と同じくらい頻繁に、 、正の投影が得られると予想される。 これには と の固有状態が含まれる。
(d) はい。 、 の固有状態では、不確かさの積 の値が非常に小さくなると予想される: これは、同じ状態に対して 。 つまり、不確定性関係を満たすことができる。
(e)以下のようなコードで確認できる:
obs1 = SparsePauliOp.from_list( [("X", 1.000)] ) obs2 = SparsePauliOp.from_list( [("Y", 1.000)] ) obs3 = SparsePauliOp.from_list( [("Z", 1.000)] ) qc = QuantumCircuit(1,1) qc.ry(pi/2,0) job = estimator.run([(qc, [[obs1], [obs2], [obs3]])], precision=0.001) res=job.result()結果はすべての期待値を返す。 すべての期待値を取得し、不確実性を計算するには、次のようにする:
xs=res[0].data.evs[0] ys=abs(res[0].data.evs[1]) zs=res[0].data.evs[2] import math prodxz=((1-xs[i]*xs[i])**0.5)*(1-zs[i]*zs[i])**0.5
以下の項目をセットで答えなさい:
(a)大きな期待値 を持つような状態が考えられるか?
(b)同じ状態であれば、 の不確かさは大きいか小さいか?
(c)同じ状態であれば、 の不確かさは大きいか小さいか?
(d) 上記の質問に対する回答は、ケース( )と一致しているか?
(e) 推定子を用いてこれを明示的にチェックするコードを書く。
(a) : の固有状態について、 が見つかると予想される。
(b) の状態で を測定すると、同じ頻度/確率でプラスとマイナスの結果が得られるため、 の状態には大きな不確かさがあると予想される。
(c) の状態で を測定すると、同じ頻度/確率でプラスとマイナスの結果が得られるため、 の状態には大きな不確かさがあると予想される。
(d) はい。 、特に の固有状態については、不確定性の積 の値が大きいと予想される。 また、 。 つまり、この状態では 、 、どちらもかなり大きく、不確定性関係が再び満たされる可能性は十分にある。
(e)以下のようなコードで確認できる:
obs1 = SparsePauliOp.from_list( [("X", 1.000)] ) obs2 = SparsePauliOp.from_list( [("Y", 1.000)] ) obs3 = SparsePauliOp.from_list( [("Z", 1.000)] ) qc = QuantumCircuit(1,1) qc.rx(-pi/2,0) job = estimator.run([(qc, [[obs1], [obs2], [obs3]])], precision=0.001) res=job.result()結果はすべての期待値を返す。 すべての期待値を取得し、不確実性を計算するには、次のようにする:
xs=res[0].data.evs[0] ys=abs(res[0].data.evs[1]) zs=res[0].data.evs[2] import math prodxz=((1-xs[i]*xs[i])**0.5)*(1-zs[i]*zs[i])**0.5
不確定性関係の検証
上記のテストは、状態ベクトル の単一選択に対する不確定性関係の妥当性を示したに過ぎない。これが一般的に実験と一致していることを確信するためには、状態ベクトルの多くの選択肢について推定量を用いて同様の計算を行う必要がある。 RY`ゲートを使って、パラメータ を使って異なる初期状態を生成するために、状態ベクトルを の軸から回転させることから始めよう。
# The calculation below uses approximately 3-4 minutes of QPU time.
# Step 1: Map the problem into a quantum circuit
from qiskit.circuit import Parameter
import numpy as np
# Specify observables
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Y")
obs3 = SparsePauliOp("Z")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Rotate away from |0>
theta = Parameter("θ")
qc.ry(theta, 0)
params = np.linspace(0, 2, num=21)
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
obs3_isa = obs3.apply_layout(layout=qc_isa.layout)
# Step 3: Run the circuit on a real quantum computer
with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, [[obs1_isa], [obs2_isa], [obs3_isa]], [params])]
job = estimator.run(pubs, precision=0.01)
res = job.result()
batch.close()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([(qc, [[obs1], [obs2], [obs3]], [params])])
# res=job.result()# Step 4: Post-processing and classical analysis.
xs = res[0].data.evs[0]
ys = abs(res[0].data.evs[1])
zs = res[0].data.evs[2]
# Calculate uncertainties
delx = []
delz = []
prodxz = []
for i in range(len(xs)):
delx.append(abs((1 - xs[i] * xs[i])) ** 0.5)
delz.append(abs((1 - zs[i] * zs[i])) ** 0.5)
prodxz.append(delx[i] * delz[i])# Here we can plot the results from this simulation.
import matplotlib.pyplot as plt
plt.plot(params, delx, label=r"$\Delta$ X")
plt.plot(params, ys, label=r"$\langle$ Y $\rangle$")
plt.plot(params, delz, label=r"$\Delta$ Z")
plt.plot(params, prodxz, label=r"$\Delta$X $\Delta$Z")
plt.xlabel(r"$\theta$")
plt.ylabel("Expectation/Uncertainty Values")
plt.legend()
plt.show()Output:
赤い曲線 は、常にオレンジの曲線 よりも大きいことに注意。 不確実性積が沈んで限界にいくらか近づくこともあれば、上昇して限界から遠ざかることもあるが、常に不確定性関係に従う。
もちろん、これは不確定性関係の最良のテストではないかもしれない。私たちの極限 は常にゼロに非常に近いからだ。 。具体的には、 を の軸から様々な角度で回転させ、 の固有状態により大きな投影を持つ量子状態を使ってみよう。しかし今度は、その結果として得られる状態を、 の周りにある角度、おそらく 、回転させて、何が起こるか見てみよう。
# The calculation below uses approximately 3-4 minutes of QPU time.
from qiskit.circuit import Parameter
import numpy as np
# Step 1: Map the problem to a quantum circuit
# Specify observables
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Y")
obs3 = SparsePauliOp("Z")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Rotate away from |0> along one plane, and then along a transverse direction.
theta = Parameter("θ")
qc.ry(theta, 0)
qc.rz(pi / 4, 0)
params = np.linspace(0, 2, num=21)
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
obs3_isa = obs3.apply_layout(layout=qc_isa.layout)
# Step 3: Run the circuit on a real quantum computer
with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, [[obs1_isa], [obs2_isa], [obs3_isa]], [params])]
job = estimator.run(pubs, precision=0.01)
res = job.result()
batch.close()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([(qc, [[obs1], [obs2], [obs3]], [params])])
# res=job.result()# Step 4: Post-processing and classical analysis.
xs = res[0].data.evs[0]
ys = abs(res[0].data.evs[1])
zs = res[0].data.evs[2]
# Calculate uncertainties
delx = []
delz = []
prodxz = []
for i in range(len(xs)):
delx.append(abs((1 - xs[i] * xs[i])) ** 0.5)
delz.append(abs((1 - zs[i] * zs[i])) ** 0.5)
prodxz.append(delx[i] * delz[i])# Here we can plot the results from this simulation.
import matplotlib.pyplot as plt
plt.plot(params, delx, label=r"$\Delta$ X")
plt.plot(params, ys, label=r"$\langle$ Y $\rangle$")
plt.plot(params, delz, label=r"$\Delta$ Z")
plt.plot(params, prodxz, label=r"$\Delta$X $\Delta$Z")
plt.xlabel(r"$\theta$")
plt.ylabel("Expectation/Uncertainty Values")
plt.legend()
plt.show()Output:
今や不確定性の限界 が試されていることが明らかになった! 赤い曲線は以前よりもオレンジ色の曲線にずっと近づいている。 実際、ノイズが存在しない場合、不確定性関係は一点で完全に飽和する( )。 ノイズや読み出し誤差が存在する場合、測定結果が時折わずかに大きい値 を示すことは驚くべきことではない。 これは不確定性の真の違反ではなく、単に誤差がゼロでないことに起因する現象である。
理解度チェック
を可能な限り大きくし、これを限界まで追求する方法を説明してください。
現在のコードには、デフォルトの初期状態 を、 の軸から、パラメトリックな角度 で回転させ、さらに、 の軸を中心に、状態ベクトルを の軸まで回転させる角度 で回転させる行がある。
qc.ry(theta,0)qc.rz(pi/4,0)の回転を から に変え、 の固有状態まで回転させることができる:
qc.ry(theta,0)qc.rz(pi/2,0)それ以外の変更は必要ない。
コードを変更するかコピーして、Yの期待値を最大化した不確かさ関係のチェックを実装する。 不確定性関係は成り立つのか?
上の例とまったく同じコードを、次のように使います
qc.rz(pi/2,0)を交換した
qc.rz(pi/4,0).その結果、下の図のようになるはずで、そう、不確定性原理はまだ有効であるはずだ。

上のコードを修正して同様の絵を作り、量子コンピューターでの測定から、積 があるべき振る舞いをすることを示す。 好きな州を選んでください。
上の例とまったく同じコードを使うことになるが、実際には、異なる不確かさを計算するために期待値を使うだけで、上と同じ結果を使うことができる。 例えば
xs=res[0].data.evs[0] ys=res[0].data.evs[1] zs=abs(res[0].data.evs[2]) import math delx = [] dely = [] prodxy=[] for i in range(len(xs)): delx.append((1-xs[i]*xs[i])**0.5) dely.append((1-ys[i]*ys[i])**0.5) prodxy.append(((1-xs[i]*xs[i])**0.5)*(1-ys[i]*ys[i])**0.5)をプロットすることができる
import matplotlib.pyplot as plt plt.plot(params, delx, label=r'$\Delta$ X') plt.plot(params, dely, label=r'$\langle$ Y $\rangle$') plt.plot(params, zs, label=r'$\Delta$ Z') plt.plot(params, prodxy, label=r'$\Delta$X $\Delta$Z') plt.xlabel(r'$\theta$') plt.ylabel('Expectation/Uncertainty Values') plt.legend() plt.show()
課題: の多くの値をスキャンしたのと同じように、 の多くの値をスキャンし、不確定性関係が決して違反しないことを示す 3 次元プロットを作成するコードを書く。 好きな観測点を選んでください。
質問
指導者は、このノートがどのように使用されているかについての簡単なアンケートに答えることで、解答と一般的なカリキュラムにおける配置についてのガイダンスが付いたバージョンのノートを要求することができる。
重要な概念:
- 位置や直線運動量、スピンの成分など、多くの物理的観測値の間には不確定性関係がある。
- パウリ行列は交わらない。 これは、スピンのすべての成分を同時に知る/決定することはできないという事実を数学的に反映したものである。
- 量子コンピュータはパウリ作用素/行列を多用するので、パウリ作用素の不確定性関係を知っておくことは、密接に関連するスピン作用素と同様に有用である。
- 2つの演算子 と の不確かさを表す一般式は以下の通りである。
- ある演算子 の固有状態 は、その演算子に関連する物理的観測量の不確定性をゼロにする。 実験的に見ても、
- ある演算子 の固有状態 は、 と交わらない演算子 に対して、より大きな不確かさをもたらす。
- 実際の量子コンピュータを用いた実験結果は、物理作用素の行列表現から得られる直感を裏付けている。
正誤問題:
- T/F と を同時に測定することはできるが、 を測定することはできない。
- T/F と を同時に測定することはできるが、 を測定することはできない。
- T/F 線形の位置演算子と線形の運動量演算子は交わらない。
- T/F IBM 量子コンピュータはデフォルトで に沿って測定するので、他の方向に沿って測定するには回転を行わなければならない。
- T/F 以下の回路は を効果的に測定し、次に を測定する。
MC質問:
-
下の図は、次の不確かさの関係のどれを示しているか?
- a.
- b.
- c.
- d. 上記のいずれでもない
-
に沿って測定を行う標準的なシーケンスは次のうちどれですか?
- a. のみ
qc.measure() - b.
qc.h()その後qc.measure() - c.
qc.h(),qc.h()その後qc.measure() - d.
qc.h()qc.sqc.h()qc.measure() - e.
qc.sdg()qc.h(),qc.sqc.measure() - f.
qc.sdg()qc.h(),qc.s,qc.h()それからqc.measure()
- a. のみ
-
次のうち、最大の期待値( )をもたらす状態はどれか?
- a.
- b.
- c. とも呼ばれる。
- d. とも呼ばれる
- e. とも呼ばれる
- f. とも呼ばれる。
-
次のうち、最大の不確定性( )をもたらす状態はどれか?
- a.
- b. とも呼ばれる
- c. とも呼ばれる。
- d. a と b が同点
- e. bとcは同点
- f. a、b、cが同点
ディスカッションの質問:
-
この不確定性の概念は、直交空間におけるベクトルの矢印としてのスピンの概念と相反するものですか? ブロッホ球ではどうですか?
-
軸と 軸の中間の方向に沿って測定装置を方向付けるとする。 何が起こりますか。 この方向に沿って測定できるか? 、 における不確実性とどのような関係があるのだろうか?
-
ここで得られた結果に納得するために、さらにどのような実験をしたいですか?