概要
- Cirq の 理解を, さらに深めるため, シュミレートするサンプルをいくつか動かしてみた.
- 動作環境は, Google Colaboratory で行った
感想
- Google社 の Simulation に 関する記事を少しずつ進めることが出来たと思う.
- 量子物理学に関する知識(用語, 数式の意味ほか)は, 徐々に身につけていく必要があると感じた.
- 時間を見つけて, 今後も, チュートリアルの残りの部分を進めていこうと思う.
Introduction to pure state simulation
量子回路を作成して, シュミレートするサンプル.
- Circuit(sqrt X, CZ, sqrt X) の サンプル
- Circuit(X, CNOT) の サンプル
- Circuit(X, X, CSWAP) の サンプル
- Simulator(X, X, CSWAP) の サンプル
- Simulator(X, X, CCNOT) の サンプル
- Simulator(sqrt X, CNOT) の サンプル
- Simulator(sqrt X, sqrt X, CSWAP) の サンプル
- Simulator(sqrt X, CNOT) で simulate を 使用する サンプル
- Simulator(sqrt X, sqrt X, CSWAP) で simulate を 使用する サンプル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[編集内容(Circuit(sqrt X, CZ, sqrt X))] import cirq q0, q1 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0) def basic_circuit(meas=True): sqrt_x = cirq.X ** 0.5 yield sqrt_x(q0), sqrt_x(q1) yield cirq.CZ(q0, q1) yield sqrt_x(q0), sqrt_x(q1) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1') circuit = cirq.Circuit() circuit.append(basic_circuit()) print(circuit) |
1 2 3 4 5 6 7 8 9 10 |
[出力結果] ※ meas=True のとき. (0, 0): ───X^0.5───@───X^0.5───M('q0')─── │ (1, 0): ───X^0.5───@───X^0.5───M('q1')─── ※ meas=False のとき. (0, 0): ───X^0.5───@───X^0.5─── │ (1, 0): ───X^0.5───@───X^0.5─── |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[編集内容(Circuit(X, CNOT))] import cirq q0, q1 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0) def x_cnot_circuit(meas=True): yield cirq.X(q0) yield cirq.CNOT(q0, q1) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1') circuit = cirq.Circuit() circuit.append(x_cnot_circuit()) print(circuit) |
1 2 3 4 |
[出力結果] (0, 0): ───X───@───M('q0')─── │ (1, 0): ───────X───M('q1')─── |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[編集内容(Circuit(X, X, CSWAP))] import cirq q0, q1, q2 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0), cirq.GridQubit(2, 0) def x_x_cswap_circuit(meas=True): yield cirq.X(q0) yield cirq.X(q1) yield cirq.CSWAP(q0, q1, q2) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1'), cirq.measure(q2, key='q2') circuit = cirq.Circuit() circuit.append(x_x_cswap_circuit()) print(circuit) |
1 2 3 4 5 6 |
[出力結果] (0, 0): ───X───@───M('q0')─── │ (1, 0): ───X───×───M('q1')─── │ (2, 0): ───────×───M('q2')─── |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[編集内容(Simulator(X, X, CSWAP))] import cirq from cirq import Simulator q0, q1, q2 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0), cirq.GridQubit(2, 0) def x_x_cswap_circuit(meas=True): yield cirq.X(q0) yield cirq.X(q1) yield cirq.CSWAP(q0, q1, q2) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1'), cirq.measure(q2, key='q2') circuit = cirq.Circuit() circuit.append(x_x_cswap_circuit()) # 以下のように理解. # 1. ↑↑↑(3量子ビット, 000 と見る) を 用意. # 2. 1量子ビット目に, X ゲート を 操作. # ※ 1量子ビット目が, ↓ に 変わるはず. # 3. 2量子ビット目に, X ゲート を 操作. # ※ 2量子ビット目が, ↓ に 変わるはず. # 4. すべての量子ビットに, CSWAP ゲート を 操作. # ※ 3量子ビット目, 3量子ビット目が, 入れ替わるはず(制御ビット(1量子ビット目, 2量子ビット目)が, いずれも 1 なので). # 5. 測定結果(1回)が, それぞれ, 以下のようになった. # 1量子ビット目: ↓ # 2量子ビット目: ↑ # 3量子ビット目: ↓ simulator = Simulator() result = simulator.run(circuit) print(result) |
1 2 3 4 |
[出力結果] q0=1 q1=0 q2=1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[編集内容(Simulator(X, X, CCNOT))] import cirq from cirq import Simulator q0, q1, q2 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0), cirq.GridQubit(2, 0) def x_x_ccnot_circuit(meas=True): yield cirq.X(q0) yield cirq.X(q1) yield cirq.CCNOT(q0, q1, q2) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1'), cirq.measure(q2, key='q2') circuit = cirq.Circuit() circuit.append(x_x_ccnot_circuit()) # 以下のように理解. # 1. ↑↑↑(3量子ビット, 000 と見る) を 用意. # 2. 1量子ビット目に, X ゲート を 操作. # ※ 1量子ビット目が, ↓ に 変わるはず. # 3. 2量子ビット目に, X ゲート を 操作. # ※ 2量子ビット目が, ↓ に 変わるはず. # 4. すべての量子ビットに, CCNOT ゲート を 操作. # ※ 3量子ビット目が, ↓ に 変わるはず(制御ビット(1量子ビット目, 2量子ビット目)が, いずれも 1 なので). # 5. 測定結果(1回)が, それぞれ, 以下のようになった. # 1量子ビット目: ↓ # 2量子ビット目: ↓ # 3量子ビット目: ↓ simulator = Simulator() result = simulator.run(circuit) print(result) |
1 2 3 4 |
[出力結果] q0=1 q1=1 q2=1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
[編集内容(Simulator(sqrt CNOT))] import cirq from cirq import Simulator q0, q1 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0) def sqrt_x_cnot_circuit(meas=True): yield cirq.X(q0) ** 0.5 yield cirq.CNOT(q0, q1) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1') circuit = cirq.Circuit() circuit.append(sqrt_x_cnot_circuit()) # 以下のように理解. # 1. ↑↑↑(3量子ビット, 000 と見る) を 用意. # 2. 1量子ビット目に, X ゲート の 0.5乗 を 操作. # ※ 1量子ビット目が, ↑ もしくは ↓ に 変わるはず. # 3. すべての量子ビットに, CCNOT ゲート を 操作. # ※ 1量子ビット目(制御ビット)が, 1 の場合(↓), 2量子ビット目も, 1 (↓)に変わる. # 4. 測定結果(5回)が, それぞれ, 以下のようになった. # 1量子ビット目: ↓↓↓↑↑ # 2量子ビット目: ↓↓↓↑↑ simulator = Simulator() result = simulator.run(circuit) print(result) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[出力結果] ※1回目. q0=1 q1=1 ※2回目. q0=1 q1=1 ※3回目. q0=1 q1=1 ※4回目. q0=0 q1=0 ※5回目. q0=0 q1=0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[編集内容(Simulator(sqrt X, sqrt X, CSWAP))] import cirq from cirq import Simulator q0, q1, q2 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0), cirq.GridQubit(2, 0) def sqrt_x_sqrt_x_cswap_circuit(meas=True): yield cirq.X(q0) ** 0.6 yield cirq.X(q1) ** 0.6 yield cirq.CSWAP(q0, q1, q2) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1'), cirq.measure(q2, key='q2') circuit = cirq.Circuit() circuit.append(sqrt_x_sqrt_x_cswap_circuit()) # 以下のように理解. # 1. ↑↑↑(3量子ビット, 000 と見る) を 用意. # 2. 1量子ビット目に, X ゲート を 操作. # ※ 1量子ビット目が, ↑ もしくは ↓ に 変わるはず. # 3. 2量子ビット目に, X ゲート を 操作. # ※ 2量子ビット目が, ↑ もしくは ↓ に 変わるはず. # 4. すべての量子ビットに, CSWAP ゲート を 操作. # ※ 制御ビット(1量子ビット目, 2量子ビット目)が, いずれも 1 の場合, 2量子ビット目, 3量子ビット目が, 入れ替わる. # 5. 測定結果(5回)が, それぞれ, 以下のようになった. # 1量子ビット目: ↓↑↓↓↓ # 2量子ビット目: ↑↓↑↑↑ # 3量子ビット目: ↑↑↑↓↓ simulator = Simulator() result = simulator.run(circuit) print(result) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[出力結果] ※1回目(1量子ビット目だけ, 0 -> 1 に変化したケース). q0=1 q1=0 q2=0 ※2回目(2量子ビット目だけ, 0 -> 1 に変化したケース). q0=0 q1=1 q2=0 ※3回目(1量子ビット目だけ, 0 -> 1 に変化したケース). q0=1 q1=0 q2=0 ※4回目(1量子ビット目, 2量子ビット目が, ともに, 0 -> 1 に変化したので, 2量子ビット目 と 3量子ビット目が入れ替わった). q0=1 q1=0 q2=1 ※5回目(1量子ビット目, 2量子ビット目が, ともに, 0 -> 1 に変化したので, 2量子ビット目 と 3量子ビット目が入れ替わった). q0=1 q1=0 q2=1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[編集内容(Simulator(sqrt X, CNOT))] import cirq import numpy as np from cirq import Simulator q0, q1 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0) def sqrt_x_cnot_circuit(meas=True): yield cirq.X(q0) ** 0.5 yield cirq.CNOT(q0, q1) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1') circuit = cirq.Circuit() circuit.append(sqrt_x_cnot_circuit(False)) simulator = Simulator() result = simulator.simulate(circuit, qubit_order=[q0, q1]) print(np.around(result.final_state_vector, 3)) |
1 2 |
[出力結果] [0.5+0.5j 0. +0.j 0. +0.j 0.5-0.5j] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[編集内容(Simulator(sqrt X, sqrt X, CSWAP))] import cirq import numpy as np from cirq import Simulator q0, q1, q2 = cirq.GridQubit(0, 0), cirq.GridQubit(1, 0), cirq.GridQubit(2, 0) def sqrt_x_sqrt_x_cswap_circuit(meas=True): yield cirq.X(q0) ** 0.6 yield cirq.X(q1) ** 0.6 yield cirq.CSWAP(q0, q1, q2) if meas: yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1'), cirq.measure(q2, key='q2') circuit = cirq.Circuit() circuit.append(sqrt_x_sqrt_x_cswap_circuit(False)) simulator = Simulator() result = simulator.simulate(circuit, qubit_order=[q0, q1, q2]) print(np.around(result.final_state_vector, 3)) |
1 2 3 |
[出力結果] [-0.107+0.329j 0. +0.j 0.452+0.147j 0. +0.j 0.452+0.147j 0.202-0.622j 0. +0.j 0. +0.j ] |