common.title

Overview
Service overview
Terms of service

Privacy policy

Contact

Sign in
Sign up
common.title

Rigettiで位相キックバック回路

Yuichiro Minato

2021/04/24 16:09

#量子ゲート #位相キックバック

量子コンピュータ業界はFTQCと呼ばれる誤り訂正ありの量子コンピュータへと向かい始めました。ここでは、FTQCのうち、暗号解読や量子化学計算などに利用される量子位相推定アルゴリズムを取り上げますが、その前段階として位相キックバックと呼ばれるテクニックを実機で確認します。

https://github.com/Blueqat/Blueqat-tutorials/blob/master/tutorial-ja/120_phase_kick_back_ja.ipynb

こちらのチュートリアルを参考とします。

量子コンピュータの文脈でたびたび出現する固有値問題ですが、ユニタリゲートUUと対応する固有値は、位相θ\thetaをもちいて、固有値ψ|\psi\rangleとして、

Uψ=eiθψU|\psi\rangle = e^{i\theta}|\psi\rangle

今回はチュートリアルの例題に合わせて、ユニタリーゲートが下記のゲートの場合の固有値の位相を求めてみます。

U=[100eiθ]U = \begin{bmatrix}1 & 0\\ 0 & e^{i\theta}\end{bmatrix}

細かい内容は上記のチュートリアルを見てもらうと助かりますが、固有状態は1|1\rangleで既知であるとして、解てみます。

位相キックバックでは制御Uゲートを準備します。

|0> --H--*--H--測定
         |
|1> -----U-----

出力の回路を重ね合わせで準備し、入力の回路に固有状態を入力します。そして、制御ユニタリを利用して位相キックバックを行います。位相キックバックされた後の量子状態は|1>の出現確率は位相でしか見れないので、位相情報を取り出す必要があります。今回は1量子ビットの量子フーリエ変換に対応するHゲートを適用します。

最終的に、Hゲートを適用した後の出力量子ビットの状態ベクトルは、

ψ0=12[1+eiθ1eiθ]|\psi_0\rangle = \frac{1}{2}\begin{bmatrix}1+e^{i\theta}\\1-e^{i\theta}\end{bmatrix}

となりますので、位相は0もしくは1の出現確率をサンプルから求めることで三角関数の逆関数から位相を求めることができます。 早速実機を利用してみます。

まずはランダムな位相を決めて、シミュレータで解きます。

from blueqat import Circuit import numpy as np theta = np.random.rand()*np.pi shots = 1000 res = Circuit(2).x[1].h[0].cphase(theta)[0,1].h[0].m[0].run(shots = shots) p0 = res['00'] / shots theta_est = np.arccos(2 * p0 - 1) print("θ推定値  :", theta_est) print("実際の値 :", theta)
θ推定値  : 1.2387270042036784

実際の値 : 1.3008068934502068
res
Counter({'10': 337, '00': 663})

シミュレータですとサンプリングでも結構いい精度で出せましたね。次に実機を準備します。今回はbraketをつかってblueqat cloud経由でAPIをたたいてみます。

from braket.circuits import Circuit from braket.device_schema import GateModelParameters from braket.device_schema.rigetti import RigettiDeviceParameters from braket.device_schema.ionq import IonqDeviceParameters import json import urllib.request f = open('../.pass', 'r', encoding='UTF-8') API_KEY = f.read()[:-1] f.close() API_ENDPOINT = "https://cloudapi.blueqat.com/v2/" def post_request(path, body): headers = { "Content-Type": "application/json", "X-Api-Key": API_KEY, } req = urllib.request.Request( API_ENDPOINT + path, json.dumps(body).encode(), headers ) with urllib.request.urlopen(req) as res: body = res.read() return json.loads(body) def get_quantum_tasks(body): path = "quantum-tasks/list" return post_request(path, params) def get_quantum_task_status(id): path = "quantum-tasks/get/status" body = { "id": id, } return post_request(path, body) def get_quantum_task(id): path = "quantum-tasks/get" body = { "id": id, } return post_request(path, body) def create_quantum_task(body): path = "quantum-tasks/create" return post_request(path, body) #circuit circuit = Circuit().x(1).h(0).cphaseshift(0, 1, theta).h(0) paradigm_parameters = GateModelParameters( qubitCount=circuit.qubit_count, disableQubitRewiring=False ) # rigetti dprig = RigettiDeviceParameters(paradigmParameters=paradigm_parameters) dprig.json() params = { "action": circuit.to_ir().json(), "device": "aws/rigetti/Aspen-9", "deviceParameters": dprig.json(), "shots": 1000, "taskGroup": "", "sendEmail": False, } result = create_quantum_task(params)
tid = get_quantum_tasks({"index":0})['tasks'][0]['id'] res = get_quantum_task(tid) a = res['result']['measurements'] b = [] for i in a: b.append("".join(map(str, i))) import collections c = collections.Counter(b) c
Counter({'00': 18, '11': 539, '01': 377, '10': 66})
p0_2 = c['01'] / 1000 theta_est2 = np.arccos(2 * p0_2 - 1) print("θ推定値  :", theta_est2) print("実際の値 :", theta)
θ推定値  : 1.8193475889282924

実際の値 : 1.3008068934502068

ある程度は計算できている気がしますが、全然違う答えが出ることも結構あります。。。実機での位相推定はIonQを今度はやってみたいと思います。以上です。

© 2024, blueqat Inc. All rights reserved