Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/translations/ja/ch-states/representing-qubit-states.ipynb
4073 views
Kernel: Python 3

量子ビット状態を表現する

あなたはビットについて、そして私たちの使い慣れたデジタルコンピューターがどのように動いているかを知っています。最新のソフトウェアで使用されているすべての複雑な変数、オブジェクト、およびデータ構造は、基本的にすべて膨大なビットの集まりでしかありません。量子コンピューティングに取り組んでいる人々は、これらを古典変数と呼んでいます。この記事を読むために使用しているように、古典変数を使用しているコンピューターは、古典コンピューターと呼ばれます。

量子コンピューターでは、基本的な変数は量子ビット、つまりビットの量子版です。これらには通常のビットとまったく同じ制限があります。1つのバイナリー情報のみを格納でき、[[0または1|-1または1|0 | 1|-1]]の出力しか出力できません。 ただし、量子力学でしか説明できない方法で操作することもできます。これにより、新しいゲートで遊ぶことができ、アルゴリズムを設計するための新しい方法を見つけることができます。

これらの新しいゲートを完全に理解するには、まず量子ビットの状態を書き留める方法を理解する必要があります。このために、ベクトル、行列、および複素数の数学を使用します。これらの概念は今後紹介していきますが、すでに慣れている方がよいでしょう。より詳細な説明や復習が必要な場合は、 こちらでガイドを見つけることができます。

1. 古典ビット vs 量子ビット

1.1 状態ベクトル

量子物理学では、状態ベクトル を使用してシステムの状態を記述します。たとえば、道路に沿った車の位置を記述したい場合、これは古典的なシステムであるため、数xxを使用します。

tracking a car with scalars

x=4x=4

代わりに、状態ベクトル と呼ばれるベクトルで数値の集合を使用します。状態ベクトルの各要素には、特定の場所で自動車を見つける確率が含まれています。

tracking a car with vectors

x=[0  0 1 0  0]         車が 位置4にある 確率   |x\rangle = \begin{bmatrix} 0\ \vdots \ 0 \ 1 \ 0 \ \vdots \ 0 \end{bmatrix} \begin{matrix} \ \ \ \leftarrow \ \ \ \ \end{matrix} \begin{matrix} \ \ \text{車が} \ \text{位置4にある} \ \text{確率} \ \ \ \end{matrix}

このことは位置だけでなく、車がとり得るすべての速度や、すべての色に対しても状態ベクトルをとることもできます。ただ(上記の車の例のような)古典的なシステムにおいては愚かなことです。なぜなら実際には1つの数値しか必要としないのに巨大なベクトルをとる必要があるためです。しかし、この章で見るように、状態ベクトルは、量子コンピューターを含む量子システムを追跡する方法としては非常に良い方法です。

1.2 量子ビット表記

古典ビットは、計算中のすべてのポイントで常に0または1のいずれかです。これ以上詳細をビットの状態に追加することはできません。したがって、古典ビット( c )の状態を書き留めるには、この2つのバイナリー値を使用できます。例えば:

c=0c = 0

この制約は量子ビットには存在しません。量子ビットから0または1を取得するかどうかは、出力を抽出するために測定を行うときに明確に定義する必要があるだけです。その時点で、これら2つの選択肢のいずれか確定する必要があります。それ以外の場合、その状態は、単純なバイナリ―値で取得できるものよりも複雑なものになります。

これらを説明する方法を理解するために、最初に2つの最も単純なケースに焦点を当てます。前のセクションで見たように、測定時に結果が確実に0になる状態で量子ビットを準備することができます。

この状態に名前が必要です。独創性に欠けますが00と呼びましょう。同様に、 1を出力することが確実な量子ビット状態が存在します。これを11と呼びます。これらの2つの状態は完全に相互に[[排他的|包括的]]です。量子ビットは確実に0を出力するか、確実に1を出力します。重複はありません。これを数学で表現する1つの方法は、2つの直交ベクトルを使用することです。

$$ \cssId{|0\rangle} = \begin{bmatrix} \cssId

{1} \ \cssId

このように、一度にたくさんの表記を取り入れるのは大変です。まず、奇妙な|\rangleを解きましょう。彼らの仕事は基本的に、0011というラベルのついた量子ビット状態を表すベクトルについて話しているのだということを思い出させることです。これは、ビット値01 、または数値0と1などと区別するのに役立ちます。これは、Diracによって導入されたブラケット表記の一部です。

ベクトルに精通していない場合は、基本的に、特定のルールを使用して操作する数値のリストと考えることができます。高校の物理レベルのベクトルに精通している場合は、これらの規則により、大きさと方向で量を記述するのにベクトルが適していることがわかります。たとえば、物体の速度はベクトルで完全に記述されます。ただし、量子状態にベクトルを使用する方法はこれとは少し異なります。したがって、以前の直感に固執しないでください。何か新しいことをする時が来ました!

ベクトルを使用すると、0|0\rangle1|1\rangleよりも複雑な状態を記述できます。たとえば、以下のベクトルを考えてみましょう。

$$ \cssId{|q_0\rangle} = \begin{bmatrix} \cssId

{\tfrac{1}{\sqrt{2}}} \ \cssId

この状態の意味を理解するには、ベクトルを操作するための数学的規則を使用する必要があります。具体的には、ベクトルを足し合わせる方法と、それらにスカラーを掛ける方法を理解する必要があります。

備忘

行列数学2つのベクトルを足し合わせるには、それらの要素同志を足し合わせます:
a=[a0 a1  an],b=[b0 b1  bn]|a\rangle = \begin{bmatrix}a_0 \ a_1 \ \vdots \ a_n \end{bmatrix}, \quad |b\rangle = \begin{bmatrix}b_0 \ b_1 \ \vdots \ b_n \end{bmatrix}a+b=[a0+b0 a1+b1  an+bn]|a\rangle + |b\rangle = \begin{bmatrix}a_0 + b_0 \ a_1 + b_1 \ \vdots \ a_n + b_n \end{bmatrix}

そして、ベクトルにスカラーを掛けるには、各要素にスカラーを掛けます:

xa=[x×a0 x×a1  x×an]x|a\rangle = \begin{bmatrix}x \times a_0 \ x \times a_1 \ \vdots \ x \times a_n \end{bmatrix}

これらの2つのルールは、ベクトルq0|q_0\rangle(上記を参照) を書き換えるために使用されます:

q0amp;=120+i21 amp;=12[1 0]+i2[0 1] amp;=[12 0]+[0 i2] amp;=[12 i2] \begin{aligned} |q_0\rangle &= \tfrac{1}{\sqrt{2}}|0\rangle + \tfrac{i}{\sqrt{2}}|1\rangle \ &= \tfrac{1}{\sqrt{2}}\begin{bmatrix}1 \ 0\end{bmatrix} + \tfrac{i}{\sqrt{2}}\begin{bmatrix}0 \ 1\end{bmatrix} \ &= \begin{bmatrix}\tfrac{1}{\sqrt{2}} \ 0\end{bmatrix} + \begin{bmatrix}0 \ \tfrac{i}{\sqrt{2}}\end{bmatrix} \ &= \begin{bmatrix}\tfrac{1}{\sqrt{2}} \ \tfrac{i}{\sqrt{2}} \end{bmatrix} \ \end{aligned}
正規直交基底2つのベクトル0|0\rangle1|1\rangleは正規直交であると前に述べました。これは、これらが両者とも_直交_していて_正規化_されていることを意味します。直交とは、ベクトルが直角であることを意味します。

また、正規化とは、それらの大きさ(矢印の長さ)が1に等しいことを意味します。2つのベクトル0|0\rangle1|1\rangle線形独立です。つまり、0|0\rangle1|1\rangleに関連して、またはその逆として表すことはできません。 ただし、二つのベクトル0|0\rangle1|1\rangle、およびスカラーによる加算と乗算の規則を使用して、2D空間で可能なすべてのベクトルを記述できます。

basis

ベクトル0|0\rangle1 rangle|1\ rangleは線形独立であり、これらのベクトルの加算とスカラー乗法を使用して2D空間の任意のベクトルを記述できることにより、ベクトル0|0\rangle1|1\rangle基底を形成すると言います。この場合、それらは直交して正規化されているため、正規直交基底とよびます。

状態0|0\rangle1 rangle|1\ rangleは正規直交基底を形成するため、これら2つの状態の組み合わせで任意の2Dベクトルを表すことができます。これにより、量子ビットの状態を別の形式で書き込むことができます。

ParseError: KaTeX parse error: Undefined control sequence: \cssId at position 1: \̲c̲s̲s̲I̲d̲{|q_0\rangle…

このベクトルq0|q_0\rangleは、量子ビットの 状態ベクトル と呼ばれます。これは、この量子ビットについておそらく知ることができるすべてのことを示しています。今のところ、状態ベクトルのこの特定の例について、いくつかの簡単な結論を引き出すことしかできません:それは完全に0|0\rangleではなく、完全に1|1\rangleでもありません。代わりに、2つの線形の組み合わせによって記述されます。量子力学では、通常、「重ね合わせ」という単語を使用して、このような線形の組み合わせを説明します。

この例の状態q0|q_0\rangleは、0|0\rangle1|1\rangleの重ね合わせとして表すことができますが、それは同じように明確でよく定義された量子ビット状態であることに変わりありません。このことを理解するために、量子ビットがどのように操作されるかを調べてみましょう。

1.3 Qiskitを使って量子ビットを探索する

まず、必要なすべてのツールをインポートする必要があります。

from qiskit import QuantumCircuit, assemble, Aer from qiskit.visualization import plot_histogram, plot_bloch_vector from math import sqrt, pi

Qiskitでは、QuantumCircuitオブジェクトを使用して回路を格納します。これは基本的に、回路内の量子ゲートとそれらが適用される量子ビットのリストです。

qc = QuantumCircuit(1) # 1量子ビットで量子回路を作成します。

私たちの量子回路では、量子ビットは常に0|0\rangleの状態で始まります。 initialize()メソッドを使用して、任意の状態に変換できます。必要なベクトルをリストの形式でinitialize()に指定し、初期化する量子ビットを指定します。

qc = QuantumCircuit(1) # Create a quantum circuit with one qubit initial_state = [0,1] # Define initial_state as |1> qc.initialize(initial_state, 0) # Apply initialisation operation to the 0th qubit qc.draw() # Let's view our circuit
Image in a Jupyter notebook

次に、Qiskitのシミュレーターの1つを使用して、量子ビットの結果の状態を表示できます。

sim = Aer.get_backend('aer_simulator') # Tell Qiskit how to simulate our circuit

回路から結果を取得するには、 回路とバックエンドを引数として指定しrunを使用して回路を実行します。次に、 .result()を使用して、次の結果を取得します。

qc = QuantumCircuit(1) # Create a quantum circuit with one qubit initial_state = [0,1] # Define initial_state as |1> qc.initialize(initial_state, 0) # Apply initialisation operation to the 0th qubit qc.save_statevector() # Tell simulator to save statevector qobj = assemble(qc) # Create a Qobj from the circuit for the simulator to run result = sim.run(qobj).result() # Do the simulation and return the result

resultから、.get_statevector()を使用して最終的な状態ベクトルを取得できます。

out_state = result.get_statevector() print(out_state) # Display the output state vector
[0.+0.j 1.+0.j]

注意 Pythonはjを使用して複素数のiiを表します。2つの複素数の要素を持つベクトルが表示されます。0.+0.j = 0と 1.+0.j = 1です。

実際の量子コンピューターと同じように量子ビットを測定して、結果を見てみましょう。

qc.measure_all() qc.draw()
Image in a Jupyter notebook

今回は、statevectorの代わりに、.get_counts()を使用して 01の結果のカウントを取得します。

qobj = assemble(qc) result = sim.run(qobj).result() counts = result.get_counts() plot_histogram(counts)
Image in a Jupyter notebook

(当然のことながら)1|1\rangleを測定する可能性が [[100]]% あることがわかります。

では、代わりに量子ビットを重ね合わせて、何が起こるか見てみましょう。 このセクションの前半の状態q0|q_0\rangleを使用します。

q0=120+i21|q_0\rangle = \tfrac{1}{\sqrt{2}}|0\rangle + \tfrac{i}{\sqrt{2}}|1\rangle

これらの振幅をPythonリストに追加する必要があります。複素振幅を追加するために、Pythonは虚数単位にjを使用します(通常、数学的には "ii" と呼びます)。

initial_state = [1/sqrt(2), 1j/sqrt(2)] # Define state |q_0>"$i$"

次に、以前と同じように量子ビットを初期化するための手順を繰り返します。

qc = QuantumCircuit(1) # Must redefine qc qc.initialize(initial_state, 0) # Initialize the 0th qubit in the state `initial_state` qc.save_statevector() # Save statevector qobj = assemble(qc) state = sim.run(qobj).result().get_statevector() # Execute the circuit print(state) # Print the result
[0.70710678+0.j 0. +0.70710678j]
qobj = assemble(qc) results = sim.run(qobj).result().get_counts() plot_histogram(results)
Image in a Jupyter notebook

1|1\rangleと比較して0|0\rangleを測定する確率が[[等しい|少ない|大きい]]結果であることがわかります。これを説明するためには、測定について話す必要があります。

2. 測定のルール

2.1 非常に重要なルール

測定には簡単なルールがあります。 状態ψ|\psi \rangleを状態x|x\rangleで測定する確率を見つけるには、

p(x)=xψ2p(|x\rangle) = | \langle x | \psi \rangle|^2

記号\langleおよび|は、x\langle x |が行ベクトルであることを示します。 量子力学では、列ベクトルを ケット 、行ベクトルを ブラ と呼びます。これらを合わせて ブラケット 表記を構成します。 すべてのケットa|a\rangleには対応するブラa\langle a|があり、共役転置を使用してそれらの間で変換します。

備忘

内積ベクトルを乗算する方法はいくつかありますが、ここでは_内積_を使用します。内積は、すでにおなじみの_ドット積_を一般化したものです。このガイドでは、ブラ(行ベクトル)とケット(列ベクトル)の間の内積を使用し、次の規則に従います。
a=[a0,amp;a1,amp;amp;an]\langle a| = \begin{bmatrix}a_0, & a_1, & \dots & a_n \end{bmatrix}b=[b0 b1  bn]|b\rangle = \begin{bmatrix}b_0 \ b_1 \ \vdots \ b_n \end{bmatrix}ab=a0b0+a1b1anbn\langle a|b\rangle = a_0 b_0 + a_1 b_1 \dots a_n b_n

2つのベクトルの内積は常にスカラーを与えることがわかります。 覚えておくと便利なことは、2つの直交ベクトルの内積は0であることです。たとえば、直交ベクトル0|0\rangle1|1\rangleがある場合、

10=[0,amp;1][1 0]=0\langle1|0\rangle = \begin{bmatrix} 0 , & 1\end{bmatrix}\begin{bmatrix}1 \ 0\end{bmatrix} = 0

さらに、ベクトル0|0\rangleおよび1|1\rangleも正規化されていることを覚えておいてください。(大きさが1に等しい)

00amp;=[1,amp;0][1 0]=1 11amp;=[0,amp;1][0 1]=1\begin{aligned} \langle0|0\rangle & = \begin{bmatrix} 1 , & 0\end{bmatrix}\begin{bmatrix}1 \ 0\end{bmatrix} = 1 \ \langle1|1\rangle & = \begin{bmatrix} 0 , & 1\end{bmatrix}\begin{bmatrix}0 \ 1\end{bmatrix} = 1 \end{aligned}
共役転置ブラケット間の変換は、共役転置法を使用して行われます。ケット(列ベクトル)は次のように表されます:
a=[a0 a1  an]\quad|a\rangle = \begin{bmatrix}a_0 \ a_1 \ \vdots \ a_n \end{bmatrix}

共役転置を取得するには、行列を転置し、要素を複素共役にします("∗" 演算で表されます)。ここで、複素数の複素共役は、実数部と虚数部が等しいが、符号が反対の数です。これにより、対応するブラ(行ベクトル)が次のようになります。

a=[a0,amp;a1,amp;amp;an]\langle a| = \begin{bmatrix}a_0^*, & a_1^*, & \dots & a_n^* \end{bmatrix}

上記の方程式では、x|x\rangleは任意の量子ビット状態にすることができます。 x|x\rangleを測定する確率を見つけるには、x|x\rangleと測定している状態(この場合はψ|\psi\rangle)の内積を取り、その大きさを二乗します。 これは少し複雑に見えるかもしれませんが、すぐに慣れます。

状態q0|q_0\rangleを見ると、0|0\rangleを測定する確率は確かに0.50.5であることがわかります。

q0amp;=120+i21 0q0amp;=1200+i201 amp;=121+i20 amp;=12 0q02amp;=12\begin{aligned} |q_0\rangle & = \tfrac{1}{\sqrt{2}}|0\rangle + \tfrac{i}{\sqrt{2}}|1\rangle \ \langle 0| q_0 \rangle & = \tfrac{1}{\sqrt{2}}\langle 0|0\rangle + \tfrac{i}{\sqrt{2}}\langle 0|1\rangle \ & = \tfrac{1}{\sqrt{2}}\cdot 1 + \tfrac{i}{\sqrt{2}} \cdot 0\ & = \tfrac{1}{\sqrt{2}}\ |\langle 0| q_0 \rangle|^2 & = \tfrac{1}{2} \end{aligned}

演習として1|1\rangleを測定する確率を確認してみてください。

この法則は、量子状態から情報を取り出す方法を支配しています。そのため、量子計算を行う上で非常に重要です。また、この法則はいくつかの重要な事実を暗示しています。

2.2 測定のルールの意味

#1 正規化

測定のルールは3つのことを意味します。1つ目は、状態ベクトルを1に正規化する必要があることです。

$$\langle\psi|\psi\rangle = 1 \$$

したがって

ψ=α0+β1|\psi\rangle = \alpha|0\rangle + \beta|1\rangle

このとき

α2+β2=1|\alpha|^2 + |\beta|^2 = 1

これは、この章を通して見た2\sqrt{2}の要因を説明しています。 実際、正規化されていないベクトルを initialize()に与えようとすると、エラーが発生します。

vector = [1,1] qc.initialize(vector, 0)
--------------------------------------------------------------------------- QiskitError Traceback (most recent call last) <ipython-input-12-ddc73828b990> in <module> 1 vector = [1,1] ----> 2 qc.initialize(vector, 0) /usr/local/anaconda3/lib/python3.7/site-packages/qiskit/extensions/quantum_initializer/initializer.py in initialize(self, params, qubits) 453 454 num_qubits = None if not isinstance(params, int) else len(qubits) --> 455 return self.append(Initialize(params, num_qubits), qubits) 456 457 /usr/local/anaconda3/lib/python3.7/site-packages/qiskit/extensions/quantum_initializer/initializer.py in __init__(self, params, num_qubits) 89 if not math.isclose(sum(np.absolute(params) ** 2), 1.0, 90 abs_tol=_EPS): ---> 91 raise QiskitError("Sum of amplitudes-squared does not equal one.") 92 93 num_qubits = int(num_qubits) QiskitError: 'Sum of amplitudes-squared does not equal one.'

練習問題

  1. 0|0\rangleを測定する確率が1/31/3になる状態ベクトルを作成してください。

  2. 同じ測定確率を与える別の状態ベクトルを作成してください。

  3. これら2つの状態の1|1\rangleを測定する確率が2/32/3であることを確認します。

以下のウィジェットで答えを確認できます(解答の精度は±1%です。ベクトルの中に 'pi' や 'sqrt()' などのnumpyの用語を使用できます)。

# このセルのコードを実行してウィジェットとやり取りします。 from qiskit_textbook.widgets import state_vector_exercise state_vector_exercise(target=1/3)

#2 他の測定

測定則は、状態ψ|\psi\ranglex|x\rangleとして測定される確率p(x)p(|x\rangle)を与えます。しかし、x|x\rangle0|0 \rangleまたは1|1\rangleしかありえないということはどこにも書いてありません。

これまでに考えてきた測定は、実は量子ビットを測定するための無限の可能性のうちの1つにすぎません。任意の直交する状態のペアに対して、量子ビットにその二つを選択させるような測定法を定義することができます。

この可能性については、次のセクションで詳しく説明します。今のところ、x|x\rangle は単に0|0\rangleまたは1|1\rangleに限定されないことだけは心に留めておいてください。

#2 グローバル位相

状態1|1\rangleを測定すると、確実に出力1が得られることがわかっています。ただし、次のような状態を書くこともできます。

[0 i]=i1.\begin{bmatrix}0 \ i\end{bmatrix} = i|1\rangle.

これがどのように動作するかを確認するために、測定則を適用してみます。

x(i1)2=ix12=x12|\langle x| (i|1\rangle) |^2 = | i \langle x|1\rangle|^2 = |\langle x|1\rangle|^2

ここで、複素数の大きさをとると、iiの因子が消えることがわかります。この効果は、測定された状態x|x\rangleとは全く関係なく、どのような測定を考えても、状態i1i|1\rangle の確率は、1|1\rangleの確率と同じです。測定は量子ビットから情報を抽出できる唯一の方法であるため、このことは、これら2つの状態が物理的に関連するすべての点で同等であることを意味します。

より一般的には、γ=1|\gamma|=1である状態の全体的な因子γ\gammaを「グローバル位相」と呼びます。グローバル位相のみが異なる状態は、物理的に区別できません。

x(γa)2=γxa2=xa2|\langle x| ( \gamma |a\rangle) |^2 = | \gamma \langle x|a\rangle|^2 = |\langle x|a\rangle|^2

これは、「相対位相」として知られている重ね合わせの項の間の位相差とは異なることに注意してください。これは、さまざまなタイプの測定と複数の量子ビットを考慮したときに重要になります。

#3 オブザーバー効果

振幅には、特定の状態の量子ビットを見つける確率に関する情報が含まれていますが、量子ビットを測定すると、量子ビットの状態が確実にわかります。 たとえば、以下のある状態の量子ビットを測定し、

q=α0+β1|q\rangle = \alpha|0\rangle + \beta|1\rangle

そして、状態0|0\rangleだと判明します。もう一度測定すると、状態0|0\rangleで量子ビットを見つける確率は100%です。 これは、測定する行為が、量子ビットの状態を 変化 させることを意味します。

q=[α β]Measure 0q=0=[1 0]|q\rangle = \begin{bmatrix} \alpha \ \beta \end{bmatrix} \xrightarrow{\text{Measure }|0\rangle} |q\rangle = |0\rangle = \begin{bmatrix} 1 \ 0 \end{bmatrix}

これを、量子ビットの状態の破壊と呼ぶことがあります。これは強力な効果であるため、賢明に使用する必要があります。たとえば、計算の各ポイントで値を追跡するために各量子ビットを常に測定していたら、それらは常に0|0\rangleまたは1|1\rangleのいずれかの明確に定義された状態であるだけしょう。そのため、それらは古典ビットと何ら変わりはなく、私たちの計算は古典計算に簡単に置き換えることができます。真の意味で、量子計算を実現するには、量子ビットがより複雑な状態を探索できるようにする必要があります。したがって、測定は、出力を取り出す必要がある場合にのみ行われます。よって、一般に測定を量子回路の最後に測定を配置することが多いです。

Qiskitのstatevectorシミュレーターを使用してこれを実証できます。重ね合わせで量子ビットを初期化しましょう:

qc = QuantumCircuit(1) # We are redefining qc initial_state = [0.+1.j/sqrt(2),1/sqrt(2)+0.j] qc.initialize(initial_state, 0) qc.draw()
Image in a Jupyter notebook

これにより、量子ビットが次の状態で初期化されます:

q=i20+121|q\rangle = \tfrac{i}{\sqrt{2}}|0\rangle + \tfrac{1}{\sqrt{2}}|1\rangle

これはシミュレーターを使用して確認できます。

qc.save_statevector() result = sim.run(assemble(qc)).result() state = result.get_statevector() print("Qubit State = " + str(state))
Qubit State = [0. +0.70710678j 0.70710678+0.j ]

ここで、量子ビットが[0.+0.70710678j 0.70710678+0.j]の状態で初期化されていることがわかります。これは、私たちが期待した状態です。

では、この量子ビットを測定する回路を作りましょう。

qc = QuantumCircuit(1) # We are redefining qc initial_state = [0.+1.j/sqrt(2),1/sqrt(2)+0.j] qc.initialize(initial_state, 0) qc.measure_all() qc.save_statevector() qc.draw()
Image in a Jupyter notebook

この回路全体をシミュレートすると、振幅の1つが 常に 0であることがわかります。

qobj = assemble(qc) state = sim.run(qobj).result().get_statevector() print("State of Measured Qubit = " + str(state))
State of Measured Qubit = [0.+0.j 1.+0.j]

このセルを数回再実行して、量子ビットを再初期化し、再び測定することができます。0と1どちらの結果も同じ確率で起こり得ますが、量子ビットの状態が0|0 \rangle1|1\rangleの重ね合わせになることはありません。興味深いことに、状態0 rangle|0\ rangle のグローバル位相は生き残りますが、これはグローバル位相であるため、実際の量子コンピューターで測定することはできません。

量子シミュレーターに関する注意

量子ビットの状態を書き留めるには、2つの複素数を追跡する必要があることがわかりますが、実際の量子コンピューターを使用する場合、各量子ビットについて、「はい」または「いいえ」( 0または1)の回答しか受け取りません。 10量子ビット量子コンピューターの出力は次のようになります。

0110111110

わずか10ビット、重ね合わせや複素振幅もありません。実際の量子コンピューターを使用する場合、量子ビットが破壊されてしまうため、計算の途中でその状態をみることはできません。この動作は学習には理想的ではないため、Qiskitはさまざまな量子シミュレーターを提供しています。デフォルトでは、 aer_simulatorは実際の量子コンピューターの実行を模倣しますが、回路に特定の命令を含めると、測定前に量子状態を確認することもできます。たとえば、命令.save_statevector()を含めると、シミュレーションの結果に.get_statevector()が使用できます。

3. ブロッホ球

3.1 制限された量子ビット状態の説明

この章の前半で、量子ビット(q|q\rangle)の一般的な状態は次のとおりであることを確認しました。

q=α0+eiϕβ1|q\rangle = \alpha|0\rangle + e^{i\phi}\beta|1\rangleα,βC\alpha, \beta \in \mathbb{C}

(2行目は、α\alphaβ\betaが複素数であることを示しています)。 セクション2の最初の2つの意味は、これらの状態のいくつかを区別できないことを示しています。 これは、量子ビットの説明をより具体的にできることを意味します。

まず、グローバルな位相を測定できないため、状態0|0\rangle1|1\rangleの間の位相の差しか測定できません。 α\alphaβ\betaを複素数にする代わりに、実数として制限し、それらの間の相対的な位相を示す項を追加することができます。

q=α0+eiϕβ1|q\rangle = \alpha|0\rangle + e^{i\phi}\beta|1\rangleα,β,ϕR\alpha, \beta, \phi \in \mathbb{R}

最後に、量子ビット状態は正規化する必要があるため、

α2+β2=1\sqrt{\alpha^2 + \beta^2} = 1

三角関数の性質を使用できます。

sin2x+cos2x=1\sqrt{\sin^2{x} + \cos^2{x}} = 1

実際のα\alphaβ\betaを1つの変数θ\thetaで説明すると、

α=cosθ2,β=sinθ2\alpha = \cos{\tfrac{\theta}{2}}, \quad \beta=\sin{\tfrac{\theta}{2}}

これから、2つの変数ϕ\phiθ\thetaを使用して、量子ビットの状態を説明できます。

q=cosθ20+eiϕsinθ21|q\rangle = \cos{\tfrac{\theta}{2}}|0\rangle + e^{i\phi}\sin{\tfrac{\theta}{2}}|1\rangleθ,ϕR\theta, \phi \in \mathbb{R}

3.2 量子ビットの状態を視覚的に表現する

一般的な量子ビット状態をプロットします。

q=cosθ20+eiϕsinθ21|q\rangle = \cos{\tfrac{\theta}{2}}|0\rangle + e^{i\phi}\sin{\tfrac{\theta}{2}}|1\rangle

θ \thetaϕ\phi を球座標として解釈すると(量子ビットの状態の大きさは11であるためr=1r = 1)、ブロッホ球と呼ばれる球の表面に任意の単一量子ビットの状態をプロットすることができます。

以下では、状態+|{+}\rangleの量子ビットをプロットしました。 この場合、θ=π/2\theta = \pi/2およびϕ=0\phi = 0です。

(Qiskitにはブロッホ球をプロットする関数 plot_bloch_vector()がありますが、これを書いている時点では、デカルト座標しかとっていません。自動的に変換を行う関数が含まれています。)

また、インタラクティブなブロッホ球のデモを試すこともできます。

from qiskit_textbook.widgets import plot_bloch_vector_spherical coords = [pi/2,0,1] # [Theta, Phi, Radius] plot_bloch_vector_spherical(coords) # 球面座標を持つブロッホベクトル
Image in a Jupyter notebook

注意!

量子ビットの状態について初めて学習するとき、量子ビットの 状態ベクトルブロッホベクトル を混同しやすいです。 状態ベクトルは 1.1 で解かれたベクトルであり、量子ビットが存在できる2つの状態の振幅を保持します。ブロッホベクトルは、2次元の複素数の状態ベクトルを実際の3次元空間にマッピングする視覚化ツールです。

練習問題

plot_bloch_vector()またはplot_bloch_sphere_spherical()を使って以下の状態の量子ビットをプロットしてください。

  1. 0|0\rangle

  2. 1|1\rangle

  3. 12(0+1)\tfrac{1}{\sqrt{2}}(|0\rangle + |1\rangle)

  4. 12(0i1)\tfrac{1}{\sqrt{2}}(|0\rangle - i|1\rangle)

  5. ParseError: KaTeX parse error: Undefined control sequence: \1 at position 36: …begin{bmatrix}i\̲1̲\end{bmatrix}

plot_bloch_vector()で使用するために、球座標からデカルト座標に変換するウィジェットも以下に含めました。

from qiskit_textbook.widgets import bloch_calc bloch_calc()
import qiskit.tools.jupyter %qiskit_version_table