概要
- Cirq について, Optimizers, Decompositions に関するサンプルをいくつか動かしてみた.
- 動作環境は, Google Colaboratory で行った
感想
- 量子物理学に関する知識(用語, 数式の意味ほか)は, 徐々に身につけていく必要があると感じた.
- 時間を見つけて, 今後も, ドキュメントの残りの部分を進めていこうと思う.
Circuit optimizers
Momentの個数を削減することが出来る場合があるとのこと
- Circuit optimizers を 使う サンプル
- Circuit optimizers を 使う サンプル
- Circuit optimizers を 使う サンプル
1 2 3 4 5 6 7 8 9 10 11 12 |
[編集内容(Circuit optimizers)] import cirq # Moment の 個数 を 削減できるケース. c = cirq.Circuit() c.append(cirq.Moment([])) c.append(cirq.Moment([cirq.X(cirq.GridQubit(1, 1))])) c.append(cirq.Moment([])) print(f'Before optimization, Circuit has {len(c)} moments') cirq.DropEmptyMoments().optimize_circuit(circuit=c) print(f'After optimization, Circuit has {len(c)} moments') |
1 2 3 |
[出力結果] Before optimization, Circuit has 3 moments After optimization, Circuit has 1 moments |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[編集内容(Circuit optimizers)] import cirq # Moment の 個数 を 削減できないケース. c = cirq.Circuit() q0, q1 = cirq.GridQubit(0, 0), cirq.GridQubit(0, 1) c.append(cirq.Moment(cirq.SWAP(q0, q1))) c.append(cirq.Moment(cirq.SWAP(q0, q1))) c.append(cirq.Moment(cirq.SWAP(q0, q1))) print(f'Before optimization, Circuit has {len(c)} moments') cirq.DropEmptyMoments().optimize_circuit(circuit=c) print(f'After optimization, Circuit has {len(c)} moments') |
1 2 3 |
[出力結果] Before optimization, Circuit has 3 moments After optimization, Circuit has 3 moments |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[編集内容(Circuit optimizers)] import cirq # Moment の 個数 を 削減できるケース. c = cirq.Circuit() c.append(cirq.SWAP(q, q + 1) for q in cirq.LineQubit.range(3)) c.append([cirq.Moment()]) c.append([cirq.Moment()]) print(f'Before optimization, Circuit has {len(c)} moments') cirq.DropEmptyMoments().optimize_circuit(circuit=c) print(f'After optimization, Circuit has {len(c)} moments') |
1 2 3 |
[出力結果] Before optimization, Circuit has 5 moments After optimization, Circuit has 3 moments |
Decompositions
量子回路を変形することができる
- Decompositions を 使う サンプル
- Decompositions を 使う サンプル
- Decompositions を 使う サンプル
1 2 3 4 5 6 7 8 9 10 11 12 |
[編集内容(Decompositions)] import cirq c1, c2 = cirq.Circuit(), cirq.Circuit() q0 = cirq.GridQubit(0, 0) c1.append(cirq.H(q0)) print('Before Decompositions:\n', c1) c2.append(cirq.H(q0)) print('After Decompositions:\n', cirq.Circuit(cirq.decompose(c2))) |
1 2 3 4 5 |
[出力結果] Before Decompositions: (0, 0): ───H─── After Decompositions: (0, 0): ───Y^0.5───X─── |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[編集内容(Decompositions)] import cirq c1, c2 = cirq.Circuit(), cirq.Circuit() q0, q1 = cirq.GridQubit(0, 0), cirq.GridQubit(0, 1) c1.append(cirq.X(q0)) c1.append(cirq.CNOT(q0, q1)) print('Before Decompositions:\n', c1) c2.append(cirq.X(q0)) c2.append(cirq.CNOT(q0, q1)) print('After Decompositions:\n', cirq.Circuit(cirq.decompose(c2))) |
1 2 3 4 5 6 7 8 9 |
[出力結果] Before Decompositions: (0, 0): ───X───@─── │ (0, 1): ───────X─── After Decompositions: (0, 0): ───X────────@─────────── │ (0, 1): ───Y^-0.5───@───Y^0.5─── |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[編集内容(Decompositions)] import cirq c1, c2 = cirq.Circuit(), cirq.Circuit() q0, q1, q2 = cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(0, 2) c1.append(cirq.X(q0)) c1.append(cirq.X(q1)) c1.append(cirq.CCNOT(q0, q1, q2)) print('Before Decompositions:\n', c1) c2.append(cirq.X(q0)) c2.append(cirq.X(q1)) c2.append(cirq.CCNOT(q0, q1, q2)) print('After Decompositions:\n', cirq.Circuit(cirq.decompose(c2))) |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[出力結果] Before Decompositions: (0, 0): ───X───@─── │ (0, 1): ───X───@─── │ (0, 2): ───────X─── After Decompositions: (0, 0): ───X───────T────────────@─────────────────────────────────────@─────────────────────────────@────────────────────────────@─────────────────────────────────────── │ │ │ │ (0, 1): ───X───────T───Y^-0.5───@────────Y^0.5───@───T^-1────Y^-0.5───@────────Y^0.5───@───Y^-0.5───@──────Y^0.5────@───Y^-0.5───@──────Y^0.5────@─────────────────────── │ │ │ │ (0, 2): ───Y^0.5───X───T────────Y^-0.5───────────@───Y^0.5───T────────Y^-0.5───────────@───Y^0.5────T^-1───Y^-0.5───@───Y^0.5────T^-1───Y^-0.5───@───Y^0.5───Y^0.5───X─── |
Create your own optimizers
例えば, 測定を後から外すことも出来るとのこと
- Create your own optimizers を 使う サンプル
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 |
[編集内容(Create your own optimizers)] import cirq class RemoveMeasurements(cirq.PointOptimizer): def optimization_at(self, circuit: cirq.Circuit, index: int, op: cirq.Operation): if isinstance(op.gate, cirq.MeasurementGate): return cirq.PointOptimizationSummary(clear_span=1, new_operations=[], clear_qubits=op.qubits) else: return None q0, q1, q2 = cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2) c = cirq.Circuit() c.append(cirq.X(q0)) c.append(cirq.X(q1)) c.append(cirq.CCNOT(q0, q1, q2)) c.append(cirq.CSWAP(q1, q2, q0)) c.append(cirq.measure(q0, key='result 0')) c.append(cirq.measure(q1, key='result 1')) c.append(cirq.measure(q2, key='result 2')) print('Before optimization') print(c) RemoveMeasurements().optimize_circuit(c) print('After optimization') print(c) |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[出力結果] Before optimization 0: ───X───@───×───M('result 0')─── │ │ 1: ───X───@───@───M('result 1')─── │ │ 2: ───────X───×───M('result 2')─── After optimization 0: ───X───@───×─────── │ │ 1: ───X───@───@─────── │ │ 2: ───────X───×─────── |