Nobisuke
Dekisugi
RAG
Privacy policy
2021/04/24 16:09
量子コンピュータ業界はFTQCと呼ばれる誤り訂正ありの量子コンピュータへと向かい始めました。ここでは、FTQCのうち、暗号解読や量子化学計算などに利用される量子位相推定アルゴリズムを取り上げますが、その前段階として位相キックバックと呼ばれるテクニックを実機で確認します。
https://github.com/Blueqat/Blueqat-tutorials/blob/master/tutorial-ja/120_phase_kick_back_ja.ipynb
こちらのチュートリアルを参考とします。
量子コンピュータの文脈でたびたび出現する固有値問題ですが、ユニタリゲートと対応する固有値は、位相をもちいて、固有値として、
今回はチュートリアルの例題に合わせて、ユニタリーゲートが下記のゲートの場合の固有値の位相を求めてみます。
細かい内容は上記のチュートリアルを見てもらうと助かりますが、固有状態はで既知であるとして、解てみます。
位相キックバックでは制御Uゲートを準備します。
|0> --H--*--H--測定
|
|1> -----U-----
出力の回路を重ね合わせで準備し、入力の回路に固有状態を入力します。そして、制御ユニタリを利用して位相キックバックを行います。位相キックバックされた後の量子状態は|1>の出現確率は位相でしか見れないので、位相情報を取り出す必要があります。今回は1量子ビットの量子フーリエ変換に対応するHゲートを適用します。
最終的に、Hゲートを適用した後の出力量子ビットの状態ベクトルは、
となりますので、位相は0もしくは1の出現確率をサンプルから求めることで三角関数の逆関数から位相を求めることができます。 早速実機を利用してみます。
まずはランダムな位相を決めて、シミュレータで解きます。
Copy 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
Copy res
Counter({'10': 337, '00': 663})
シミュレータですとサンプリングでも結構いい精度で出せましたね。次に実機を準備します。今回はbraketをつかってblueqat cloud経由でAPIをたたいてみます。
Copy 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)
Copy 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})
Copy 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