common.title

Overview
Service overview
Terms of service

Privacy policy

Contact

Sign in
Sign up
common.title

Blueqat 0.4.1の状態ベクトル指定機能を使った量子テレポーテーション

gyu-don

2021/03/11 03:21

1

Blueqat 0.4.1の状態ベクトル指定機能について

Blueqat 0.4.1では(ようやく)任意の初期状態を指定して回路を動かせるようになりました。例えば次のように使うことができます。

Blueqatのアップデート

Blueqatの旧バージョンがインストールされている場合は、次のようにアップデートします。

!pip install -U blueqat
Collecting blueqat

  Downloading blueqat-0.4.1-py3-none-any.whl (60 kB)

     |████████████████████████████████| 60 kB 577 kB/s eta 0:00:011

[?25hRequirement already satisfied, skipping upgrade: scipy>=1.1.0 in /opt/conda/lib/python3.8/site-packages (from blueqat) (1.4.1)

Requirement already satisfied, skipping upgrade: numpy~=1.12 in /opt/conda/lib/python3.8/site-packages (from blueqat) (1.19.1)

ERROR: openfermionblueqat 0.2.2 has requirement blueqat~=0.3.3, but you'll have blueqat 0.4.1 which is incompatible.

Installing collected packages: blueqat

  Attempting uninstall: blueqat

    Found existing installation: blueqat 0.3.18

    Uninstalling blueqat-0.3.18:

機能の利用

runの引数にinitial=vecのように初期ベクトルを指定することで、指定された初期ベクトルから計算を始めることができます。

import numpy as np from blueqat import Circuit # まずは、普通に動かす c = Circuit().h[0].m[0] c.run(shots=100) # => 0と1が50%ずつ
Counter({'0': 49, '1': 51})
# 状態ベクトルvec = (|0> - |1>)/√2 を用意 vec = np.array([1, -1]) / np.sqrt(2) # 回路cに状態ベクトルvecを指定→vecにアダマールゲートをかけると、1のみが測定される c.run(shots=100, initial=vec)
Counter({'1': 100})

次元の一致

状態ベクトルの大きさは、回路の2 ^ 量子ビット数になっている必要があります。また、状態ベクトルが正規化されていることをblueqat側では確認していませんが、正規化されていない場合、測定などの動作が予期しない結果となることがあるので、正規化されたベクトルを利用することを推奨します。

# 次元が合わないとエラーになります c.x[3].run(shots=100, initial=np.array([1, 0, 0, 0]))
# 正規化はblueqat側では確認していません。正規化されていることを確認するには、以下のようにします。 # True: 正規化されている np.allclose(np.vdot(vec, vec), 1)
True
# False: 正規化されていない vec2 = np.array([1, 1]) np.allclose(np.vdot(vec2, vec2), 1)
False

量子回路を動かした結果を、別の回路に入力する

初期状態ベクトルはnumpyなどで作ることもできますが、blueqat回路の計算結果を流用することもできます。その際、量子ビット数を合わせて回路を実行する必要があります。

# Circuit(2)のようにすることで、1量子ビットしかないc1も2量子ビットで計算を行います c1 = Circuit(2).x[0] c2 = Circuit(2).x[1] c2.run(initial=c1.run())
array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])

量子テレポーテーション

blueqatは、量子ビットのクロネッカー積を取る際、右から順にかけられていること(2番目\otimes1番目\otimes0番目となること)に注意して、以下の記事を読んでください。

# AliceとBobは、ベル状態を共有しています bell = Circuit().h[0].cx[0, 1].run() bell
array([0.70710678+0.j, 0.        +0.j, 0.        +0.j, 0.70710678+0.j])
# これをテレポーテーションします psi = np.array([np.cos(0.4), 1j*np.sin(0.4)]) psi
array([0.92106099+0.j        , 0.        +0.38941834j])
# 系全体としては、bellとpsiのクロネッカー積を取った状態となります state = np.kron(bell, psi) state
array([0.65128847+0.j        , 0.        +0.27536035j,

       0.        +0.j        , 0.        +0.j        ,

       0.        +0.j        , 0.        +0.j        ,

       0.65128847+0.j        , 0.        +0.27536035j])
# Alice側: 量子テレポーテーションの回路 alice = Circuit(3).cx[0, 1].h[0].m[0, 1] # 状態ベクトルとショットの両方を取得します vec, shot = alice.run(returns="statevector_and_shots", shots=1, initial=state) vec, shot
(array([0.        +0.j        , 0.        +0.j        ,

        0.        +0.j        , 0.        -0.38941834j,

        0.        +0.j        , 0.        +0.j        ,

        0.        +0.j        , 0.92106099+0.j        ]),

 Counter({'110': 1}))
# Alice→Bobに測定結果を伝えます measured = shot.most_common()[0][0] measured
'110'
# Bob側: 量子テレポーテーションの回路 bob = Circuit(3) if measured[0] == '1': bob.x[2] if measured[1] == '1': bob.z[2] # Aliceが測定した続きから、Bobが測定をします result = bob.run(initial=vec) result
array([ 0.        +0.j        ,  0.        +0.j        ,

        0.        +0.j        ,  0.92106099+0.j        ,

       -0.        +0.j        , -0.        +0.j        ,

       -0.        +0.j        ,  0.        +0.38941834j])

Bobに状態ベクトルが転送されました。これを確認するには、この状態ベクトルが、テレポーテーションした状態psiとaliceが手元に持っている状態のクロネッカー積であることを見ればよいです。

alice_state = Circuit(2) if measured[0] == '1': alice_state.x[0] if measured[1] == '1': alice_state.x[1] expect = np.kron(psi, alice_state.run()) expect
array([0.        +0.j        , 0.        +0.j        ,

       0.        +0.j        , 0.92106099+0.j        ,

       0.        +0.j        , 0.        +0.j        ,

       0.        +0.j        , 0.        +0.38941834j])
# 一致していることが分かります np.allclose(result, expect)
True

© 2024, blueqat Inc. All rights reserved