量子コンピュータ難民ガイド　-qiskit 1.0 で超基本的な量子回路をシュミュレータと実機で動かしてみる。-

趣味（半分弱仕事）で量子コンピュータを触っております。
量子力学を勉強しなおして、入門書をいくつか読んでさぁqiskitを動かそう！と思ったら最近qiskitがversion 1.0になり今までの記法がことごとくおじゃんになり検索してもあまり情報が出てこない状態に。あ、これpymicで経験したやつだ！（version 3.0でガラッと変わり今までの記法がすべておじゃんに）。　Migration guide https://docs.quantum.ibm.com/api/migration-guides/qiskit-runtime-from-ibm-provider
を読みながら、移住も何も僕最初から難民なんですけど（笑）と思いながら、あれやこれやさわっていたら動いたので、難民ガイドとしてここに記しておきます。

まず、何はともあれqiskitをインストールしてください。https://docs.quantum.ibm.com/start/install

端的にいうと、適当に仮想環境をpython 3.10以上で作ってそこにいつものやつと  qiskit と qiskit-ibm-runtime をぶち込むだけです。

```zsh
# 新しいConda環境を作成し、その環境名を'IQT'として、Pythonをインストールする
conda create -n IQT python

# 作成した'IQT'環境をアクティブにする
conda activate IQT

# Condaを使用して、Jupyter, JupyterLab, pandas, numpyをインストールする
conda install jupyter jupyterlab pandas numpy

# PIPを使用して、QiskitとQiskit IBM Runtimeをインストールする
pip install qiskit
pip install qiskit-ibm-runtim
```

あとIBM Quantum のアカウントを作ってTokenを入手しておきます。
ここを参考にしてください。
https://docs.quantum.ibm.com/start/setup-channel
なんか、　IBM cloudを使う場合とかあって混乱するですけどとりあえずIBM Quantumのアカウントつくっておけば間違い無いです。何らかしの理由でcloud使いたい人はそっちでも良いと思います。多分あんまかわりません。IBM Quamtum のtokeの取り方はかわらんので昔のやつを参考にしてください。
https://utokyo-icepp.github.io/qc-workbook/ja/prerequisites.html


この状態でjupyter labでもnotebookでも何でもよいので立ち上げます。
言い忘れましたが、量子コンピュータの基本はこのページが超わかりやすいです。https://www.r-staffing.co.jp/engineer/entry/20221202_1
今回の難民ガイドではこの第5回と最終回のスクリプトと基本同じものを動かすことをめざします。

まず、serviceの設定をします。多分、IBM Quantumへ入る入り口の設定みたいなもんです（知らんけど）。設定方法には2つあって、毎回設定させる方法と、記憶させておく方法があります。
多分どっちでもよいです。your-tokenでは上で取得したあなたのtokenをコピペしてください。

毎回設定しておくパターン

```python
from qiskit_ibm_runtime import QiskitRuntimeService
 
service = QiskitRuntimeService(channel="ibm_quantum", token='your-token')
```

で
記憶しておくパターンが

```python
from qiskit_ibm_runtime import QiskitRuntimeService
 
# Save an IBM Quantum account and set it as your default account.
QiskitRuntimeService.save_account(channel="ibm_quantum", token='your-token')
 
# Load saved credentials
service = QiskitRuntimeService()
```
となります。

続いて、モジュール読み込んで簡単な回路をつくります。

```python
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler
circuit = QuantumCircuit(2, 2) # 量子回路を初期化
# 量子回路の組み立て
circuit.h(0) # アダマール行列を適用
circuit.cx(0, 1) # CNOTを適用
# 測定
circuit.measure([0, 1], [0, 1])
```

次にこれがどんな回路か図をだします。

```python
circuit.draw(output='mpl')
```
なんか　mpl関係のモジュールがないよと怒られるかもしれません。画面を叩き割らず、大人しく指示にしたがってインストールしてください。
そうするとこんな感じの図が出るはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194156/ba06dc24-6b2d-4ce8-f105-2558986daad8.png)


さてここからが本題です。
Version1.0ではserviceのbackendを変えるだけでシュミレータと実機を使い分けることができます。使えるもののいちらんは以下のコマンドででます。

```python
#覚えさせいる前提
service = QiskitRuntimeService()
service.backends()

>>[<IBMBackend('simulator_mps')>,
 <IBMBackend('simulator_statevector')>,
 <IBMBackend('ibm_brisbane')>,
 <IBMBackend('ibm_kyoto')>,
 <IBMBackend('ibm_sherbrooke')>,
 <IBMBackend('ibmq_qasm_simulator')>,
 <IBMBackend('simulator_extended_stabilizer')>,
 <IBMBackend('simulator_stabilizer')>,
 <IBMBackend('ibm_osaka')>]
 ```
 という感じで使えるバックエンド一覧がでてきます。
 とりま、シュミレータをつかってみましょう。

 ```python
 #実行と結果取得
from qiskit.primitives import BackendSampler
#backend = Aer.get_backend('qasm_simulator')
service = QiskitRuntimeService()
 backend = service.backend("ibmq_qasm_simulator")

sampler = BackendSampler(backend)
#sampler = Sampler(backend)
job = sampler.run([circuit])
result = job.result()

print(result)
SamplerResult(quasi_dists=[{0: 0.49325, 3: 0.50675}], metadata=[{'shots': 4000}])
 ```

 こんな感じです。
 シュミレータなので、ミスはなく理想的な答えが返ってきます。あとVersion１からビットの書き方が変わっているようにおもいます。|00>が0で|11>が3になっています（以前は|00>が00で|11>が11でまんまだった）

 次に実機を使っていきます。
 まずはシュミレータじゃないやつを調べて、その中で一番空いてるやつを使いましょう

```python
#実機で5bit以上のやつら、
service.backends(simulator=False, operational=True, min_num_qubits=5)
>>[<IBMBackend('ibm_brisbane')>,
 <IBMBackend('ibm_kyoto')>,
 <IBMBackend('ibm_sherbrooke')>,
 <IBMBackend('ibm_osaka')>]

#シュミレータじゃなくて一番空いているやつ。今回は2bitなのでビットの指定なし。
service.least_busy(simulator=False)
>><IBMBackend('ibm_osaka')>
```

大阪が一番空いているっぽいですね。ではこの情報をつかって実機を動かみましょう。

```python3
#実行と結果取得
from qiskit.primitives import BackendSampler
#backend = Aer.get_backend('qasm_simulator')
service = QiskitRuntimeService()
#ここで実機を設定している。
backend = service.least_busy(simulator=False)

sampler = BackendSampler(backend)
#sampler = Sampler(backend)
job = sampler.run([circuit])
result = job.result()

result
>>SamplerResult(quasi_dists=[{0: 0.46625, 2: 0.029, 1: 0.017, 3: 0.48775}], metadata=[{'shots': 4000}])

```

おお！でちゃいけないはずの|01>と|10>が出てきています（1,2がでているということです。）実機のの匂いがします(笑）

最後に可視化してみます。

```python
from qiskit.visualization import plot_distribution

plot_distribution(result.quasi_dists)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194156/0dac17c7-608b-a883-f321-d11fbc35da49.png)