概要
- Cirq について, Custom Gates に関するサンプルをいくつか動かしてみた.
- 動作環境は, Google Colaboratory で行った
感想
- 量子物理学に関する知識(用語, 数式の意味ほか)は, 徐々に身につけていく必要があると感じた.
- 時間を見つけて, 今後も, ドキュメントの残りの部分を進めていこうと思う.
With parameters
- RotationGate を 使う サンプル
- decomposition を 使う サンプル
- decomposition を 使う サンプル
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
[編集内容(RotationGate)] import numpy as np import cirq """Define a custom gate with a parameter.""" class RotationGate(cirq.Gate): def __init__(self, theta): super(RotationGate, self) self.theta = theta def _num_qubits_(self): return 1 def _unitary_(self): return np.array([ [np.cos(self.theta), np.sin(self.theta)], [np.sin(self.theta), -np.cos(self.theta)] ]) / np.sqrt(2) def _circuit_diagram_info_(self, args): return f"R({self.theta})" # Pick two qubits. q0, q1 = cirq.GridQubit(0, 1), cirq.GridQubit(2, 3) # 以下のように理解. # 1. ↑↑(2量子ビット, 00 と見る) を 用意. # 2. 1量子ビット目に, X ゲート を 操作. # ※ 1量子ビット目が, ↑ もしくは ↓ に 変わるはず. # 3. 2量子ビット目に, X ゲート を 操作. # ※ 2量子ビット目が, ↑ もしくは ↓ に 変わるはず. # -> 1量子ビット目, 2量子ビット目の操作結果によって, # ↑↑(00, つまり, q0 = 0, q1 = 0), ↑↓(01, つまり, q0 = 0, q1 = 1), # ↓↑(10, つまり, q0 = 1, q1 = 0), ↓↓(11, つまり, q0 = 1, q1 = 1) の 4種類 の 出力結果があり得る. """Use the custom gate in a circuit.""" for y in range(5): circuit = cirq.Circuit() op_1 = RotationGate(theta = np.around(0.1 * (y + 1), 3)).on(q0) op_2 = RotationGate(theta = np.around(0.2 * (y + 1), 3)).on(q1) circuit.append([op_1, op_2]) circuit.append([cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1')]) print("Circuit with a custom rotation gate: ", y, "times") print(circuit) # Simulate 10 times. simulator = cirq.Simulator() results = simulator.run(circuit, repetitions=10) # Output result. print(results) print("") |
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 33 34 35 36 |
[出力結果] Circuit with a custom rotation gate: 0 times (0, 1): ───R(0.1)───M('q0')─── (2, 3): ───R(0.2)───M('q1')─── q0=0000000000 q1=0010000000 Circuit with a custom rotation gate: 1 times (0, 1): ───R(0.2)───M('q0')─── (2, 3): ───R(0.4)───M('q1')─── q0=0000000000 q1=0000100010 Circuit with a custom rotation gate: 2 times (0, 1): ───R(0.3)───M('q0')─── (2, 3): ───R(0.6)───M('q1')─── q0=0100000000 q1=0000000100 Circuit with a custom rotation gate: 3 times (0, 1): ───R(0.4)───M('q0')─── (2, 3): ───R(0.8)───M('q1')─── q0=0000000000 q1=1000110101 Circuit with a custom rotation gate: 4 times (0, 1): ───R(0.5)───M('q0')─── (2, 3): ───R(1.0)───M('q1')─── q0=0100010000 q1=1011111111 -> シュミレート結果 は, プログラム実行ごとに違った値が出力される. |
From a known decomposition
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 33 34 35 36 37 38 39 40 |
[編集内容(decomposition)] import numpy as np import cirq class MySwap(cirq.TwoQubitGate): def __init__(self): super(MySwap, self) def _decompose_(self, qubits): a, b = qubits yield cirq.CNOT(a, b) yield cirq.CNOT(b, a) yield cirq.CNOT(a, b) def _circuit_diagram_info_(self, args): return ["CustomSWAP"] * self.num_qubits() my_swap = MySwap() # Pick two qubits. q = [cirq.GridQubit(0, 1), cirq.GridQubit(2, 3)] """Use the custom gate in a circuit.""" for y in range(3): circuit = cirq.Circuit() op_1 = cirq.X(q[0]) ** 0.52 # TypeError: on() argument after * must be an iterable, not GridQubit op_2 = my_swap.on(*q) circuit.append([op_1, op_2]) circuit.append([cirq.measure(q[0], key='q0'), cirq.measure(q[1], key='q1')]) print("Circuit: ", y, "times") print(circuit) # Simulate 10 times. simulator = cirq.Simulator() results = simulator.run(circuit, repetitions=10) # Output result. print(results) print("") |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[出力結果] Circuit: 0 times (0, 1): ───X^0.52───CustomSWAP───M('q0')─── │ (2, 3): ────────────CustomSWAP───M('q1')─── q0=0000000000 q1=0001111011 Circuit: 1 times (0, 1): ───X^0.52───CustomSWAP───M('q0')─── │ (2, 3): ────────────CustomSWAP───M('q1')─── q0=0000000000 q1=0000100101 Circuit: 2 times (0, 1): ───X^0.52───CustomSWAP───M('q0')─── │ (2, 3): ────────────CustomSWAP───M('q1')─── q0=0000000000 q1=0111001011 -> シュミレート結果 は, プログラム実行ごとに違った値が出力される. |
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 33 34 35 36 37 38 39 |
[編集内容(decomposition)] import numpy as np import cirq class MyCCNOT(cirq.ThreeQubitGate): def __init__(self): super(MyCCNOT, self) def _decompose_(self, qubits): a, b, c = qubits yield cirq.CCNOT(a, b, c) yield cirq.CCNOT(c, b, a) def _circuit_diagram_info_(self, args): return ["Custom CCNOT"] * self.num_qubits() my_ccnot = MyCCNOT() # Pick three qubits. q = [cirq.GridQubit(0, 1), cirq.GridQubit(1, 2), cirq.GridQubit(2, 3)] """Use the custom gate in a circuit.""" for y in range(3): circuit = cirq.Circuit() op_1, op_2 = cirq.X(q[0]) ** 0.5, cirq.X(q[1]) ** 0.6 # TypeError: on() argument after * must be an iterable, not GridQubit op_3 = my_ccnot.on(*q) circuit.append([op_1, op_2, op_3]) circuit.append([cirq.measure(q[0], key='q0'), cirq.measure(q[1], key='q1'), cirq.measure(q[2], key='q2')]) print("Circuit: ", y, "times") print(circuit) # Simulate 10 times. simulator = cirq.Simulator() results = simulator.run(circuit, repetitions=10) # Output result. print(results) print("") |
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 |
[出力結果] Circuit: 0 times (0, 1): ───X^0.5───Custom CCNOT───M('q0')─── │ (1, 2): ───X^0.6───Custom CCNOT───M('q1')─── │ (2, 3): ───────────Custom CCNOT───M('q2')─── q0=0000000000 q1=1111111011 q2=1110110000 Circuit: 1 times (0, 1): ───X^0.5───Custom CCNOT───M('q0')─── │ (1, 2): ───X^0.6───Custom CCNOT───M('q1')─── │ (2, 3): ───────────Custom CCNOT───M('q2')─── q0=0000000000 q1=1110101111 q2=1110101010 Circuit: 2 times (0, 1): ───X^0.5───Custom CCNOT───M('q0')─── │ (1, 2): ───X^0.6───Custom CCNOT───M('q1')─── │ (2, 3): ───────────Custom CCNOT───M('q2')─── q0=0000100001 q1=1110011110 q2=1000001010 -> シュミレート結果 は, プログラム実行ごとに違った値が出力される. |