進捗のようなもの

やったこと書きます

Pythonで量子プログラミングやってみた

Pythonで触れられる色々な量子コンピュータSDKを紹介します。

ここでは、量子アルゴリズムであるグローバーアルゴリズムを量子ゲートで実装します。 2量子ビットで|11>を探索します。

今回、紹介するのはこれです。

理論、パッケージのインストールは紹介しないので、適宜他のページを参照してください。

Qiskit

IBMが開発した量子コンピュータSDKです。

無料のIBMQアカウントを登録すると実機の量子コンピュータを使って計算することもできます。

qiskit.org

パッケージのインポート

%matplotlib inline
import matplotlib.pyplot as plt
import numpy
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import Aer, execute
from qiskit.visualization import plot_histogram

グローバーアルゴリズムを実装

# 量子ビット、古典ビットの準備
qr = QuantumRegister(2)
cr = ClassicalRegister(2)

# 量子回路初期化
qc = QuantumCircuit(qr,cr)

# オラクル(|11>を反転)
qc.h(qr)
qc.cz(qr[0],qr[1])
qc.h(qr)

# 振幅増幅
qc.x(qr)
qc.cz(qr[0],qr[1])
qc.x(qr)
qc.h(qr)

# 測定
qc.measure(qr,cr)

量子回路の表示

qc.draw(output='mpl')

f:id:SJSY:20190929193010p:plain

シミュレーション結果

simulator  = Aer.get_backend('qasm_simulator')
result = execute(qc, simulator, shots=10000).result()
result.get_counts()

{'11': 10000}

plot_histogram(result.get_counts())

f:id:SJSY:20190929193005p:plain

グローバーアルゴリズムで解を得ることができました。

実機の量子コンピュータで計算

計算を実行するにはIBMQアカウント(無料)の設定が必要です。

from qiskit import IBMQ
from qiskit.providers.ibmq import least_busy

IBMQ.load_account()
provider = IBMQ.get_provider(group='open')
backend_lb = least_busy(provider.backends(simulator=False, operational=True))
print("Least busy backend: ", backend_lb)

Least busy backend: ibmq_16_melbourne

from qiskit.tools.monitor import job_monitor

backend = backend_lb
shots = 1024
job_exp = execute(qc, backend=backend, shots=shots)

job_monitor(job_exp, interval = 2)

Job Status: job has successfully run

results = job_exp.result()
answer = results.get_counts(qc)
plot_histogram(answer)

f:id:SJSY:20190929194400p:plain

実機でも|11>が最も確率が高くなっており、グローバーアルゴリズムで解が得られていることがわかります。 確率が1ではないのは、ノイズの影響と考えられます。

Blueqat

日本の量子コンピュータベンチャーのMDRが開発した量子コンピュータシミュレータです。

github.com

日本語でのチュートリアルが充実しています。 github.com

パッケージのインポート

from blueqat import Circuit

グローバーアルゴリズムを実装

# 量子回路初期化
qc = Circuit(2)

# オラクル(|11>を反転)
qc.h[:].cz[0, 1].h[:]

# 振幅増幅
qc.x[:].cz[0, 1].x[:].h[:]

# 測定
qc.m[:]

回路の実装コードが短いのが特徴だと思います。

量子回路の表示

表示機能はなさそう。

シミュレーション結果

qc.run(shots=10000)

Counter({'11': 10000})

import numpy as np

labels , values = zip(*qc.run(shots=10000).items())

indexes = np.arange(len(labels))
width = 0.3
plt.bar(indexes, values, width)
plt.xticks(indexes, labels)

f:id:SJSY:20190929203717p:plain

グローバーアルゴリズムで解を得ることができました。

Cirq

Googleが開発した量子コンピュータシミュレータです。

github.com

パッケージのインポート

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

from cirq import LineQubit, Circuit, Simulator, measure
import cirq

グローバーアルゴリズムを実装

# 量子回路初期化
qr = [LineQubit(i) for i in range(2)]
qc = Circuit()

# 量子回路
qc = qc.from_ops(
    # オラクル(|11>を反転) 
    cirq.H(qr[0]),
    cirq.H(qr[1]),
    cirq.CZ(qr[0],qr[1]),
    cirq.H(qr[0]),
    cirq.H(qr[1]),
    
    # 振幅増幅
    cirq.X(qr[0]),
    cirq.X(qr[1]),
    cirq.CZ(qr[0],qr[1]),
    cirq.X(qr[0]),
    cirq.X(qr[1]),
    cirq.H(qr[0]),
    cirq.H(qr[1]),   

    # 測定 
    cirq.measure(qr[0], key='m0'),
    cirq.measure(qr[1], key='m1'),
)

量子回路の表示

qc
0: ───H───@───H───X───@───X───H───M('m0')───
        │           │
1: ───H───@───H───X───@───X───H───M('m1')───

シミュレーション結果

simulator = cirq.Simulator()
result = simulator.run(qc, repetitions=10000)
result.histogram(key=['m0'])

Counter({1: 10000})

result.histogram(key='m1')

Counter({1: 10000})

グローバーアルゴリズムで解を得ることができました。

感想

個人的にはQiskitが機能そろってて、使いやすい印象です。