common.title

Docs
Quantum Circuit
TYTAN CLOUD

QUANTUM GAMING


Overview
Contact
Event
Project
Research

Terms of service (Web service)

Terms of service (Quantum and ML Cloud service)

Privacy policy


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:
      Successfully uninstalled blueqat-0.3.18
Successfully installed blueqat-0.4.1

機能の利用

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番目\otimes$0番目となること)に注意して、以下の記事を読んでください。

# 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

© 2025, blueqat Inc. All rights reserved