🐈
振幅エンコーディング (3)
制御振幅エンコーディング
前回は、データ木構造を用いた振幅エンコーディングについて記載しました。
VQLS(Variational Quantum Linear Solver)でこれを用いるにあたり、制御振幅エンコーディング回路を実装する必要があります。
VQLSについて日本語の参考になる解説記事がありますので、VQLSについてはそちらを参照ください。
制御ビットの指定
例として、データ木の一番深いところで考えます。
疑似コードのとおり、制御回転ゲート
# v_i : エンコードしたいベクトルの要素
# multi_flag : (1/pi)*arccos(v_i)を二進数表示の計算のためのフラグ
# msb_index : 最上位量子ビットのインデックス
# si_offset : m bit精度近似計算のための、データレジスタの開始インデックス
# depth : データ木構造の深さ
# node_prob_list : データ木構造におけるノードの確率をリストにしたもの
# upper_nd_index : データ木構造における現ノードの、一つ上の深さのノード(上位ビット)のインデックス
# Ry Rotation
for k in range(len(multi_flag)):
if multi_flag[k] == 1:
qc.ccx(controled_bit_index, (msb_index-si_offset) - (depth-1), k)
# CRy
qc.ry(0.5* (np.pi / np.power(2, (k+1)*multi_flag[k]) *2), (msb_index-si_offset) - depth)
qc.cx(k, (msb_index-si_offset) - depth)
qc.ry(0.5* - (np.pi / np.power(2, (k+1)*multi_flag[k]) *2), (msb_index-si_offset) - depth)
qc.cx(k, (msb_index-si_offset) - depth)
if (depth == len(node_prob_list)-1) and (np.sign(node_prob_list[depth][upper_nd_index*2 + 1]) < 0):
# if depth is the last, and amplitude of |k>|1> is negative, you should consider sign of vector
# apply to only |1> state
qc.ccz(controled_bit_index, (msb_index-si_offset) - (depth-1), (msb_index-si_offset) - depth)
if (depth == len(node_prob_list)-1) and (np.sign(node_prob_list[depth][upper_nd_index*2]) < 0):
qc.ccx(controled_bit_index, (msb_index-si_offset) - (depth-1), (msb_index-si_offset) - depth)
qc.ccz(controled_bit_index, (msb_index-si_offset) - (depth-1), (msb_index-si_offset) - depth)
qc.ccx(controled_bit_index, (msb_index-si_offset) - (depth-1), (msb_index-si_offset) - depth)
実装 (Qiskit)
-
制御量子ビット(最上位量子ビット)が 0 の場合
# Input vector tgt_vec = np.array([-2, -2, 0, -1, 3, -1, 0, -2]) norm_vec = normalize(tgt_vec) node_prob_list = gen_node_prob_list(norm_vec) # Calc Quantum Circuit property probamp_si_offset = 1 mbit_precison = 16 n = int(np.log2(np.size(norm_vec)-1)) + 1 # Initialize Quantum Circuit qc = QuantumCircuit() qr = QuantumRegister(probamp_si_offset + n + mbit_precison) qc.add_register(qr) # X gate to Control-bit for debugging # Do nothing # Apply controlled Probabilistic Amplitude Encoding qc = controled_prob_amp_encoding_3qubit(qc, 0, probamp_si_offset, norm_vec, node_prob_list, mbit_precison) # Simulate State print("---------------- State simulation -----------------") print("tgt_vec(normalized): ", norm_vec) state = sim_state(qc) print("---------------------------------------------------")
---------------- State simulation ----------------- tgt_vec(normalized): [-0.41702883 -0.41702883 0. -0.20851441 0.62554324 -0.20851441 0. -0.41702883] 1.0*|00000000000000000000> + 4.16333634234434e-16*I*|00000000000000000000> + 1.67919913975003e-17*|00010000000000000000> + 1.30770226682234e-21*I*|00010000000000000000> - 1.34877475860597e-17*|00100000000000000000> - 3.7722833377141e-33*I*|00100000000000000000> - 9.37236364387668e-35*|00110000000000000000> - 2.50144392150061e-38*I*|00110000000000000000> - 2.12455859514543e-17*|01000000000000000000> - 7.48377201431772e-33*I*|01000000000000000000> - 3.3083292814181e-34*|01010000000000000000> + 7.95954099103817e-38*I*|01010000000000000000> + 9.78271983161075e-34*|01100000000000000000> - 1.11724190190601e-49*I*|01100000000000000000> - 3.05971458325977e-50*|01110000000000000000> - 4.81651011585083e-55*I*|01110000000000000000> ---------------------------------------------------
-
制御量子ビット(最上位量子ビット)が 1 の場合
# Input vector tgt_vec = np.array([-2, -2, 0, -1, 3, -1, 0, -2]) norm_vec = normalize(tgt_vec) node_prob_list = gen_node_prob_list(norm_vec) # Calc Quantum Circuit property probamp_si_offset = 1 mbit_precison = 16 n = int(np.log2(np.size(norm_vec)-1)) + 1 # Initialize Quantum Circuit qc = QuantumCircuit() qr = QuantumRegister(probamp_si_offset + n + mbit_precison) qc.add_register(qr) # X gate to Control-bit for debugging qc.x(probamp_si_offset + n + mbit_precison-1) # Apply controlled Probabilistic Amplitude Encoding qc = controled_prob_amp_encoding_3qubit(qc, 0, probamp_si_offset, norm_vec, node_prob_list, mbit_precison) # Simulate State print("---------------- State simulation -----------------") print("tgt_vec(normalized): ", norm_vec) state = sim_state(qc) print("---------------------------------------------------")
---------------- State simulation ----------------- tgt_vec(normalized): [-0.41702883 -0.41702883 0. -0.20851441 0.62554324 -0.20851441 0. -0.41702883] -0.417080686523715*|10000000000000000000> - 2.52581891030085e-16*I*|10000000000000000000> - 0.417080686523715*|10010000000000000000> - 2.7803905168812e-16*I*|10010000000000000000> - 2.63398908107789e-18*|10100000000000000000> - 9.1066950267484e-34*I*|10100000000000000000> - 0.208500420384733*|10110000000000000000> - 1.09584438270859e-16*I*|10110000000000000000> + 0.625526498858582*|11000000000000000000> + 2.95460030351555e-16*I*|11000000000000000000> - 0.20844353146532*|11010000000000000000> - 1.37724091954937e-16*I*|11010000000000000000> + 4.75898859798235e-18*|11100000000000000000> + 1.35457613644109e-18*I*|11100000000000000000> - 0.416992649783176*|11110000000000000000> - 2.48625173688326e-16*I*|11110000000000000000> ---------------------------------------------------
要改善事項
-
bit精度近似計算のデータレジスタ(m qubits)のアドレス指定を可変にするm
Discussion