打率ハチワリの試験要綱読解～IBM量子開発者認定資格と開発ドキュメントとを結びつける(4)

## はじめに

このシリーズの記事では、量子コンピュータ関連の認定資格の一つであるIBM量子開発者認定資格"Fundamentals of Quantum Computation Using Qiskit v0.2X Developer"について、認定資格の試験要綱を元に出題されると思われる問題を想像し、Qiskitを学習するにあたって、開発ドキュメント上で参考になると思われるところの対応付けを試みます。

前回はIBM量子開発者認定資格の出題範囲である[Section 5](https://qiita.com/imh1104/items/ea87089c899e8d6e32ee)について開発ドキュメントとの対応付けを試みました。今回は、Section 6に対して、対応付けを試みます。このシリーズの記事では、これまで[Section 1](https://qiita.com/imh1104/items/ac2c3d0b92add77109e0)、[Section 9](https://qiita.com/imh1104/items/cb9fc19a31cd903eb6c2)、[Section 5](https://qiita.com/imh1104/items/ea87089c899e8d6e32ee)と対応付けを試みてきました。今回のSection 6で、IBM量子開発者認定資格の試験で出題されるトピックのうち83%をカバーすることとなり、ハチワリ越えになります。

今回、対応先の開発ドキュメントは、記事執筆時点(2024/3)で最新版のQiskit v1.4.2です。

## Section 6: Return the Experiment Resultsの出題トピック

[IBM Certified Associate Developer - Quantum Computation using Qiskit v0.2X](https://www.ibm.com/training/certification/ibm-certified-associate-developer-quantum-computation-using-qiskit-v02x-C0010300)からSection 6: Return the Experiment Resultsの出題トピックを見てみましょう。

| Section 5の出題トピック                                      | 日本語訳                                                     |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| 1. Return and understand the histogram data of an experiment | 1. 実験におけるヒストグラムデータを出力し、出力結果を理解する |
| 2. Return and understand the statevector of an experiment    | 2. 実験における状態ベクトルを出力し、出力結果を理解する      |
| 3. Return and understand the unitary of an experiment        | 3. 実験におけるユニタリを出力し、出力結果を理解する          |

## 試験要綱の読解と開発ドキュメントとの結びつけ
### Section 6：Return the Experiment Results

Section 6は、「Return the Experiment Results」です。Qiskit上でプログラムしたシミュレーションや実験の結果を出力する方法が出題範囲となっている点で、これまでの[Section 1](https://qiita.com/imh1104/items/ac2c3d0b92add77109e0)、[Section 9](https://qiita.com/imh1104/items/cb9fc19a31cd903eb6c2)、[Section 5](https://qiita.com/imh1104/items/ea87089c899e8d6e32ee)に比べて、より実践的な内容になっている印象を受けます。「実験結果を出力」するという言葉からも、量子ビットの状態を見える化する話題を扱った[Section 9](https://qiita.com/imh1104/items/cb9fc19a31cd903eb6c2)と重複するようなトピックもありますが、「実験の過程で見える化をする」というところに焦点があたっているようです。加えて、「状態ベクトル」や「ユニタリ」といった数学分野の単語があり、数学的な要素もあるSectionです。

####  1. 実験におけるヒストグラムデータを出力し、出力結果を理解する

ヒストグラム出力に関する話題は、開発ドキュメント中の下記ページが該当します。[Section 9](https://qiita.com/imh1104/items/cb9fc19a31cd903eb6c2)の[出題トピック2](https://qiita.com/imh1104/items/cb9fc19a31cd903eb6c2#2%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%83%92%E3%82%B9%E3%83%88%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E3%83%97%E3%83%AD%E3%83%83%E3%83%88%E3%81%99%E3%82%8B)と一緒ですね。

[plot_histogram (latest version) | IBM Quantum Documentation](https://docs.quantum.ibm.com/api/qiskit/qiskit.visualization.plot_histogram)

[visualize-results](https://docs.quantum.ibm.com/guides/visualize-results#plot-histogram-)

Section 9の記事を読んでいただいた方は、ヒストグラムを出力するインターフェースがQiskitにあるところまでは、知ることができたと思います。今回は、このインターフェースに指定できるパラメーターを見て、どういったヒストグラムを出力できるか覗いてみましょう。

##### qiskit.visualization.plot_histogram

```Python
qiskit.visualization.plot_histogram(data, figsize=None, color=None, number_to_keep=None, sort='asc', target_string=None, legend=None, bar_labels=True, title=None, ax=None, filename=None)
```

[qiskit/qiskit/visualization/counts_visualization.py at stable/1.4 · Qiskit/qiskit · GitHub](https://github.com/Qiskit/qiskit/blob/stable/1.4/qiskit/visualization/counts_visualization.py)

引数dataで指定した回数のデータをヒストグラムとしてプロットします。

**引数**

- ```data``` ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *or*[*dict*](https://docs.python.org/3/library/stdtypes.html#dict)) – 辞書型もしくリスト型でヒストグラム対象のデータを指定します。開発ドキュメントでは、```{量子ビット列：その量子ビット列を観測できた回数}```を指定する旨が例として、記載されています。この例では、```{'001': 130}```であれば、量子ビット列「001」を130回観測できたというデータを指定しています。
- ```figsize``` ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)) – 図の大きさをインチ単位で指定します。
- ```color``` ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *or*[*str*](https://docs.python.org/3/library/stdtypes.html#str)) – ヒストグラムの棒を塗りつぶす色を色名で指定します。
- ```number_to_keep``` ([*int*](https://docs.python.org/3/library/functions.html#int)) – ヒストグラムの棒の数のうち省略しない棒の数を指定します。例えば、2つの量子ビット列で観測できるビット列のパターンは4パターンありますので、ヒストグラムとしては、4つの棒を出力します。ただし、特に注目したいビット列のパターンがある場合、```2```を指定するとソート結果の先頭2つのパターンの観測回数が表示され、残り2パターンは、合算値となり「rest」と名前が付けられ、まとめられます。
- ```sort``` (*string*) – ヒストグラムの棒の並び順を指定します。並び順は、```asc```(昇順), ```desc```(降順), ```hamming```(ハミング距離), ```value```(観測回数),```value_desc```(観測回数降順)から指定します。```value```もしくは、```value_desc```を指定した場合、ヒストグラムのX座標の並び順は、ビット列の観測回数順になります。デフォルトは```asc```です。
- ```target_string``` ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – ヒストグラムの棒の並び順```sort```を```hamming```(各量子ビット列のハミング距離)としたときに、先頭にする量子ビット列を指定します。
- ```legend``` ([*list*](https://docs.python.org/3/library/stdtypes.html#list)) – ヒストグラムの棒の凡例を指定します。指定数は、ヒストグラムにするデータ列の数と同じにする必要があります。例えば、1回目の観測データと2回目の観測データをヒストグラムにする場合は、1回目の観測データ列と2回目の観測データ列の2つになりますので、凡例として指定する文字列は、1回目の観測データ列の凡例と2回目の観測データ列の凡例とで、2つの要素を持つ「リスト」型の変数を指定します。
- ```bar_labels``` ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – ヒストグラム中に、回数を表示するかしないかを指定します。```bar_labels```と言っているので、ヒストグラムの棒のラベルのことですが、開発ドキュメントでは、ヒストグラムにする際の使用するデータ形式が、```{量子ビット列：その量子ビット列を観測できた回数}```を前提としているのか、量子ビット列を観測できた回数の表示するかどうかといった具合に、量子コンピュータ分野に特化した説明がなされています。
- ```title``` ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – タイトルを指定します。ヒストグラムの上部エリアの```title```に指定した文字列が表示されます。
- ```ax``` ([*matplotlib.axes.Axes*](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes)) – このインターフェースでは指定できない細かな書式設定を指定します。指定可能な書式は、matplotlibの範囲となり、Qiskitの範囲から外れてしまいますので、この記事では割愛します。
- ```filename``` ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – ヒストグラムの保存先パスを指定します。

いかがでしょうか。ヒストグラムをプロットする機能があるとはいえ、観測された量子ビット列、観測回数というように量子コンピュータ上の実験結果を簡単に出力できるよう特化・最適化されたインターフェースになっています。Excelのグラフ機能でプロットするのとでは、違うことがわかります。特に、ハミング符号の距離を使ってQiskit側で並び替えができるのは、科学技術的なグラフの描画に特化しているという点では特徴的な仕様を備えていますね。

#### 2. 実験における状態ベクトルを出力し、出力結果を理解する

状態ベクトルの出力に関する話題は、開発ドキュメント中の下記ページが該当します。

[Statevector (latest version) | IBM Quantum Documentation](https://docs.quantum.ibm.com/api/qiskit/qiskit.quantum_info.Statevector)

もうちょっと深堀して、量子回路を作成→シミュレーターによる実験→実験結果として状態ベクトルとして出力する、という一連の流れを見てみましょう。開発ドキュメントの対応箇所は、下記です。

[Qiskit 1.0 feature migration guide | IBM Quantum Documentation](https://docs.quantum.ibm.com/migration-guides/qiskit-1.0-features#ccs-:R2jbcvfafasq:-tab-0)

API referenceではなく、Additional resourcesのMigration guidesということで、Qiskit 0.X系のAPIを用いて書かれたソースコードをQiskit1.X系へ移植する際のガイドの1つとして、状態ベクトルを出力するサンプルプログラムがあります。

```Python
from qiskit import QuantumCircuit

qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
 
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("statevector_simulator")
statevector = backend.run(qc).result().get_statevector()
 
# Current
qc.remove_final_measurements()  # no measurements allowed
from qiskit.quantum_info import Statevector
statevector = Statevector(qc)
```

このサンプルプログラムの量子回路は、

* 定義した3量子ビットのうち：
  * 1量子ビット目にアダマールゲートを作用させる
  * 2量子ビット目にアダマールゲートを作用させる
  * 2量子ビット目を作用させた結果と3量子ビット目をCXゲートで作用させる

という構造になっています。上記は、プログラムを読んだ通りの説明になりますが、量子の視点を入れると、「定義した3量子ビットのうち、1量子ビット目に、量子における重ね合わせの状態を作り出すアダマールゲートを作用させる、2量子ビット目と3量子ビット目において量子間でもつれ合いの関係を作る量子回路」と説明できます。

```#Previous```の部分は、Qiskit 1.X系になる前での状態ベクトルの取得処理で、

* 状態ベクトルのシミュレーターを指定
* シミュレーターを実行し、状態ベクトルを取得

という流れになっています。

```#Current```は、現在のメジャーリリース版であるQiskit 1.X系での状態ベクトルの取得処理で、

* 各量子ビットにおける最後の測定操作を削除
* Statevectorパッケージをインポート
* 状態ベクトルを取得

となっています。

では、実行してみましょう。サンプルプログラムでは、回路図を出力する処理と、状態ベクトルを出力する処理とがないので、回路図を出力する処理、状態ベクトルを出力する処理を追記し、```#Previous```の部分をコメントアウトの上、実行します。

```Python
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()

# Previous
# Qiskit 0.X系での状態ベクトル取得処理
#from qiskit import BasicAer
#backend = BasicAer.get_backend("statevector_simulator")
#statevector = backend.run(qc).result().get_statevector()
 
# Current
# Qiskit 1.X系での状態ベクトル取得処理
qc.remove_final_measurements()  # no measurements allowed
from qiskit.quantum_info import Statevector
statevector = Statevector(qc)

# 追加：状態ベクトルの出力
print(statevector)
# 追加：量子回路図の出力
qc.draw(output="text")
```

実行結果：

```
Statevector([0.5+0.j, 0.5+0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j, 0.5+0.j,
             0.5+0.j],
            dims=(2, 2, 2))
```

```
     ┌───┐     
q_0: ┤ H ├─────
     ├───┤     
q_1: ┤ H ├──■──
     └───┘┌─┴─┐
q_2: ─────┤ X ├
          └───┘
```

状態ベクトルと量子回路図が出力されました。

#### 3. 実験におけるユニタリを出力し、出力結果を理解する

量子回路のユニタリ出力に関する話題は、開発ドキュメント中の下記ページが該当します。

[Operators module overview | IBM Quantum Documentation](https://docs.quantum.ibm.com/guides/operators-overview#operator)

[Qiskit 1.0 feature migration guide | IBM Quantum Documentation](https://docs.quantum.ibm.com/migration-guides/qiskit-1.0-features#ccs-:R2jbcvfafasq:-tab-0)

サンプルプログラムは、[出題トピック2](#2.実験における状態ベクトルを出力し、出力結果を理解する)で取り上げたページと同じです。(リンク先の画面から「Unitary Simulator」のタブをクリックしてください。)

[Operators module overview | IBM Quantum Documentation](https://docs.quantum.ibm.com/guides/operators-overview#operator)には、「ユニタリ(Unitary)」というキーワードはありませんが、[出題トピック2](#2.実験における状態ベクトルを出力し、出力結果を理解する)で紹介した移植ガイドの「Unitary simulator」のサンプルプログラムと合わせて読むと、```Operator()```オブジェクトに量子回路のオブジェクトを渡して、```data```インスタンスにアクセスすると、指定した量子回路の「ユニタリ」が出力されるよう、コードが書かれています。[出題トピック2](#2.実験における状態ベクトルを出力し、出力結果を理解する)と同じ流れで、サンプルプログラムにユニタリを出力する処理を追加して実行してみます。今回は、```Operator()```オブジェクト中の```draw()```メソッドを使って、数式も表示してみます。

```Python
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
 
# Previous
# Qiskit 0.X系でのユニタリ出力処理
#from qiskit import BasicAer
#backend = BasicAer.get_backend("unitary_simulator")
#result = backend.run(qc).result()
 
# Current
# Qiskit 1.X系でのユニタリ出力処理
qc.remove_final_measurements()  # no measurements allowed
from qiskit.quantum_info import Operator
result = Operator(qc).data
# 追加：量子回路qcのユニタリを出力
print(result)
# 追加：量子回路qcのユニタリを数式で出力
Operator(qc).draw(output="latex")
```

```
[[ 0.5+0.j  0.5+0.j  0.5+0.j  0.5+0.j  0. +0.j  0. +0.j  0. +0.j  0. +0.j]
 [ 0.5+0.j -0.5+0.j  0.5+0.j -0.5+0.j  0. +0.j  0. +0.j  0. +0.j  0. +0.j]
 [ 0. +0.j  0. +0.j  0. +0.j  0. +0.j  0.5+0.j  0.5+0.j -0.5+0.j -0.5+0.j]
 [ 0. +0.j  0. +0.j  0. +0.j  0. +0.j  0.5+0.j -0.5+0.j -0.5+0.j  0.5+0.j]
 [ 0. +0.j  0. +0.j  0. +0.j  0. +0.j  0.5+0.j  0.5+0.j  0.5+0.j  0.5+0.j]
 [ 0. +0.j  0. +0.j  0. +0.j  0. +0.j  0.5+0.j -0.5+0.j  0.5+0.j -0.5+0.j]
 [ 0.5+0.j  0.5+0.j -0.5+0.j -0.5+0.j  0. +0.j  0. +0.j  0. +0.j  0. +0.j]
 [ 0.5+0.j -0.5+0.j -0.5+0.j  0.5+0.j  0. +0.j  0. +0.j  0. +0.j  0. +0.j]]
```

$$
\begin{bmatrix}
\frac{1}{2} & \frac{1}{2} & \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0  \\\\
\frac{1}{2} & - \frac{1}{2} & \frac{1}{2} & - \frac{1}{2} & 0 & 0 & 0 & 0 \\\\
0 & 0 & 0 & 0 & \frac{1}{2} & \frac{1}{2} & - \frac{1}{2} & - \frac{1}{2} \\\\
0 & 0 & 0 & 0 & \frac{1}{2} & - \frac{1}{2} & - \frac{1}{2} & \frac{1}{2} \\\\
0 & 0 & 0 & 0 & \frac{1}{2} & \frac{1}{2} & \frac{1}{2} & \frac{1}{2} \\\\
0 & 0 & 0 & 0 & \frac{1}{2} & - \frac{1}{2} & \frac{1}{2} & - \frac{1}{2} \\\\
\frac{1}{2} & \frac{1}{2} & - \frac{1}{2} & - \frac{1}{2} & 0 & 0 & 0 & 0 \\\\
\frac{1}{2} & - \frac{1}{2} & - \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0 \\\\
\end{bmatrix}
$$

量子回路qcの行列表現が出力されました。

なお「ユニタリ」は、線形代数学(連立方程式を行列を使って解くことから始まった理論体系)と呼ばれる数学の世界で使われる専門用語なので、説明は割愛しますが、量子回路の行列表現をしたいとなったとき、「ユニタリ」という性質を満たせば、量子回路の行列表現を求めることができる道具といったところです。

## まとめ

Section 6は、量子コンピュータ上における実験をプログラミングした後の、実験結果をQiskitで出力することが問われているようです。Qiskitには、[Section 9](https://qiita.com/imh1104/items/cb9fc19a31cd903eb6c2)の通り、出力結果を見える化する方法が本記事で取り上げた以外のものありますが、このセクションでは特に、

* 実験結果をヒストグラムとして表示([出題トピック1](#1.実験におけるヒストグラムデータを出力し、出力結果を理解する))
* 量子回路の状態ベクトルを表示する([出題トピック2](#2.実験における状態ベクトルを出力し、出力結果を理解する))
* 量子回路のユニタリを表示する([出題トピック3](#3.実験におけるユニタリを出力、出力結果を理解する))

の3点は最低限抑えておく必要がありそうです。[Section 5](https://qiita.com/imh1104/items/ea87089c899e8d6e32ee)から量子特有の項目が出てきて、Section 6では、数学的な要素が出てきているのも特徴的ですね。

今回の記事で参照先とした開発ドキュメントを表にして、今回の記事のまとめとさせていただきます。

| 出題トピック                                                 | 開発ドキュメント                                             |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| 1. 実験におけるヒストグラムデータを出力し、出力結果を理解する | [plot_histogram (latest version) \|IBM Quantum Documentation](https://docs.quantum.ibm.com/api/qiskit/qiskit.visualization.plot_histogram)<br />[visualize-results](https://docs.quantum.ibm.com/guides/visualize-results#plot-histogram-) |
| 2. 実験における状態ベクトルを出力し、出力結果を理解する      | [Statevector (latest version) \| IBM Quantum Documentation](https://docs.quantum.ibm.com/api/qiskit/qiskit.quantum_info.Statevector)<br />[Qiskit 1.0 feature migration guide \| IBM Quantum Documentation](https://docs.quantum.ibm.com/migration-guides/qiskit-1.0-features#ccs-:R2jbcvfafasq:-tab-0) |
| 3. 実験におけるユニタリを出力し、出力結果を理解する          | [Operators module overview \|IBM Quantum Documentation](https://docs.quantum.ibm.com/guides/operators-overview#operator)<br />[Qiskit 1.0 feature migration guide \|IBM Quantum Documentation](https://docs.quantum.ibm.com/migration-guides/qiskit-1.0-features#ccs-:R2jbcvfafasq:-tab-0) |

さて、冒頭の「[はじめに](#はじめに)」に書きました通り、この記事で、IBM量子開発者認定資格の試験で出題されるトピックと開発ドキュメントとの対応付けは、ハチワリを越えました。

この記事が本シリーズ、最後の記事となります。連載記事に対するフィードバックとして、記事に興味を持ってくださった方、いいねやストックしてくださった方がいらっしゃること、とても励みになります。これからも、役に立ちそうな情報を発信できるよう努めてまいりますので、どうぞよろしくお願いします。ありがとうございました。