Qiskit 1.0で量子計算

久しぶりにQiskitで遊ぼうと思って、Qiskit 0.43を使ったコードを動かしたところ、[IBM Quantum Platform](https://www.ibm.com/quantum)へジョブを投入できなくなっていることに気づきました。

せっかくの機会ということでQiskit 1.0.0を使ったコードに書き直したので、整理した内容を共有しようと思います。

1.0では、```from qiskit import execute, Aer, IBMQ```が使えなくなっているため、これらの置き換えが主な変化点となります。

## 0. 準備
#### ライブラリをインストール
関連するライブラリをインストールします。
今回はqiskit 1.0.2, qiskit_ibm_runtime 0.22.0を使用します。
```
pip -q install qiskit==1.0.2
pip -q install qiskit[visualization]==1.0.2
pip -q install qiskit_ibm_runtime==0.22.0
```

#### アカウント作成 / APIトークンの取得
※既にお持ちの場合はスキップで大丈夫です

https://www.ibm.com/jp-ja/quantum
1. こちらにアクセスして、アカウントを作成してログイン
1. ログインすると画面右上にAPI Tokenが表示されているので、コピーして手元にメモ

アカウント作成手順は、[こちら](https://qiita.com/kifumi/items/7ac33ab7939d2dd796d0)を参考にしました。


## 1. 量子回路の作成
ここは0.43と変わらず、同じコードで動きました。
```
from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

qc.draw('mpl')
```

Output:
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114213/49d256aa-1fa1-3909-1e81-1179b0ddb6df.png">

## 2. 回路情報の取得（状態ベクトル, ユニタリ行列)
作成した量子回路の状態ベクトルやユニタリ行列の取得手順です。１行で書けるようになったので、以前よりコードがシンプルになりました。

#### 状態ベクトル(State vector)
```
from qiskit.quantum_info import Statevector
statevector = Statevector(qc)
print(statevector)
```

Output:
Statevector([0.707+0.j, 0.   +0.j, 0.   +0.j, 0.707+0.j], dims=(2, 2))

#### ユニタリ行列(Unitary matrix)
```
from qiskit.quantum_info import Operator
matrix = Operator(qc)
print(matrix)
```

Output:
Operator([
　[ 0.707+0.j,  0.707+0.j,  0.   +0.j,  0.   +0.j ],
　[ 0.   +0.j,  0.   +0.j,  0.707+0.j, -0.707+0.j ],
　[ 0.   +0.j,  0.   +0.j,  0.707+0.j,  0.707+0.j ],
　[ 0.707+0.j, -0.707+0.j,  0.   +0.j,  0.   +0.j ]
], input_dims=(2, 2), output_dims=(2, 2))

## 3. 量子回路の実行
最後に、作成した量子回路の実行手順です。理想的な量子コンピュータシミュレーションを使った実行と、本物の量子コンピュータを使った実行について説明します。

#### 理想的な量子コンピュータシミュレーションを手元で実行
```
from qiskit.providers.basic_provider import BasicSimulator

backend = BasicSimulator()
result = backend.run(qc, shots=1000).result()
counts = result.get_counts()

print(counts)
```

Output:
※今回は1000 shotsで実行したので count(|00>) + count(|11>) =  1000)
{'11': 509, '00': 491}

Visualization:
```
from qiskit.visualization import plot_histogram
plot_histgram(counts)
```
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114213/dcba5ed0-a8f5-f963-011a-df498e5c0b10.png">

#### IBM Quantum Platformで実行
1. サービスに接続して、使用可能なバックエンド一覧を取得
   ```
   from qiskit_ibm_runtime import QiskitRuntimeService, Session, Sampler
  
   api_token = 手順の最初にメモしたAPI token
   service = QiskitRuntimeService(channel='ibm_quantum', token=api_token)
   service.backends()
   ```

2. バックエンドを選択し、作成し量子回路をトランスパイルして、計算を実行
   ```
   from qiskit import transpile
   
   ibm_backend = service.get_backend('ibm_kyoto')

   transpiled_qc = transpile(qc, ibm_backend)
   result = ibm_backend.run(transpiled_qc, shots=1000).result()
   counts = result.get_counts()

   print(counts)
   ```
   ※空いてるバックエンドならなんでもOKというときは
     ```ibm_backend = service.least_busy(operational=True)```
     と書いてもOKです

   
Output:
{'01': 32, '00': 456, '11': 489, '10': 23}

## まとめ
Qiskit 1.0.0を使ったコードについて説明しました
実は、qiskit-aerを使った方法やQiskit Runtimeを使う方法など、コード実装に色々なパターンがあるようなのですが、今回はシンプルなパターンでのコード実装に絞って記事にしてみました。
「とりあえず、Qiskitで遊んでみたい！」という方は、よければご参考ください。