射影測定
変分分類器の解説をした時に計算結果を取り出すのに最後測定をするという話をしました。
量子機械学習に限った話ではありませんが、量子回路での計算(演算)結果を取り出すには適した量子ビットを適した方法で測定することが必要になります。
古典コンピュータではANDとかOR回路で演算した結果の電圧値を読み出すような行為に相当します。
量子ビットの場合はどの量子ビットをどのような方法で読み出すかで取り出せる情報が異なります。
将来的にこういうハードウェアを理解しないといけないようなことはソフトウェア工学的には無くなるべきと思いますが、現状ではまだこのような原始的なレベルの理解が必要なので勉強しておきましょう。
対象とする読者
- 量子プログラミングに興味を持ち始めたばかりのエンジニア
- 量子計算に興味を持ち始めたばかりの高校生・大学生
- 数学・論理演算・電子回路に慣れていない方
など
前提とする知識
バージョン情報
- Python 3.9.5
- Qiskit 0.29.0
目次
測定理論
量子測定の仮定
量子力学にはいくつかの仮定(postulate)があり、その一つに測定についての項目があります。
様々な本で解説されており、本によって具体的な文は異なりますが、主旨は同一です。
ここではNielsen-Chuangの2.2.3節にある文を引用します。
Postulate3: Quantum measurements are described by a collection of measurement operators. These are operators acting on the state space of the system being measured. The index m refers to the measurement outcomes that may occur in the experiment. If the state of the quantum system is immediately before the measurement then the probability that result m occurs is given by and the state of the system after the measurement is The measurement operators satisfy the completeness equation,
手元に英語版しかなくすみません、、
これはコペンハーゲン解釈ではいわゆる「波束の収縮」に当たる文言ですが、その哲学的な話には立ち入らず、量子計算に用いることができる数学的なエッセンスだけ取り出して解釈します。
この仮定から量子状態とその測定について理解できることは次の3点です。
- ある測定値(に対応するインデックス)が得られる測定演算子(行列)をとする
- 測定前の量子状態において測定値が得られる確率は(2.92)式で得られる
- 測定後の量子状態は(2.93)式で得られる状態に変化する
測定というのは対象となる量子系(ここでは量子ビット)に対して測定器と結合させることによって測定値が得られるのですが、この際には何らかの物理現象を介しています。
超伝導量子ビットでは初期では電荷計や磁気センサーを、また最近ではマイクロ波の透過・吸収・反射などを利用して読み出しています。
これらの測定器との結合時に起こる物理現象によってそれまで純粋に他と相互作用することなくユニタリー発展していた量子系はその測定後に何らかの状態に遷移してしまうということです。
この遷移するプロセスも厳密には何らかの時間発展なのだと思いますが、ここでは不連続な変化が起きることとします。
一般の量子測定
今回のテーマは「射影測定」なのですが、それ以外の測定もありますので「量子測定」の全体像を整理しますと下記のベン図になります。
この図の通り、まず一般的な測定があって、その特別な場合として射影測定があります。
まずは一般的な測定から解説します。
測定とは
具体的な方法としては先の電荷計や磁気センサーなどで、量子系から物理量を得て、それに対応する情報を得るということです。
測定演算子
ある測定値
が得られる測定演算子は で、その集合をと表します。
この時に具体的にどのような測定器でどのような測定をするかは考慮していません。
先の(2.94)式
を満たしていればよいです。
測定前の状態をとし、測定後の状態をとした場合に、測定後の状態は測定前の状態と測定演算子を用いて下記で表します。
射影測定
量子計算でよく使うのは射影測定で、主に3種類あります。
- X測定(測定)
- 量子状態がかかを測定
- Y測定(測定)
- 光の偏光がかかを測定(本当は両矢印なのですが、tex記号に無い、、)
(一般の量子状態で簡潔に表せる状態はなく、光の偏光状態くらいが特別な表現があります。)
- 光の偏光がかかを測定(本当は両矢印なのですが、tex記号に無い、、)
- Z測定(測定)
- 量子状態がかかを測定
通常はかかを求めるZ測定がほとんどだと思います。
ただ、論文とかで式を追っていったときにが出てきたらやってることは射影測定だということを思い出していただければと思います。
ここでは簡単のために3種類紹介しましたが、一般に正規直交基底となる軸に射影する演算子を用いていれば、軸はX, Y, Zでなくとも良いですが量子計算ではまず使われないと思います。
それぞれの測定がハードウェア的に何をしているかは物理系によります。
偏光であればは右回り円偏光、は左回り円偏光に対応し、偏光板などを用いて光が通過する/しないを観測します。
超伝導量子ビット(トランズモン)の場合はは基底状態に、は第一励起状態に対応しており、マイクロ波の反射・透過・吸収を計測して、どちらの量子状態にいるかを観測します。
その他色々ありますが、量子回路に落とし込んでいるため、プログラミングする際にどのような物理系かは意識しなくて良くなっています。
計算基底(Computational Basis)
1量子ビットの場合、具体的にはなど、軸上の基底そのものです。
複数量子ビットの場合、具体的にはなど、1量子ビットの計算基底の組み合わせです。
射影測定とは
基底の軸上で測定で、射影演算子を用いた測定です。
具体的にが満たすべき条件は下記です。
- (はKroneckerのdelta)
これらを満たせれば何でも良いのですが、通常は測定値に対応した状態を用いて
が用いられます。
Z測定であれば(エネルギー固有値のインデックスに対応)であり、対応する状態はで、射影演算子はです。
ちゃんと1, 2を満たしていますので行列計算してみてください。
量子回路での対応
実際にそれぞれの基底で測定するにはどのようにプログラミングしてどのような量子回路を構成するのかを確認します。
以下のコードでcircuit.barrier()
の上までが状態生成で、circuit.barrier()
の下で測定方法を指定します。
Z測定
の4状態を実機を使ってZ基底で測定してみます。
| 0 >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.barrier() circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
| 1 >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.x(qr) circuit.barrier() circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
Z基底による測定によってとを見分けられています。
| + >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.barrier() circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
図4右のグラフでと表示されている状態がに相当し、がに相当します。
| - >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.z(qr) circuit.barrier() circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
状態はBloch球上では明らか別の状態なのですが、Z基底による測定上では見分けることができません。
下記のX測定で改めて確認しますが、X測定では見分けることが可能です。
X測定
の4状態を実機を使ってX基底で測定してみます。
| 0 >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.barrier() circuit.h(qr) circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
| 1 >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.x(qr) circuit.barrier() circuit.h(qr) circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
X基底の場合は状態と状態の見分けがつかなくなりました。
| + >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.barrier() circuit.h(qr) circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
| - >を測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.z(qr) circuit.barrier() circuit.h(qr) circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
X測定の場合はとを見分けることができています。
測定したい状態に合わせて基底を変えましょう!
また、ここでは測定したい状態の方を回転させましたが、偏光を量子ビットとした場合は量子状態はそのままに、偏光板の向きや位相など測定の方を変えることができます。
超伝導量子ビットの場合は状態の方を変えるしかない、、、と思います。
間違ってたらすみません、どなたか教えてください。
Y測定
の2状態を実機を使ってY基底で測定してみます。
Y軸上を向いた状態を見分けられ、X測定・Z測定では見分けられず、Y測定で見分けられます。 まずはX, Z測定してみます。
| + > + | - >をX基底で測定
import numpy as np qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.rz(np.pi / 2, qr) circuit.barrier() circuit.h(qr) circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
| + > + | - >をZ基底で測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.rz(np.pi / 2, qr) circuit.barrier() circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
| + > + | - >をY基底で測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.rz(np.pi / 2, qr) circuit.barrier() circuit.rz(-np.pi / 2, qr) circuit.h(qr) circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
| + > - | - >をY基底で測定
qr = QuantumRegister(1) cr = ClassicalRegister(1) circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.rz(-np.pi / 2, qr) circuit.barrier() circuit.rz(-np.pi / 2, qr) circuit.h(qr) circuit.measure(qr, cr) backend = provider.get_backend('ibmq_armonk') job = execute(circuit, backend=backend, shots=8192) job_monitor(job, interval = 2) result = job.result() count = result.get_counts()
量子測定をもっと知りたい方へ
量子計算する上では計測・観測というのは状態を読み出して終わりですが、量子力学としては重要な理論の一つです。
理論をちゃんと勉強しようとするのは大学・大学院での研究になってしまいますが、一般向けの読み物として下記のようなものがあります。
まとめ
量子測定とは何か、数学的な定義、物理系との対応、そして実際に実機で測定する際の量子回路とコーディングをまとめました。
- 量子計算で主に使うのはX測定・Y測定・Z測定
- Z測定はそのままで、X測定はHゲートの後にZ測定、Y測定はゲート・Hゲートの後にZ測定
今回扱ったのは基本的な状態の観測だけなので、任意の状態をそれぞの基底で観測した時にどういう確率分布になるか試してみてください。
量子計測理論についてもNielsen & Chuangにあります。