Qiskit 状態図示いろいろ


[前回](https://qiita.com/tare_/items/0753a977de9d8d3348a2)は量子ゲートについて紹介したので，今回はそれによって生成された状態がどのようなものであるかを視覚的に表現する方法について見てみます．

# Blochベクトル
まずは１量子ビットの適当な回路を作ってみます．
```python
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_bloch_multivector

# 1つの量子ビットを持つ量子回路を作成
circ = QuantumCircuit(1)

# 量子ビット0にアダマールゲートを適用
circ.h(0)

# 量子回路の描画（matplotlibを使用）
circ.draw('mpl')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887541/49a8d5db-3586-272c-89cf-d5842e49a070.png)


この回路によって生成された状態のBlochベクトル表示は，`plot_bloch_multivector`を用います．
```python
# 量子回路の状態ベクトルを計算
state = Statevector(circ)

# Bloch球面上に状態ベクトルを可視化
plot_bloch_multivector(state)
```
![ンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887541/80b08685-f89f-00c1-73da-a3ac0c74a5a7.png)

確かにアダマールゲートが作用した後の状態になっています．しれっと，`QuantumCircuit`であった`circ`を`Statevevotr`である`state`に変えています．

複数の量子ビットが存在する場合についても対応しています．
```python
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_bloch_multivector
import numpy as np

# 3つの量子ビットを持つ量子回路を作成
circ = QuantumCircuit(3)

# 量子ビット0と1に制御Zゲート（CZ）を適用
circ.cz(0, 1)

# 量子ビット1にRXゲートを適用
circ.rx(np.pi / 2, 1)

# 量子ビット1と2にRYYゲートを適用
circ.ryy(np.pi / 6, 1, 2)

# 量子ビット0と2にRZXを適用
circ.rzx(np.pi / 8, 0, 2)

# 量子ビット0と1にRXXを適用
circ.rxx(np.pi / 8, 0, 1)

# 量子ビット0と2にRZXを再度適用
circ.rzx(np.pi / 4, 0, 2)

# 量子ビット0と1にRXXを再度適用
circ.rxx(np.pi / 4, 0, 1)

# 量子回路の状態ベクトルを計算
state = Statevector(circ)

# Bloch球面上に状態ベクトルを可視化
plot_bloch_multivector(state)
```
![ダウンロ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887541/71f121db-e7fa-a3c0-c8c9-fa10149b5ec6.png)

ここで，それぞれのブロッホベクトルは部分トレースをとったものに対応していることに注意してください．
$$
\rho_{1} := \operatorname{Tr}_{23} (\rho _ {123})
$$
３量子ビットがエンタングルしているため，部分トレースをとった後の状態が混合状態となってしまっていることが，ブロッホベクトルの長さから理解できます．

# 密度演算子の成分をヒストグラム表示
これも１量子ビットの場合からコードを見てみます．
```python
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import DensityMatrix
from qiskit.visualization import plot_state_city

# 1つの量子ビットを持つ量子回路を作成
circ = QuantumCircuit(1)

# 量子ビット0にアダマールゲートを適用
circ.h(0)

# 量子回路の状態密度行列を計算
state = DensityMatrix(circ)

# 状態の都市プロットを生成し、色を指定
plot_state_city(state, color=['midnightblue', 'crimson'])
```
以下が出力結果です．
![dens.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887541/f0c7afb3-323c-71f7-e1da-8055aa9db10c.png)
アダマールゲートを作用させた後の密度演算子は，全ての行列要素が$1/2$のため，確かにそれが表現されていることが分かります[^2]．また，ここでも`QuantumCircuit`を`DensityMatrx`のクラスに変えています．

3量子ビットの場合は，以下のようになります．
```python
# 3つの量子ビットを持つ量子回路を作成
circ = QuantumCircuit(3)

# 量子ビット0と1に制御Zゲート（CZ）を適用
circ.cz(0, 1)

# 量子ビット1にRXゲートを適用
circ.rx(np.pi / 2, 1)

# 量子ビット1と2にRYYを適用
circ.ryy(np.pi / 6, 1, 2)

# 量子ビット0と2にRZXを適用
circ.rzx(np.pi / 8, 0, 2)

# 量子ビット0と1にRXXを適用
circ.rxx(np.pi / 8, 0, 1)

# 量子ビット0と2にRZXを再度適用
circ.rzx(np.pi / 4, 0, 2)

# 量子ビット0と1にRXXを再度適用
circ.rxx(np.pi / 4, 0, 1)

# 量子回路の状態密度行列を計算
state = DensityMatrix(circ)

# 状態の都市プロットを生成し、色を指定
plot_state_city(state, color=['midnightblue', 'crimson'])
```
![dens3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887541/4c5b8418-5c41-ab7c-df43-7d4d98c0ba4a.png)
圧巻ですね．２次元の表示の方が良い方は，`plot_state_hinton`を使うことも可能です．

```python
from qiskit.visualization import plot_state_hinton

# 状態のヒントンプロットを生成
plot_state_hinton(state)
```
![hinton.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887541/5c7bb66c-940e-cff6-9782-fea26bca5dff.png)

# 終わりに
今回は状態の図示について見ました．他の図示の仕方もあるので，気になる方は[ドキュメント](https://qiskit.org/documentation/apidoc/visualization.html#state-visualizations)をご覧ください．


#### Version Information
|Software|Version|
|---|---|
|qiskit|1.3.1|


||System information|
|---|---|
|Python version	|3.10.12|


[^2]:都市プロット？洒落てますね．