LoginSignup
7

More than 3 years have passed since last update.

1量子ビットVQEを世界一簡単に書く 2020年2月Ver.

Posted at

VQEを世界一簡単に書く1

VQEの解説記事が、最近、いろいろ世に出てきました。勉強された人なら、少しの試行錯誤で書けるでしょう。
けれど「もっと簡単に書きたい」と思う方も大勢いるかと思います。

私もそういうタイプで、その気持ちが強まりすぎたので、BlueqatにはVQEを世界一簡単に1書ける仕組みを用意しているのですが。
自分で言わないと誰も気づいてくれないので、記事を書きます。

HamiltonianとAnsatzさえあればいい

「何に対して答えを求めるか」は、ユーザが決めざるを得ないので、ハミルトニアンはユーザが作る必要があります。
また、とりあえずどんな回路になりそうかも、今はユーザに決めてもらっています。これはAnsatzと呼ばれます。

QAOA用のAnsatzなど、Blueqat側で用意しているAnsatzもあるのですが、問題に合わせてAnsatzを作ることになるかと思います。
これはユーザに負担を強いることです。ごめんなさい、けど、簡単なので許して下さい。

というわけで、今回は、1量子ビットのVQEを世界一簡単に1書いてみます。

Hamiltonianは、blueqat.pauliから作れる

ごっつ簡単です。blueqat.pauliを使えば、

from blueqat.pauli import X, Y, Z, I

h = 1.23 * I - 4.56 * X(0) + 2.45 * Y(0) + 2.34 * Z(0)

のように、積和の形で書けます。

乱数を使って、ランダムにHamiltonianを作ってみる

今回、何か特別に解きたいハミルトニアンがあるわけではないので、乱数を使ってハミルトニアンを作ってみましょう。

from random import random
from blueqat.pauli import X, Y, Z, I

h = random() * I + random() * X(0) + random() * Y(0) + random() * Z(0)

できました。簡単ですね。

Ansatzはblueqat.vqe.AnsatzBaseを継承してget_circuitを実装すればできる

任意の1量子ビットを作るには、RYゲートとRZゲートを1回ずつ適用したら十分です。2
そのようなAnsatzを作ってみましょう。

from blueqat import Circuit
from blueqat.vqe import AnsatzBase

class OneQubitAnsatz(AnsatzBase):
    def __init__(self, hamiltonian):
        AnsatzBase.__init__(hamiltonian, 2) # 親クラスの__init__に、Hamiltonianとパラメータ数を渡す

    def get_circuit(self, params):
        # RYゲートとRZゲートを適用した回路を返す
        a, b = params
        return Circuit().ry(a)[0].rz(b)[0]

簡単ですね。

HamiltonianとAnsatzがあればVQEはできる

from blueqat.vqe import Vqe

h = random() * I + random() * X(0) + random() * Y(0) + random() * Z(0)
runner = Vqe(OneQubitAnsatz(h))
result = runner.run()

print('Result by VQE')
print(runner.ansatz.get_energy(result.circuit, runner.sampler))

runner = Vqe(OneQubitAnsatz(h)) で、さっき定義したAnsatzを作って、さらに、VQEを動かすためのrunnerを作っています。
result = runner.run() で、VQEを動かして、結果を得ることができます。

結果からエネルギーを取り出す処理は、恐らく、この記事で最難関でしょう。覚えないでコピペして下さい。3
runner.ansatz.get_energy(result.circuit, runner.sampler)

これで、エネルギーが取り出せました。ちょっと難しいけれど、まぁまぁ簡単ですね。

本当に答えあってるの? numpyで求めた固有値と比較してみよう

import numpy as np
# Hamiltonian to matrix
mat = h.to_matrix()
# Calculate by numpy
print('Result by numpy')
print(np.linalg.eigh(mat))

blueqat.pauliの機能で、Hamiltonianをto_matrix()によりnumpyのarrayに変換できます。4
変換したarrayから、numpyのnp.linalg.eighを使って固有値を求めることができます。

通しで実行してみよう

ソース全体はこんな感じ

from random import random
import numpy as np
from blueqat import Circuit
from blueqat.pauli import X, Y, Z, I
from blueqat.vqe import AnsatzBase, Vqe

class OneQubitAnsatz(AnsatzBase):
    def __init__(self, hamiltonian):
        super().__init__(hamiltonian, 2)

    def get_circuit(self, params):
        a, b = params
        return Circuit().ry(a)[0].rz(b)[0]


# Calculate by VQE
h = random() * I + random() * X(0) + random() * Y(0) + random() * Z(0)
runner = Vqe(OneQubitAnsatz(h))
result = runner.run()

print('Result by VQE')
print(runner.ansatz.get_energy(result.circuit, runner.sampler))

# Hamiltonian to matrix
mat = h.to_matrix()
# Calculate by numpy
print('Result by numpy')
print(np.linalg.eigh(mat))

実行結果はこんな感じ(乱数でHamiltonianを作っているので実行するたびに変わります)

Result by VQE
-0.7972144535545334
Result by numpy
(array([-0.7972159 ,  2.24607842]), array([[-0.41818368+0.j        , -0.90836249+0.j        ],
       [ 0.57016708+0.70712935j, -0.26248835-0.32554179j]]))

VQEで求まった固有値は-0.7972144535545334
numpyで求まった固有値(のうち、最小のもの)は-0.7972159
ほぼほぼ一致していることが確認できました。

まとめ

Blueqatを使えば世界一簡単に1VQEが書ける


  1. 当社比 

  2. 「パラメータ3ついるんじゃなかったっけ?」と思われた方もいるかもしれません。確かに、任意の1量子ビットを作るには、3つのパラメータが必要です。けれど、|0>から、任意の1量子ビット状態|Ψ>を作るには、2つのパラメータで十分です。ブロッホ球を思い浮かべてください。|0>状態なので、針は真上に向いています。それを、Z軸と垂直な、例えばY軸まわりにいくらか回転させて、続いてZ軸まわりにいくらか回転させれば、球上のどこにでも針を向けることができます。 

  3. これを書くのがあまりにも面倒であることを、Blueqat開発者は十分に理解しているので、今後、より簡単な形に改良するはずです。 

  4. ただし、この処理は、量子ビット数が多いHamiltonianでは非常に重くなります。特に10量子ビットを越えてくると、待ちきれないほど待たされることになるかと思います。あくまで、小さめのHamiltonianのチェック用だとご理解ください。 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7