PennyLaneでサンプリングしてヒストグラムプロット(TIPS)


PennyLaneでのサンプリング

PennyLaneでは、以下の構文で量子回路出力をサンプリング出来ます。

return qml.sample(qml.PauliZ(0))

例えば以下のようになります。

import pennylane as qml
from pennylane import numpy as np

@qml.qnode(dev)
def circuit(params):
    for i in range(n_qubits):
        qml.Hadamard(wires=i)

    for i in range(n_qubits):
        qml.CNOT(wires=[i, (i + 1) % n_qubits])
        qml.RZ(2*params[1],wires=(i + 1) % n_qubits)        
        qml.CNOT(wires=[i, (i + 1) % n_qubits])

    for i in range(n_qubits):
        qml.RX(2*params[0], wires=i)
    return qml.sample(qml.PauliZ(0)), qml.sample(qml.PauliZ(1)), qml.sample(qml.PauliZ(2)), qml.sample(qml.PauliZ(3))

この場合は$Z \otimes Z \otimes Z \otimes Z$ をサンプリングします。
実行すると、戻り値は 量子ビット数×Shot数 の(+1,-1)の配列です。
このままだと使い勝手が悪いので、ヒストグラムを書くために、これを集計する必要があります。
今回はこのスクリプトを書いたので公開します。

集計スクリプト

ゴリ押しにもほどがありますが、とりあえず動きます。

def sample_to_counts(sample):
    n_qubits, n_shots = np.shape(sample)
    sample_bin = (1+sample)/2
    weights = [2**i for i in range(n_qubits)]
    sample_dec = np.average(sample_bin,axis=0,weights=weights)*np.sum(weights) # sum b_n*2^n
    sample_dec = sample_dec.astype('int8')
    u, freq = np.unique(sample_dec, return_counts=True) # count frequency
    counts=dict()
    for i,j in zip(u,freq):
        counts.setdefault(format(i, '0'+str(n_qubits)+'b'),j)
    for i in range (2**n_qubits):
        counts.setdefault(format(i, '0'+str(n_qubits)+'b'),0) # zero-padding
    return counts

やっていることとしては、

  • +1を1に、-1を0に置換
  • 2進数を10進数に変換(2^n重み付き和)
  • 集計する
  • dict型にまとめる

です。 出力は、

{'0000': 11,
'0001': 16,
'0010': 14,
'0011': 78,
'0100': 15,
'0101': 275,
'0110': 73,
'0111': 11,
'1000': 8,
'1001': 90,
'1010': 292,
'1011': 12,
'1100': 74,
'1101': 20,
'1110': 18,
'1111': 17}

このようになります。

ヒストグラム

params = [1.17809152, 0.39269362] #beta,gamma
sample = circuit(params)
counts = sample_to_counts(sample)

集計したものをヒストグラムにするには、

import matplotlib.pyplot as plt
plt.bar(counts.keys(), counts.values());
plt.xlabel('bitstrings');
plt.ylabel('counts');
plt.xticks(rotation=90);

ちゃんとヒストグラムになっています。

ぶっちゃけ

PennyLaneを使った理由は、本SDKからならionqでもrigettiでもibmqでも何でも動かせるからだからでした。
ただ、blueqatが上記マシン全てに対応してしまったので、その意味はなくなりました。
blueqatのほうが使いやすいです。。
PennyLaneのよさは、自動微分ですかね・・・。

まとめ

qml.sampleからヒストグラムまでの道のりは意外と長い。