IBM Quantum Challenge 2020 (4th anniversary) 振り返りEx04編
私が参加した、 IBM Quantum Challengeの課題について今回は振り返って行きたいと思います。今回はEx04についてです。
Ex01~Ex03に関しては↓で書きました。
問題に入る前に
この↓のツイートは開催終了後にアップされたものですが、めちゃくちゃ驚きました。
Let me tell you why it’s so rewarding to work with such an awesome community:
— Elisa Bäumer (@ElisaBaumer) 2020年5月8日
When we designed the challenge, we thought 46 was the absolute best. Then someone came and destroyed that with 45!💥#IBMQuantumChallenge
IBMの中の人が想定していた回路の最小コスト45を上回るコスト45の解答が参加者から出てきました。(コストについては後で説明します。もちろん小さい値ほど良い結果です。)
ただでさえ難かった(少なくとも私にとっては)最終問題を予想を上回る解答を4日間の短い時間で導きだしたことに感動しました。コンテストならでは(?)の体験ができました。
Exercise 4: Circuit Decomposition
最終問題は、量子コンピュータのゲート操作がユニタリ行列の演算であることに注目した問題でした。課題は与えられたのユニタリ行列を量子回路に実装することです。任意のユニタリ行列はシングル量子ビットの回転ゲートゲートとゲートだけで構成できることが知られており、ユニタリ行列をゲートとゲートに分解して回路を実装します。ちなみに、IBM Quantum Experienceでは量子回路はゲートとゲートにtranspileされて実行されているそうです。
分解する際に考えなければいけないのは回路のコストです。できるだけ少ないゲート操作で近似することができれば効率的に計算でき、ノイズも少なくより正しい結果を得ることができます。ここではコストを次の計算式で求めます。
ここで、はゲートの数、はゲートの数を表します。1ビットゲートは2ビットゲートよりもはるかに高い忠実度を持っているので、ゲートはゲートの10倍のコストになっています。この課題ではゲートとゲートのみで構成され、コストが1600以下の回路に最適化することで正解となります。
ただし、ユニタリ行列を近似して求めるユニタリは誤差、を満たす必要があります。
解答のアプローチ
解答のアプローチは主に2つあると思います。
- ユニタリ行列の対称性に着目した解析的な解法
- 変分量子回路を用いた回転ゲートパラメタ調整による解法
1つ目の方法は、ユニタリ行列の対称性に着目してとてもスマート解法です。おそらくIBMの中の人もこの解法を想定していると思います(個人の推測ですが)。 2つ目の方法は、Quantum Circuit Learning (量子回路学習, QCL)などに用いられる変分量子回路を利用して、ゲートの角度パラメタを調整します。この方法は、入力サイズに対して指数的にパラメタが増えるため、一般的には現実的な方法ではありません。今回はユニタリ行列の対称性があるので、なんとか解ける問題になっていると思っています。2つ目の解法につていは、研究も行われているようで参考になりそうな文献を列挙しておきます。
- 山下 茂,松尾 惇士 『量子回路設計と最適化』
- 変分量子回路の 高速自動最適化ツールの開発
- 5-2. Quantum Circuit learning — Quantum Native Dojo ドキュメント
- K. Mitarai, M. Negoro, M. Kitagawa, and K. Fujii, Quantum circuit learning, Phys. Rev. A 98, 032309 (2018), arXiv:1803.00745
- L. Cincio, Y. Subaşi, A. T. Sornborger, and P. J. Coles, Learning the quantum algorithm for state overlap, arXiv:1803.04114.
ユニタリ行列の対称性に着目した解析的な解法
ここでは、コンテスト2位の方が公開されている解法を参考に問題を振り返っていきます。スマートな解法を丁寧に分かりやすく解説しています。
準備
必要なパッケージのインポートと、ユニタリ行列のshapeを確認しておきます。
from qiskit import QuantumCircuit, execute, Aer from qiskit.compiler import transpile, assemble from may4_challenge.ex4 import get_unitary, check_circuit, submit_circuit U = get_unitary() # print(U) print("U has shape", U.shape)
U has shape (16, 16)
transpile
まずは、ユニタリ行列を量子回路に接続してtranspilingして、どんな回路になるか見てみましょう。
任意のユニタリ行列を回路に接続するには、iso()
を使います。
transpilingとは、ゲートなどの一般的なゲートを抽象的な回転ゲート(今回はゲート)とゲートに変換することです。transpile()
を使用します。オプションにあるoptimization_level
は最適化の設定ですが、一番重い最適化の3
は実行するバックエンドの情報を含めた最適化らしくコストが大きくなる場合もあるので、今回は一段落としたoptimization_level=2
に設定しています。詳細は公式ドキュメントを参照してください。
今回は使用しませんでしたが、Qiskitには色々な種類のtranspilerが用意されてるみたいなので、気になったら↓のチュートリアルを参照してみてください。
https://www.qiskit.org/documentation/locale/ja_JP/tutorials/advanced/terra/4_transpiler_passes_and_passmanager.htmlwww.qiskit.org
本題に戻ってコードです。
qc1 = QuantumCircuit(4) qc1.iso(U, [0,1,2,3], []) qc1 = transpile(qc1, basis_gates = ['u3', 'cx'], optimization_level=2) qc1.draw(output='mpl')
check_circuit(qc1)
Circuit stats: ||U-V||_2 = 9.761271800590147e-14 (U is the reference unitary, V is yours, and the global phase has been removed from both of them). Cost is 1662 Something is not right with your circuit: the cost of the circuit is too high (above 1600)
ユニタリ行列とほぼ等価な回路を作成できましたが、めちゃくちゃデカイ回路になってしまいました。コストも1600オーバーでアウトです。
ユニタリ行列を観察
次は多すぎるゲートを削減できないか、ユニタリ行列を解析してみます。
視覚的に感覚を掴むため、行列のヒートマップを作成してみます。
%matplotlib inline import numpy as np import matplotlib.pyplot as plt import seaborn as sns fig, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4, figsize=(16, 3)) sns.heatmap(np.real(U), vmin=-1, vmax=1, cmap='hot', square=True, ax=ax1) ax1.set_title('Real part') sns.heatmap(np.imag(U), vmin=-1, vmax=1, cmap='hot', square=True, ax=ax2) ax2.set_title('Imaginary part') sns.heatmap(np.abs(U), vmin=0, vmax=1, cmap='hot', square=True, ax=ax3) ax3.set_title('Magnitude') sns.heatmap(np.angle(U), vmin=-np.pi, vmax=np.pi, cmap='hot', square=True, ax=ax4) ax4.set_title('Phase') plt.show()
幾何学模様なっていて、明らかに対称性がありますね!!!
対角化
参照元の解法では、一旦QFT(Quantum Fourier transform, 量子フーリエ変換)のワンクッション置いてますが、QFTはショートカットします。
ここで考えるのは、この問題のポイントでもあるユニタリ行列の対角化です。実は、のようにユニタリ行列をゲートで両側を挟んであげると(Hadamard空間に写してあげると)対角化することができます。
対角化するためにゲートを使うということをどうやって思いついたか説明できませんが(ここは直感なのかな?)、コンテスト開催中のQiskitでは「をつくってみろ」というヒントが上がっていました。
# 1ビットのH行列 H = 1/np.sqrt(2)*np.array([[1,1],[1,-1]]) # 4ビットのH行列 H4 = np.kron(H,np.kron(H,np.kron(H,H))) HUH = np.matmul(H4,np.matmul(U,H4)) for i in range(len(HUH)): for j in range(len(HUH[i])): if -1e-14 < np.real(HUH[i,j]) < 1e-14: HUH[i,j] = 0 + 1j*(np.imag(HUH[i,j])) if -1e-14 < np.imag(HUH[i,j]) < 1e-14: HUH[i,j] = np.real(HUH[i,j]) + 1j*0 fig, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4, figsize=(16, 3)) sns.heatmap(np.real(HUH), vmin=-1, vmax=1, cmap='hot', square=True, ax=ax1) ax1.set_title('Real part') sns.heatmap(np.imag(HUH), vmin=-1, vmax=1, cmap='hot', square=True, ax=ax2) ax2.set_title('Imaginary part') sns.heatmap(np.abs(HUH), vmin=0, vmax=1, cmap='hot', square=True, ax=ax3) ax3.set_title('Magnitude') sns.heatmap(np.angle(HUH), vmin=-np.pi, vmax=np.pi, cmap='hot', square=True, ax=ax4) ax4.set_title('Phase') plt.show()
対角成分だけが残り、しっかりと対角化できています。
で回路作成
を回路に接続してコストが減少しているか確かめてみます。はHadamard空間の行列のため、前後にゲートをつけて元の空間に戻してあげる必要があります。
qc2 = QuantumCircuit(4) qc2.h([0,1,2,3]) qc2.iso(HUH, [0,1,2,3], []) qc2.h([0,1,2,3]) qc2 = transpile(qc2, basis_gates = ['u3', 'cx'], optimization_level=2) qc2.draw(output='mpl')
check_circuit(qc2)
Circuit stats: ||U-V||_2 = 7.555325382443748e-15 (U is the reference unitary, V is yours, and the global phase has been removed from both of them). Cost is 194 Great! Your circuit meets all the constrains.
大きくゲートを削減でき、コスト1600以下になってチャレンジクリアです!
対角行列を見る
ここからは、どこまでコストを削減できるか考えていきましょう。対角化した行列の左から3番目のプロットをみると対角化成分がすべて1であり、正規化された対角行列という事がわかります。まずは、正規化された対角演算子がどのような作用をするか行列を例に見てます。
この演算子はそれぞれの量子状態に次のような操作をすることを表しています。
つまり、各量子状態に位相を付加する作用を持っています。
では、では位相がどのようになっているか見てみましょう。
np.diagonal(HUH)
array([ 1. +0.j , 0.70710678+0.70710678j, -0.70710678-0.70710678j, 0. +1.j , 0. +1.j , 0.70710678-0.70710678j, -0.70710678+0.70710678j, -1. +0.j , -0.70710678+0.70710678j, -1. +0.j , -1. +0.j , 0.70710678+0.70710678j, -0.70710678-0.70710678j, 0. +1.j , 0. +1.j , -0.70710678+0.70710678j])
書き直すと
これを位相の角度に書き直すと
まずは、1つだけビットが反転した状態()に注目すると、位相は
になっています。この角度をそれぞれ、対応する量子ビットにゲートで対応させます。
qcp = QuantumCircuit(4) qcp.u3(0,np.pi/4,0,0) qcp.u3(0,-3*np.pi/4,0,1) qcp.u3(0,np.pi/2,0,2) qcp.u3(0,3*np.pi/4,0,3) qcp.draw(output='mpl')
この回路のユニタリ行列がどうなっているか見てみます。
U_simulator = Aer.get_backend('unitary_simulator')
result = execute(qcp, backend = U_simulator).result()
P = result.get_unitary()
np.diagonal(P)
array([ 1.00000000e+00+0.00000000e+00j, 7.07106781e-01+7.07106781e-01j, -7.07106781e-01-7.07106781e-01j, 0.00000000e+00-1.00000000e+00j, 6.12323400e-17+1.00000000e+00j, -7.07106781e-01+7.07106781e-01j, 7.07106781e-01-7.07106781e-01j, 1.00000000e+00-6.12323400e-17j, -7.07106781e-01+7.07106781e-01j, -1.00000000e+00+2.22044605e-16j, 1.00000000e+00+0.00000000e+00j, 7.07106781e-01+7.07106781e-01j, -7.07106781e-01-7.07106781e-01j, -2.22044605e-16-1.00000000e+00j, 0.00000000e+00+1.00000000e+00j, -7.07106781e-01+7.07106781e-01j])
また、位相を角度に直してみます。
つぎに、この得られた角度との角度との差を取ってみます。
ここで、位相がズレてるのは、3,5,6,7,10,13番目なので、対応する量子状態は
です。この量子状態の位相をズラす回路はゲートを使うと次のようになります。
こういう回路の繋ぎ方を試行錯誤して考える時、IBM Quantum ExperienceのCircuit Composerが便利ですね。
の位相をズラせました。
これまでの結果から、ユニタリ行列の回路は次のようになります。
qc4 = QuantumCircuit(4) qc4.h([0,1,2,3]) qc4.barrier() qc4.cz(0,1) qc4.cz(0,2) qc4.cz(1,2) qc4.cz(1,3) qc4.barrier() qc4.u3(0,np.pi/4,0,0) qc4.u3(0,np.pi/2,0,2) qc4.u3(0,-3*np.pi/4,0,1) qc4.u3(0,3*np.pi/4,0,3) qc4.barrier() qc4.h([0,1,2,3]) qc4.draw(output='mpl')
transpile()
で回路を単純化してもらいましょう。
qc5 = QuantumCircuit(4) qc5.h([0,1,2,3]) qc5.cz(0,1) qc5.cz(0,2) qc5.cz(1,2) qc5.cz(1,3) qc5.u3(0,np.pi/4,0,0) qc5.u3(0,np.pi/2,0,2) qc5.u3(0,-3*np.pi/4,0,1) qc5.u3(0,3*np.pi/4,0,3) qc5.h([0,1,2,3]) qc5 = transpile(qc5, basis_gates = ['u3', 'cx'], optimization_level=2,) qc5.draw(output='mpl')
気になるコストは……
check_circuit(qc5)
Circuit stats: ||U-V||_2 = 1.4545997371336807e-15 (U is the reference unitary, V is yours, and the global phase has been removed from both of them). Cost is 46
46!!!IBM中の人が想定していたベストスコアを叩き出せました!!!
コスト45を目指して
ここからは、あと一つ回転ゲートを減らすことを考えます。
公式リポジトリに上がっている↓のメモを参考に考えていきます。
点線で囲った部分に注目します。目標はにある回転ゲートの削減です。
回路の変換には↓の論文が参考になります。
おなじみのCircuit Composerで考えます。
右側を変換します。
次は左側の2つのゲートを変換します。
真ん中のゲートは打ち消せます。
論文を参考にしつつ、ゲートとゲートを変換していきます。
重なっているゲートは消しておきます。
に残っているゲートは本体の回路にあるゲートと打ち消せるのでの回転ゲートは削除できました。
これを本体に戻してtanspile()
してあげます。
qc6 = QuantumCircuit(4) qc6.h([1,3]) qc6.cx(0,2) qc6.cx(1,0) qc6.h(0) qc6.u3(0,np.pi/2,0,0) qc6.h(0) qc6.cx(0,2) qc6.h(0) qc6.u3(0,np.pi*3/2,0,0) qc6.u3(0,np.pi/4,0,0) qc6.h(2) qc6.cz(1,3) qc6.u3(0,-3*np.pi/4,0,1) qc6.u3(0,3*np.pi/4,0,3) qc6.h([0,1,2,3]) qc6 = transpile(qc6, basis_gates = ['u3', 'cx'], optimization_level=2,) qc6.draw(output='mpl')
コストは……
check_circuit(qc6)
Circuit stats: ||U-V||_2 = 1.4000864719689736e-15 (U is the reference unitary, V is yours, and the global phase has been removed from both of them). Cost is 45
45!!!最小スコア達成できました!!!
変分量子回路を用いた回転ゲートパラメタ調整による解法
続いて、もう一つの別解について見ていきます。
コンテスト中、私が使ったアプローチです。参考になるか分かりませんが私が挑戦中に考えていたことも合わせて記しておきます。
まず問題を見た瞬間に、私は「適当に回路作って、回転ゲートの角度は最適化のアルゴリズム使って、ちゃちゃっと調整すればイケるんじゃね」と、何も思考せずこのアプローチを選びました。
最初の回路を作成
まずはベースとなる回路を考えます。ベストな回路が提案されているかもしれないので、まずは[quantum circuit controlled rotation]のような関連ワードでググりました。さらに、回路を見つけたいので画像のタブを眺めてみます。
上の方にあるControlled-ゲートが使えそうだったので、
や
https://www.appi.keio.ac.jp/Itoh_group/abe/pdf/qc5.pdf
を参考にして、"それっぽい回路"を作りました。
ではコードです。
import numpy as np from qiskit.compiler import transpile from qiskit import QuantumCircuit from may4_challenge.ex4 import check_circuit, submit_circuit from may4_challenge.ex4 import get_unitary U = get_unitary() def make_qc(params): qc = QuantumCircuit(4) qc.u3(params[0],params[1],0,0) qc.u3(params[2],params[3],0,1) qc.cx(0,1) qc.u3(params[4],params[5],0,1) qc.u3(params[6],params[7],0,2) qc.cx(1,2) qc.u3(params[8],params[9],0,2) qc.cx(0,2) qc.u3(params[10],params[11],0,2) qc.cx(1,2) qc.u3(params[12],params[13],0,2) qc.u3(params[14],params[15],0,3) qc.cx(2,3) qc.u3(params[16],params[17],0,3) qc.cx(1,3) qc.u3(params[18],params[19],0,3) qc.cx(2,3) qc.u3(params[20],params[21],0,3) qc.cx(0,3) qc.u3(params[22],params[23],0,3) qc.cx(2,3) qc.u3(params[24],params[25],0,3) qc.cx(1,3) qc.u3(params[26],params[27],0,3) qc.cx(2,3) qc.u3(params[28],params[29],0,2) qc.cx(1,2) qc.u3(params[30],params[31],0,2) qc.cx(0,2) qc.u3(params[32],params[33],0,2) qc.cx(1,2) qc.u3(params[34],params[35],0,1) qc.cx(0,1) qc.u3(params[36],params[37],0,0) qc.u3(params[38],params[39],0,1) qc.u3(params[40],params[41],0,2) qc.u3(params[42],params[43],0,3) return qc np.random.seed(0) params = np.random.uniform(0,0.1,44) qc = make_qc(params) qc.draw(output='mpl')
パラメタが多くなると最適化の収束が大変そうだと思ったので、ゲートの3つのパラメタのうち2つの角度だけを変数に設定しました。 初期値はランダムな値を設定しています。
回路最適化
最適化するにあたって目標関数を設定します。今回はちょうどの目標値が設定されていたので、それをそのまま目標関数として拝借します。
ここを覗くと_validate()
を使えば良さそうです。
from may4_challenge.ex4 import _validate def loss(params): qc = make_qc(params) return _validate(qc)['delta'] # 初期値 loss(params)
1.9979253424790289
最適化アルゴリズムはQiskitにもいろいろありますが、私の場合はScipyのSLSQPがいい感じでした。
from scipy.optimize import minimize import scipy options = {'disp': True,'maxiter':1000} result = minimize(loss, x0=params, method='SLSQP', options=options)
Optimization terminated successfully. (Exit mode 0) Current function value: 0.9616194503294917 Iterations: 829 Function evaluations: 38692 Gradient evaluations: 829
lossが0.96でした。局所解に落ちている可能性があるので、グローバル最適化をしてみます。Scipyのbasinhopping()
を使用します。lossが小さくなることをお祈りしながら画面を見つめましょう。
result = scipy.optimize.basinhopping(loss,result['x'],stepsize=1, T=500, niter=30, minimizer_kwargs={'method':'SLSQP'}, disp=True)
basinhopping step 0: f 0.958414 warning: basinhopping: local minimization failure basinhopping step 1: f 1.2423 trial_f 1.2423 accepted 1 lowest_f 0.958414 basinhopping step 2: f 1.78182 trial_f 1.78182 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 3: f 1.48645 trial_f 1.48645 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 4: f 1.41711 trial_f 1.41711 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 5: f 1.41806 trial_f 1.41806 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 6: f 1.91918 trial_f 1.91918 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 7: f 1.43017 trial_f 1.43017 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 8: f 1.9447 trial_f 1.9447 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 9: f 1.72044 trial_f 1.72044 accepted 1 lowest_f 0.958414 warning: basinhopping: local minimization failure basinhopping step 10: f 0.779125 trial_f 0.779125 accepted 1 lowest_f 0.779125 found new global minimum on step 10 with function value 0.779125 warning: basinhopping: local minimization failure basinhopping step 11: f 0.770332 trial_f 0.770332 accepted 1 lowest_f 0.770332 found new global minimum on step 11 with function value 0.770332 warning: basinhopping: local minimization failure basinhopping step 12: f 0.268215 trial_f 0.268215 accepted 1 lowest_f 0.268215 found new global minimum on step 12 with function value 0.268215 warning: basinhopping: local minimization failure basinhopping step 13: f 0.00136049 trial_f 0.00136049 accepted 1 lowest_f 0.00136049 found new global minimum on step 13 with function value 0.00136049 warning: basinhopping: local minimization failure basinhopping step 14: f 0.00306066 trial_f 0.00306066 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 15: f 0.797419 trial_f 0.797419 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 16: f 1.71626 trial_f 1.71626 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 17: f 1.18878 trial_f 1.18878 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 18: f 0.79497 trial_f 0.79497 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 19: f 1.32662 trial_f 1.32662 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 20: f 1.11387 trial_f 1.11387 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 21: f 1.21394 trial_f 1.21394 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 22: f 0.765612 trial_f 0.765612 accepted 1 lowest_f 0.00136049 warning: basinhopping: local minimization failure basinhopping step 23: f 0.000141734 trial_f 0.000141734 accepted 1 lowest_f 0.000141734 found new global minimum on step 23 with function value 0.000141734 warning: basinhopping: local minimization failure basinhopping step 24: f 1.82943 trial_f 1.82943 accepted 1 lowest_f 0.000141734 warning: basinhopping: local minimization failure basinhopping step 25: f 1.49653 trial_f 1.49653 accepted 1 lowest_f 0.000141734 warning: basinhopping: local minimization failure basinhopping step 26: f 1.68299 trial_f 1.68299 accepted 1 lowest_f 0.000141734 warning: basinhopping: local minimization failure basinhopping step 27: f 1.41449 trial_f 1.41449 accepted 1 lowest_f 0.000141734 warning: basinhopping: local minimization failure basinhopping step 28: f 0.795348 trial_f 0.795348 accepted 1 lowest_f 0.000141734 warning: basinhopping: local minimization failure basinhopping step 29: f 1.1086 trial_f 1.1086 accepted 1 lowest_f 0.000141734 basinhopping step 30: f 1.11632 trial_f 1.11632 accepted 1 lowest_f 0.000141734
お祈りしたおかげで0.01以下になりました。コストを見てみましょう。
qc = make_qc(result['x']) check_circuit(qc) qc.draw(output='mpl')
Circuit stats: ||U-V||_2 = 0.00014173388577980503 (U is the reference unitary, V is yours, and the global phase has been removed from both of them). Cost is 172 Great! Your circuit meets all the constrains. Your score is 172. The lower, the better! Feel free to submit your answer and remember you can re-submit a new circuit at any time!
はい!チャレンジクリアです!!
回路のコスト削減
ここかからは、余分そうなゲートを削って行きます。
方針はコストがデカイゲートを消すことを考えます。どうやって消すかというと、回路からゲートを1つ削る→最適化をひたすら繰り返し、人力で消せるゲートを探索しました。
途中いろいろ試行錯誤して、最終的にコンテスト時間切れで↓のような回路になりました。
def make_qc(params): qc = QuantumCircuit(4) qc.u3(params[0],params[1],params[2],0) qc.u3(params[3],params[4],params[5],1) qc.u3(params[6],params[7],params[8],2) qc.u3(params[9],params[10],params[11],3) qc.cx(2,3) qc.u3(params[12],params[13],params[14],3) qc.cx(1,3) qc.cx(2,3) qc.u3(params[15],params[16],params[17],3) qc.cx(2,3) qc.u3(params[18],params[19],params[20],3) qc.cx(1,2) qc.cx(0,2) qc.u3(params[21],params[22],params[23],0) qc.u3(params[24],params[25],params[26],2) qc.cx(1,2) qc.u3(params[27],params[28],params[29],1) qc.u3(params[30],params[31],params[32],2) return qc qc = make_qc(result['x']) check_circuit(qc) qc.draw(output='mpl')
Circuit stats: ||U-V||_2 = 1.5597049605037762e-15 (U is the reference unitary, V is yours, and the global phase has been removed from both of them). Cost is 81
コスト81の129位でフィニッシュしました!
終了後に気づいたのですが、transpile()
すると
qc = transpile(qc, optimization_level=3,basis_gates=['u3','cx']) check_circuit(qc) qc.draw(output='mpl')
Circuit stats: ||U-V||_2 = 2.2956789054593593e-15 (U is the reference unitary, V is yours, and the global phase has been removed from both of them). Cost is 73
さらにコスト73まで削減できました。見落としてましたね。
更に詰める(仮)
ここからどうやって、コスト削減できるかは思いついていないです。
ここから、ゲート削減できた方はぜひ教えて下さい!!!
おわりに
以上で、IBM Quantum Challenge 2020 (4th anniversary)の振り返りを終わりにしたいと思います。 今回のチャレンジも導入が丁寧で、得られる知識も多くて参加して良かったと思えるコンテストでした。 きっと次のIBM Quantum Challengeもあると思っているので、それまでに色々勉強していきたいと思います。