Qiskitでヒストグラムを描画する(plot_histogram)

計算結果を可視化する手段としてヒストグラムは広く利用される。

Qiskitでヒストグラムをプロットするにはvisualizationモジュールに含まれるplot_histogram関数を使用する。

qiskit.visualization.plot_histogram — Qiskit 0.43.1 documentation

引数にはplot_histogram(Dict[str, int])のようにデータを辞書形式で与える。

from qiskit.visualization import plot_histogram

plot_histogram({'0': 898, '1': 126})

また、plot_histogram(List[Dict[str, int])のように複数のデータ群を与えることで複数のヒストグラムを並べて表示することもできる。

from qiskit.visualization import plot_histogram

plot_histogram(
    [
      {'00': 525, '11': 499},
      {'00': 511, '11': 514}
    ],
    legend=['First execution', 'Second execution'],
    color=['crimson','midnightblue'],
)

Qiskitで回路にバリアを設置する(qc.barrier)

Qiskitで回路にBarrierを設置するには、QuantumCircuitbarrierメソッドを使用する。

qiskit.circuit.QuantumCircuit.barrier — Qiskit 0.43.1 documentation

引数として、qc.barrier(int)のように設置対象の量子ビットを指定する。

from qiskit import QuantumCircuit

qc = QuantumCircuit(3, 3)
qc.barrier(1)

複数の量子ビットに渡るバリアを設置するには、qc.barrier(List[int])のようにリストで指定する。

qc = QuantumCircuit(3, 3)
qc.barrier([1, 2])

または、単にqc.barrier(int, int, ...)のように指定することも可。

qc = QuantumCircuit(3, 3)
qc.barrier(1, 2)

qc.barrier()のように引数を指定しないことで、回路中の全量子ビットに渡るバリアを設置することができる。

qc = QuantumCircuit(3, 3)
qc.barrier()

QiskitでQsphereをプロットする(plot_state_qsphere)

本記事では、QiskitでQsphereをプロットする方法について説明する。

Qsphereは量子状態の可視化方法の一つ。

他によく用いられる可視化方法としてブロッホ球がある。

ブロッホ球については以下の記事を参照。

happy-quantum.hateblo.jp

Qsphereもブロッホ球と同様に球面上に量子ビットの状態を表現する。

ブロッホ球に対して優位な点としては、位相も表現できることが挙げられる。

Qshpereでは、球上の点の大きさが状態に含まれる各項の重み(確率振幅の絶対値の2乗)に対応し、色が位相に対応する。

QiskitでQsphereをプロットするには、qiskit.visualizationパッケージに含まれるplot_state_qsphereを使用する。

qiskit.visualization.plot_state_qsphere — Qiskit 0.43.1 documentation

以下に例を挙げる。

例1:  |0\rangle

from qiskit.visualization import plot_state_qsphere

plot_state_qsphere([1.0, 0.0])

例2:  \frac1{\sqrt{2}}|00\rangle + \frac1{\sqrt{2}}|11\rangle

from qiskit.visualization import plot_state_qsphere
import numpy as np

plot_state_qsphere([1.0/np.sqrt(2.0), 0.0, 0.0, 1.0/np.sqrt(2.0)])

例3:  \frac12|00\rangle - \frac12|01\rangle + \frac12|10\rangle - \frac12|11\rangle

from qiskit.visualization import plot_state_qsphere

plot_state_qsphere([0.5, -0.5, 0.5, 0.5])

例4:  |\psi\rangle = \frac12|0\rangle - \frac{\sqrt{3}}{2}|1\rangle

from qiskit.visualization import plot_state_qsphere
import numpy as np

plot_state_qsphere([0.5, -0.5*np.sqrt(3)])

Qiskitでブロッホ球をプロットする(plot_bloch_vector、plot_bloch_multivector)

ブロッホ球は量子ビットの状態を視覚的に表現するツール。

https://qiskit.org/textbook/ch-states/representing-qubit-states.html#3.-The-Bloch-Sphere-

Qiskitでブロッホ球をプロットするにはVisualizationモジュールに含まれるplot_bloch_vectorまたはplot_bloch_multivectorを使用する。

plot_bloch_vector

単一量子ビットをプロットする場合はplot_bloch_vectorを使用する。

qiskit.visualization.plot_bloch_vector — Qiskit 0.43.1 documentation

デカルト座標で指定する場合は、plot_bloch_vector([double, double, double])の形式で引数にxyzの各座標を渡す。

また、任意で図のタイトルを指定することもできる。

from qiskit.visualization import plot_bloch_vector

plot_bloch_vector([0,1,0], title="New Bloch Sphere")

さらに、もともとは不可能だったが、極座標で指定することもできるようになった。

極座標で指定するには、plot_bloch_vector([double, double, double], coord_type='spherical')として r \theta \phiを指定する。

from qiskit.visualization import plot_bloch_vector
import numpy as np

plot_bloch_vector([1, np.pi/2, np.pi/3], coord_type='spherical')

plot_bloch_multivector

複数量子ビットの状態をそれぞれブロッホ球にプロットするには、plot_bloch_multivectorを使用する。

qiskit.visualization.plot_bloch_multivector — Qiskit 0.43.1 documentation

例えば状態 をプロットするには以下のようにする。

from qiskit.visualization import plot_bloch_multivector
import numpy as np

plot_bloch_multivector([1.0/np.sqrt(2.0), 0.0, 1.0/np.sqrt(2.0), 0.0])

Qiskitで量子回路の行列を確認する(unitary_simulator)

一般的に、量子ビットに対するゲート操作と、その集合である量子回路はユニタリ行列により表される。

Qiskitで量子回路の行列表現を確認するにはunitary_simulatorを使用する。

unitary_simulatorAerのバックエンドとして提供され、量子回路に対応する行列を出力することができる。

UnitarySimulator — Qiskit Aer 0.12.1 documentation

例えば以下のように、1つのアダマールゲート Hだけで構成される回路があるとする。

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.h(0)

qc.draw()

この行列表現は以下のように出力できる。

from qiskit import Aer, execute

job = Aer.get_backend('unitary_simulator').run(qc)

print(job.result().get_unitary())
# Operator([[ 0.70710678+0.00000000e+00j,  0.70710678-8.65956056e-17j], [ 0.70710678+0.00000000e+00j, -0.70710678+8.65956056e-17j]], input_dims=(2,), output_dims=(2,))

これは実際の値と一致する。

 H = \frac{1}{\sqrt{2}}\begin{pmatrix} 1&1\\1&-1\end{pmatrix}

または、以下のようにバックエンドのrunメソッドを使用することもできる。どちらも得られる結果は同じ。

from qiskit import Aer

job = execute(qc, Aer.get_backend('unitary_simulator'))

print(job.result().get_unitary())
# Operator([[ 0.70710678+0.00000000e+00j,  0.70710678-8.65956056e-17j], [ 0.70710678+0.00000000e+00j, -0.70710678+8.65956056e-17j]], input_dims=(2,), output_dims=(2,))

なお、量子ビット状態ベクトルを確認するstatevector_simulatorについては以下の記事を参照。

happy-quantum.hateblo.jp

また、回路の初期化方法については以下の記事を参照。

happy-quantum.hateblo.jp

Qiskitで状態ベクトルを確認する(statevector_simulator)

Qiskitで量子回路を構築した後、量子ビットがどのような状態になっているかを確認したい場合がある。

statevector_simulatorAerによりバックエンドとして提供され、量子ビットの状態を状態ベクトルとして出力することができる。

Simulators — Qiskit 0.43.1 documentation

qiskit.result.Result.get_statevector — Qiskit 0.43.1 documentation

例えば、0番目のビットにXゲートを作用させる X_0|00\rangle = |01\rangleを確認するには以下のようにする。

from qiskit import QuantumCircuit, Aer, execute

qc = QuantumCircuit(2)
qc.x(0)
 
job = execute(qc, Aer.get_backend('statevector_simulator'))
    
print(job.result().get_statevector())
# Statevector([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j], dims=(2, 2))

または、以下のようにバックエンドのrunメソッドを利用することもできる。 どちらも結果は同じ。

from qiskit import QuantumCircuit, Aer

qc = QuantumCircuit(2)
qc.x(0)
 
job = Aer.get_backend('statevector_simulator').run(qc)
    
print(job.result().get_statevector())
# Statevector([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j], dims=(2, 2))

なお、回路の行列表現を確認するunitary_simulatorについては以下の記事を参照。

happy-quantum.hateblo.jp

また、回路の初期化方法については以下の記事を参照。

happy-quantum.hateblo.jp

Qiskitで複合ゲートを分解する(qc.decompose)

Qiskitで回路に存在する複合ゲートを単一量子ビットゲートおよび2量子ビットゲートに分解するにはQuantumCircuitdecomposeメソッドを使用する。

https://qiskit.org/textbook/ja/ch-gates/more-circuit-identities.html

Advanced Circuits — Qiskit 0.43.1 documentation

qiskit.circuit.QuantumCircuit.decompose — Qiskit 0.43.1 documentation

例えば、トフォリゲートがあるとき

from qiskit import *

qc = QuantumCircuit(3)
qc.ccx(0, 1, 2)
qc.draw()

これを分解すると以下のようになる。

qc.decompose().draw()