{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 含参量子线路的等价性检查\n", "\n", "[](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.5.0/mindquantum/zh_cn/advanced/mindspore_equivalence_checking_of_PQC.ipynb) \n", "[](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.5.0/mindquantum/zh_cn/advanced/mindspore_equivalence_checking_of_PQC.py) \n", "[](https://gitee.com/mindspore/docs/blob/r2.5.0/docs/mindquantum/docs/source_zh_cn/advanced/equivalence_checking_of_PQC.ipynb)\n", "\n", "## 概述\n", "\n", "在量子设备上运行含参量子线路之前,需要将其编译成由该设备支持的量子门集组成的新线路。于是,需要对编译前后的两个线路进行等价性检查。论文Equivalence Checking of Parameterized Quantum Circuits中提出了一种基于ZX演算的含参量子线路等价性检查方法,本文尝试在MindSpore Quantum架构中复现论文中的方法。\n", "\n", "论文链接:https://doi.org/10.1145/3566097.3567932" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# 引入相关库\n", "from mindquantum.core.circuit import Circuit\n", "import numpy as np\n", "from mindquantum.core.gates import H, CNOT, RX, RZ\n", "from mindquantum.core.circuit import dagger" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第一步\n", "\n", "准备量子线路\n", "\n", "以Qiskit线路库中的TwoLocal线路为例。TwoLocal线路是由旋转层和纠缠层交替组成的含参线路,旋转层即作用在所有量子比特上的单量子门,纠缠层根据纠缠策略使用双量子门将量子比特纠缠起来。\n", "\n", "构造一个作用在127位量子比特上、由三组旋转层和纠缠层交替组成、纠缠策略为循环纠缠的TwoLocal线路,共包含508个参数。旋转层是作用在每一个量子比特上的含参[RX](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RX.html)门;循环纠缠层是由最后一个量子比特控制第一个量子比特的[CNOT](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.CNOTGate.html)门,以及依次由前一个量子比特控制后一个量子比特的[CNOT](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.CNOTGate.html)门。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "tags": [] }, "outputs": [], "source": [ "# 每一组旋转层和纠缠层的组合就是一层ansatz线路\n", "def build_ansatz(n_qubits, depth):\n", " circ = Circuit() # 初始化量子线路\n", "\n", " for i in range(depth):\n", " for j in range(n_qubits):\n", " circ += RX(f'theta{i*n_qubits+j}').on(j) # 每个量子比特上一个RX门\n", " circ += CNOT.on(0, n_qubits-1) # 最后一个量子比特和第一个量子比特上一个CNOT门\n", " for j in range(n_qubits-1):\n", " circ += CNOT.on(j+1, j) # 相邻两个量子比特上一个CNOT门,CNOT门作用在第j+1位,且受第j位控制\n", "\n", " for j in range(n_qubits):\n", " circ += RX(f'theta{depth*n_qubits+j}').on(j) # 每个量子比特上一个RX门\n", "\n", " return circ" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"476.8\" height=\"200.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect x=\"0\" y=\"0.0\" width=\"476.8\" height=\"200.0\" fill=\"#ffffff\" /><text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q0: </text><text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q1: </text><text x=\"20.0\" y=\"160.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q2: </text><line x1=\"48.8\" x2=\"456.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"456.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"456.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><rect x=\"72.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 </text><rect x=\"72.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta1 </text><rect x=\"72.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta2 </text><circle cx=\"192.8\" cy=\"160.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"192.8\" x2=\"192.8\" y1=\"40.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"172.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"178.8\" x2=\"206.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"192.8\" x2=\"192.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"252.8\" cy=\"40.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"252.8\" x2=\"252.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"232.8\" y=\"80.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"238.8\" x2=\"266.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"252.8\" x2=\"252.8\" y1=\"86.0\" y2=\"114.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"312.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"292.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"298.8\" x2=\"326.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"292.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"332.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"332.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta3 </text><rect x=\"352.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"392.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"392.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta4 </text><rect x=\"352.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"392.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"392.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta5 </text></svg>" ], "text/plain": [ "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x7f09d84ffeb0>" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 作用在3个量子比特上的一层ansatz线路示例\n", "build_ansatz(3, 1).svg()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ff0000; text-decoration-color: #ff0000; font-weight: bold\"> Circuit Summary </span>\n", "╭───────────────────────┬───────────────────────────────────────────────────────────────────╮\n", "│<span style=\"font-weight: bold\"> </span><span style=\"color: #3b3b95; text-decoration-color: #3b3b95; font-weight: bold\">Info</span><span style=\"font-weight: bold\"> </span>│<span style=\"font-weight: bold\"> </span><span style=\"color: #3b3b95; text-decoration-color: #3b3b95; font-weight: bold\">value</span><span style=\"font-weight: bold\"> </span>│\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Number of qubit</span> │ 127 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Total number of gate</span> │ 889 │\n", "│ Barrier │ 0 │\n", "│ Noise Channel │ 0 │\n", "│ Measurement │ 0 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Parameter gate</span> │ 508 │\n", "│ 508 ansatz parameters │ <span style=\"color: #48c9b0; text-decoration-color: #48c9b0\">theta0, theta1, theta2, theta3, theta4, theta5, theta6, theta7, </span> │\n", "│ │ <span style=\"color: #48c9b0; text-decoration-color: #48c9b0\">theta8, theta9...</span> │\n", "╰───────────────────────┴───────────────────────────────────────────────────────────────────╯\n", "</pre>\n" ], "text/plain": [ "\u001b[1;38;2;255;0;0m Circuit Summary \u001b[0m\n", "╭───────────────────────┬───────────────────────────────────────────────────────────────────╮\n", "│\u001b[1m \u001b[0m\u001b[1;38;2;59;59;149mInfo\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1;38;2;59;59;149mvalue\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m│\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mNumber of qubit\u001b[0m │ 127 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mTotal number of gate\u001b[0m │ 889 │\n", "│ Barrier │ 0 │\n", "│ Noise Channel │ 0 │\n", "│ Measurement │ 0 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mParameter gate\u001b[0m │ 508 │\n", "│ 508 ansatz parameters │ \u001b[38;2;72;201;176mtheta0, theta1, theta2, theta3, theta4, theta5, theta6, theta7, \u001b[0m │\n", "│ │ \u001b[38;2;72;201;176mtheta8, theta9...\u001b[0m │\n", "╰───────────────────────┴───────────────────────────────────────────────────────────────────╯\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 初始线路共3层,作用在127个量子比特上\n", "n_qubits = 127\n", "depth = 3\n", "circ1 = build_ansatz(n_qubits, depth)\n", "circ1.summary() # 总结初始线路" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "接下来对初始量子线路进行编译。\n", "\n", "假设编译前的量子门集为:[H](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.HGate.html)、[CNOT](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.CNOTGate.html)、[RZ](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RZ.html)、[RX](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RX.html);编译后的量子门集为:[H](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.HGate.html)、[CNOT](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.CNOTGate.html)、[RZ](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RZ.html)。编译规则是[H](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.HGate.html)、[CNOT](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.CNOTGate.html)、[RZ](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RZ.html)门保持不变,将[RX](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RX.html)门编译成[H](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.HGate.html)、[RZ](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RZ.html)、[H](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.HGate.html)的组合。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def compile_circuit(circ):\n", " circ_compiled = Circuit()\n", "\n", " for gate in circ: # 遍历初始线路中的量子门\n", " # H,CNOT,RZ门保持不变\n", " if gate.name == 'H' or gate.name == 'CNOT' or gate.name == 'RZ':\n", " circ_compiled += gate\n", " elif gate.name == 'RX': # RX门经过编译变成H*RZ*H\n", " circ_compiled += H.on(gate.obj_qubits)\n", " circ_compiled += RZ(gate.coeff).on(gate.obj_qubits)\n", " circ_compiled += H.on(gate.obj_qubits)\n", "\n", " return circ_compiled" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"716.8\" height=\"200.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect x=\"0\" y=\"0.0\" width=\"716.8\" height=\"200.0\" fill=\"#ffffff\" /><text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q0: </text><text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q1: </text><text x=\"20.0\" y=\"160.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q2: </text><line x1=\"48.8\" x2=\"696.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"696.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"696.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><rect x=\"72.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"92.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"132.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"172.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"172.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 </text><rect x=\"232.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"252.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"72.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"92.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"132.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"172.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"172.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta1 </text><rect x=\"232.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"252.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"72.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"92.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"132.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"172.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"172.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta2 </text><rect x=\"232.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"252.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><circle cx=\"312.8\" cy=\"160.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"40.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"292.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"298.8\" x2=\"326.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"372.8\" cy=\"40.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"372.8\" x2=\"372.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"352.8\" y=\"80.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"358.8\" x2=\"386.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"372.8\" x2=\"372.8\" y1=\"86.0\" y2=\"114.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"432.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"432.8\" x2=\"432.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"412.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"418.8\" x2=\"446.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"432.8\" x2=\"432.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"412.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"432.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"472.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"512.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"512.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta3 </text><rect x=\"572.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"592.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"472.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"492.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"532.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"572.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"572.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta4 </text><rect x=\"632.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"652.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"472.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"492.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"532.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"572.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"572.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta5 </text><rect x=\"632.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"652.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text></svg>" ], "text/plain": [ "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x7f09d84f23d0>" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 一层ansatz线路编译后生成的线路示例,可以看到,所有RX门都根据编译规则发生了变化\n", "compile_circuit(build_ansatz(3, 1)).svg()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ff0000; text-decoration-color: #ff0000; font-weight: bold\"> Circuit Summary </span>\n", "╭───────────────────────┬───────────────────────────────────────────────────────────────────╮\n", "│<span style=\"font-weight: bold\"> </span><span style=\"color: #3b3b95; text-decoration-color: #3b3b95; font-weight: bold\">Info</span><span style=\"font-weight: bold\"> </span>│<span style=\"font-weight: bold\"> </span><span style=\"color: #3b3b95; text-decoration-color: #3b3b95; font-weight: bold\">value</span><span style=\"font-weight: bold\"> </span>│\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Number of qubit</span> │ 127 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Total number of gate</span> │ 1905 │\n", "│ Barrier │ 0 │\n", "│ Noise Channel │ 0 │\n", "│ Measurement │ 0 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Parameter gate</span> │ 508 │\n", "│ 508 ansatz parameters │ <span style=\"color: #48c9b0; text-decoration-color: #48c9b0\">theta0, theta1, theta2, theta3, theta4, theta5, theta6, theta7, </span> │\n", "│ │ <span style=\"color: #48c9b0; text-decoration-color: #48c9b0\">theta8, theta9...</span> │\n", "╰───────────────────────┴───────────────────────────────────────────────────────────────────╯\n", "</pre>\n" ], "text/plain": [ "\u001b[1;38;2;255;0;0m Circuit Summary \u001b[0m\n", "╭───────────────────────┬───────────────────────────────────────────────────────────────────╮\n", "│\u001b[1m \u001b[0m\u001b[1;38;2;59;59;149mInfo\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1;38;2;59;59;149mvalue\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m│\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mNumber of qubit\u001b[0m │ 127 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mTotal number of gate\u001b[0m │ 1905 │\n", "│ Barrier │ 0 │\n", "│ Noise Channel │ 0 │\n", "│ Measurement │ 0 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mParameter gate\u001b[0m │ 508 │\n", "│ 508 ansatz parameters │ \u001b[38;2;72;201;176mtheta0, theta1, theta2, theta3, theta4, theta5, theta6, theta7, \u001b[0m │\n", "│ │ \u001b[38;2;72;201;176mtheta8, theta9...\u001b[0m │\n", "╰───────────────────────┴───────────────────────────────────────────────────────────────────╯\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 编译初始线路\n", "circ2 = compile_circuit(circ1)\n", "circ2.summary() # 总结编译线路" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "最后构造完整的量子线路。\n", "\n", "根据量子线路的可逆性可知,若两个线路功能等价,那么将一个线路作用到量子比特上,再将另一个线路的逆线路作用到量子比特上,最终得到的量子态与两次作用之前的量子态等价。于是,完整的量子线路由编译后的线路和初始线路的逆线路组成。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ff0000; text-decoration-color: #ff0000; font-weight: bold\"> Circuit Summary </span>\n", "╭───────────────────────┬───────────────────────────────────────────────────────────────────╮\n", "│<span style=\"font-weight: bold\"> </span><span style=\"color: #3b3b95; text-decoration-color: #3b3b95; font-weight: bold\">Info</span><span style=\"font-weight: bold\"> </span>│<span style=\"font-weight: bold\"> </span><span style=\"color: #3b3b95; text-decoration-color: #3b3b95; font-weight: bold\">value</span><span style=\"font-weight: bold\"> </span>│\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Number of qubit</span> │ 127 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Total number of gate</span> │ 2794 │\n", "│ Barrier │ 0 │\n", "│ Noise Channel │ 0 │\n", "│ Measurement │ 0 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ <span style=\"font-weight: bold\">Parameter gate</span> │ 1016 │\n", "│ 508 ansatz parameters │ <span style=\"color: #48c9b0; text-decoration-color: #48c9b0\">theta507, theta506, theta505, theta504, theta503, theta502, </span> │\n", "│ │ <span style=\"color: #48c9b0; text-decoration-color: #48c9b0\">theta501, theta500, theta499, theta498...</span> │\n", "╰───────────────────────┴───────────────────────────────────────────────────────────────────╯\n", "</pre>\n" ], "text/plain": [ "\u001b[1;38;2;255;0;0m Circuit Summary \u001b[0m\n", "╭───────────────────────┬───────────────────────────────────────────────────────────────────╮\n", "│\u001b[1m \u001b[0m\u001b[1;38;2;59;59;149mInfo\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1;38;2;59;59;149mvalue\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m│\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mNumber of qubit\u001b[0m │ 127 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mTotal number of gate\u001b[0m │ 2794 │\n", "│ Barrier │ 0 │\n", "│ Noise Channel │ 0 │\n", "│ Measurement │ 0 │\n", "├───────────────────────┼───────────────────────────────────────────────────────────────────┤\n", "│ \u001b[1mParameter gate\u001b[0m │ 1016 │\n", "│ 508 ansatz parameters │ \u001b[38;2;72;201;176mtheta507, theta506, theta505, theta504, theta503, theta502, \u001b[0m │\n", "│ │ \u001b[38;2;72;201;176mtheta501, theta500, theta499, theta498...\u001b[0m │\n", "╰───────────────────────┴───────────────────────────────────────────────────────────────────╯\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 完整线路\n", "circ1_inv = dagger(circ1) # dagger()将量子线路左右逆转,得到初始线路的逆线路\n", "circ_all = circ1_inv + circ2 # 完整线路=初始线路的逆线路+编译后的线路\n", "circ_all.summary() # 总结完整线路" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第二步\n", "\n", "将完整的量子线路转换成ZX图。\n", "\n", "含参量子线路等价性检查方法基于ZX演算实现,需要将量子线路转换成ZX图。\n", "\n", "量子门是ZX图中的顶点,分为3种颜色,[H](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.HGate.html)门表示成黄色顶点,[RX](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RX.html)门表示成含参的红色顶点,[RZ](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.RZ.html)门表示成含参的绿色顶点,[CNOT](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.CNOTGate.html)门的受控位表示成红色顶点,控制位表示成绿色顶点,受控位与控制位的顶点互为邻居。同一个量子比特上相邻两个量子门的顶点互为邻居。\n", "\n", "先定义顶点类和图类。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# 顶点类\n", "class Vertex:\n", " def __init__(self, name, color, qubit, neighbor, phase=0.0):\n", " self.name = name # 量子门顶点的序号\n", " self.color = color # 量子门顶点的颜色\n", " self.phase = phase # 含参量子门的参数\n", " self.qubit = qubit # 作用在哪个量子比特上\n", " self.neighbor = neighbor # 顶点之间的邻居关系" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# 图类\n", "class Graph:\n", " def __init__(self):\n", " self.vertices = {} # 初始图,空\n", " self.count = 0 # 顶点总数,只增不减,也用于给新顶点命名\n", "\n", " # 新增边\n", " def add_edge(self, from_vertex, to_vertex): # 添加一条从起点到终点的边\n", " self.vertices[from_vertex].neighbor.append(to_vertex)\n", "\n", " # 新增顶点\n", " def add_vertex(self, color, qubit, neighbor, phase=0.0):\n", " name = self.count\n", " self.count += 1\n", " # 添加从新顶点到相邻顶点的边\n", " self.vertices[name] = Vertex(name, color, qubit, neighbor, phase)\n", " for v in neighbor: # 再添加从相邻顶点到新顶点的边\n", " self.add_edge(v, name)\n", "\n", " # 打印图信息\n", " def print(self):\n", " print(\"==================graph message==================\")\n", " for v in self.vertices.values():\n", " print(v.name, '\\t', v.neighbor, '\\t', v.color, '\\t', v.phase)\n", " print('\\n')\n", "\n", " # 删除自身的环\n", " # 省略了ZX图的无环规则(本文中,所有“无环”均指不存在单条边构成的环)\n", " def clear(self):\n", " for v in self.vertices.values():\n", " while v.name in v.neighbor:\n", " # 将本顶点从自己的邻居中删除\n", " self.vertices[v.name].neighbor.remove(v.name)\n", "\n", " # 删除顶点\n", " def delete_vertex(self, name):\n", " for v in self.vertices.values():\n", " while name in v.neighbor: # 删除终点是该顶点的边\n", " self.vertices[v.name].neighbor.remove(name)\n", " self.vertices.pop(name) # 删除起点是该顶点的边\n", "\n", " # 两个电路是否等价\n", " def equiv(self):\n", " if not self.vertices: # 等价的两个电路,经过ZX演算化简后,图中无顶点\n", " print(\"Equivalent!\")\n", " else:\n", " print(\"Not sure!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "接下来将量子线路绘制成ZX图。\n", "\n", "遍历线路中的所有量子门,并依次将其绘制成ZX图中的顶点。若当前量子比特上暂无量子门,则当前的量子门暂无邻居;若当前量子比特上已有量子门,则当前的量子门与该量子比特上最后一个量子门互为邻居;[CNOT](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.10/core/gates/mindquantum.core.gates.CNOTGate.html)门在绘制时就添加了控制位与受控位顶点之间的邻居关系。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def draw_graph(circ):\n", " g = Graph() # 初始化一个空图\n", " last_name = [-1] * circ.n_qubits # last_name保存每个量子比特上当前的最后一个顶点\n", " for gate in circ: # 遍历线路中的所有量子门\n", " if gate.name == 'H': # H门绘制成黄色顶点\n", " if last_name[gate.obj_qubits[0]] != -1: # 当前量子比特上已有顶点\n", " g.add_vertex('yellow', gate.obj_qubits[0],\n", " [last_name[gate.obj_qubits[0]]])\n", " else: # 当前量子比特上暂无顶点\n", " g.add_vertex('yellow', gate.obj_qubits[0], [])\n", " last_name[gate.obj_qubits[0]] = g.count-1 # 更新当前量子比特上最后一个顶点为新增顶点\n", " if gate.name == 'RX': # RX门绘制成红色顶点\n", " if last_name[gate.obj_qubits[0]] != -1:\n", " g.add_vertex('red', gate.obj_qubits[0],\n", " [last_name[gate.obj_qubits[0]]], gate.coeff)\n", " else:\n", " g.add_vertex('red', gate.obj_qubits[0], [], gate.coeff)\n", " last_name[gate.obj_qubits[0]] = g.count-1\n", " if gate.name == 'RZ': # RZ门绘制成绿色顶点\n", " if last_name[gate.obj_qubits[0]] != -1:\n", " g.add_vertex('green', gate.obj_qubits[0],\n", " [last_name[gate.obj_qubits[0]]], gate.coeff)\n", " else:\n", " g.add_vertex('green', gate.obj_qubits[0], [], gate.coeff)\n", " last_name[gate.obj_qubits[0]] = g.count-1\n", " if gate.name == 'CNOT': # CNOT门要分别绘制控制位顶点和受控位顶点\n", " # 绘制控制位顶点,绿色\n", " if last_name[gate.obj_qubits[1]] != -1:\n", " g.add_vertex('green', gate.obj_qubits[1],\n", " [last_name[gate.obj_qubits[1]]])\n", " else:\n", " g.add_vertex('green', gate.obj_qubits[1], [])\n", " last_name[gate.obj_qubits[1]] = g.count-1\n", " # 绘制受控位顶点,红色\n", " if last_name[gate.obj_qubits[0]] != -1:\n", " g.add_vertex('red', gate.obj_qubits[0],\n", " [last_name[gate.obj_qubits[0]], g.count-1])\n", " else:\n", " g.add_vertex('red', gate.obj_qubits[0], [g.count-1])\n", " last_name[gate.obj_qubits[0]] = g.count-1\n", " return g" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "最后,将第一步构造好的完整量子线路绘制成ZX图。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "tags": [] }, "outputs": [], "source": [ "g = draw_graph(circ_all)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第三步\n", "\n", "化简ZX图。\n", "\n", "ZX演算由ZX图和化简规则组成,根据化简规则,对ZX图中的顶点和邻居关系进行化简。\n", "\n", "以下列出部分规则,具体实现过程即图和顶点的相关操作,只举例说明,不再一一赘述。\n", "\n", "规则1:不与其他量子比特上的顶点相邻的、参数为0的红色或绿色顶点可以删除。\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "def rule_1(g: Graph):\n", " for v1 in list(g.vertices.keys()): # ZX演算过程中,图中的顶点会发生增减,用list()获取最初的所有顶点\n", " if v1 not in g.vertices.keys(): # 判断当前顶点在化简过程中有没有被删除\n", " continue # 已被删除,略过\n", " v1 = g.vertices[v1]\n", " # 顶点参数为0\n", " if v1.phase == 0 or list(v1.phase.values()) == [0.0]*len(list(v1.phase.values())):\n", " flag = True # 用于判断当前顶点是否与其他量子比特上的顶点相关,如果相关,暂时不能删除\n", " for v2 in v1.neighbor:\n", " v2 = g.vertices[v2]\n", " if v2.qubit != v1.qubit: # 与其他量子比特上的顶点相关\n", " flag = False\n", " break\n", " if flag: # 与其他量子比特上的顶点无关\n", " for v2 in v1.neighbor:\n", " v2 = g.vertices[v2]\n", " v2.neighbor.extend(v1.neighbor) # 将前一个顶点与后一个顶点相连,略过当前顶点\n", " g.clear() # 清除化简过程中可能产生的环\n", " g.delete_vertex(v1.name) # 删除该顶点" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "规则2:相邻的、相同颜色的红色或绿色顶点可以合并。\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "def rule_2(g: Graph):\n", " for v1 in list(g.vertices.keys()):\n", " if v1 not in g.vertices.keys():\n", " continue\n", " v1 = g.vertices[v1]\n", " if v1.color == 'red' or v1.color == 'green': # 红色或绿色顶点\n", " for v2 in v1.neighbor: # 相邻\n", " v2 = g.vertices[v2]\n", " if v2.color == v1.color: # 相同颜色\n", " v2.phase = v2.phase + v1.phase # 参数相加\n", " v2.neighbor.extend(v1.neighbor) # 合并两个顶点\n", " g.clear()\n", " for v3 in v1.neighbor: # 更新合并顶点后的邻居关系\n", " v3 = g.vertices[v3]\n", " v3.neighbor.append(v2.name)\n", " g.clear()\n", " g.delete_vertex(v1.name) # 删除已被合并的顶点" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "规则3:所有邻居都是黄色顶点的绿色顶点,可以变成红色顶点,并删除相邻的黄色顶点。\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "def rule_3(g: Graph):\n", " for v1 in list(g.vertices.keys()):\n", " if v1 not in g.vertices.keys():\n", " continue\n", " v1 = g.vertices[v1]\n", " if v1.color == 'green':\n", " flag = True # 用于判断是否所有邻居都是黄色\n", " for v2 in v1.neighbor:\n", " v2 = g.vertices[v2]\n", " if v2.color != 'yellow': # 不满足所有邻居都是黄色\n", " flag = False\n", " break\n", " if flag: # 所有邻居都是黄色\n", " v1.color = 'red' # 变成红色\n", " v1_neighbor = list(v1.neighbor)\n", " for v2 in v1_neighbor: # 删除这些黄色顶点\n", " v2 = g.vertices[v2]\n", " v1.neighbor.extend(v2.neighbor)\n", " g.clear()\n", " for v3 in v2.neighbor:\n", " v3 = g.vertices[v3]\n", " v3.neighbor.append(v1.name)\n", " g.clear()\n", " g.delete_vertex(v2.name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "规则 4:相邻的、存在两条边的红绿顶点,可以删除这两条边。\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def rule_4(g: Graph):\n", " for v1 in list(g.vertices.keys()):\n", " if v1 not in g.vertices.keys():\n", " continue\n", " v1 = g.vertices[v1]\n", " if v1.color == 'green':\n", " for v2 in v1.neighbor:\n", " v2 = g.vertices[v2]\n", " # 红绿顶点,且两顶点间有两条边\n", " if v2.color == 'red' and v2.neighbor.count(v1.name) == 2:\n", " while v2.name in g.vertices[v1.name].neighbor: # 删除相连的边\n", " v1.neighbor.remove(v2.name)\n", " while v1.name in g.vertices[v2.name].neighbor:\n", " v2.neighbor.remove(v1.name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "接下来利用以上规则对ZX图进行循环化简,若某轮循环中没有删除任何顶点,则认为化简结束。" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "def simplify(g: Graph):\n", " temp = [] # 用于对比本轮循环是否有顶点被删除\n", " while temp != list(g.vertices.keys()): # 如果本轮循环没有删除任何顶点,则认为化简结束,退出循环\n", " temp = list(g.vertices.keys())\n", " rule_3(g)\n", " rule_2(g)\n", " rule_4(g)\n", " rule_1(g)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "完整线路规模较大,可以先构造一个作用在三个量子比特上的单层线路进行测试。" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1096.8\" height=\"200.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect x=\"0\" y=\"0.0\" width=\"1096.8\" height=\"200.0\" fill=\"#ffffff\" /><text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q0: </text><text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q1: </text><text x=\"20.0\" y=\"160.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q2: </text><line x1=\"48.8\" x2=\"1076.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"1076.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"1076.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><rect x=\"72.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta5 </text><rect x=\"72.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta4 </text><rect x=\"72.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta3 </text><circle cx=\"192.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"192.8\" x2=\"192.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"172.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"178.8\" x2=\"206.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"192.8\" x2=\"192.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"252.8\" cy=\"40.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"252.8\" x2=\"252.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"232.8\" y=\"80.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"238.8\" x2=\"266.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"252.8\" x2=\"252.8\" y1=\"86.0\" y2=\"114.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"312.8\" cy=\"160.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"40.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"292.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"298.8\" x2=\"326.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"352.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"392.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"392.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta2 </text><rect x=\"352.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"392.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"392.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta1 </text><rect x=\"352.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"392.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"392.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta0 </text><rect x=\"452.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"472.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"512.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"552.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"552.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 </text><rect x=\"612.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"632.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"452.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"472.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"512.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"552.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"552.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta1 </text><rect x=\"612.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"632.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"452.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"472.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"512.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"552.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"552.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta2 </text><rect x=\"612.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"632.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><circle cx=\"692.8\" cy=\"160.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"692.8\" x2=\"692.8\" y1=\"40.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"672.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"678.8\" x2=\"706.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"692.8\" x2=\"692.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"752.8\" cy=\"40.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"752.8\" x2=\"752.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"732.8\" y=\"80.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"738.8\" x2=\"766.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"752.8\" x2=\"752.8\" y1=\"86.0\" y2=\"114.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"812.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"812.8\" x2=\"812.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"792.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"798.8\" x2=\"826.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"812.8\" x2=\"812.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"792.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"812.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"852.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"892.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"892.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta3 </text><rect x=\"952.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"972.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"852.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"872.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"912.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"952.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"952.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta4 </text><rect x=\"1012.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"1032.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"852.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"872.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"912.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"952.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"952.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta5 </text><rect x=\"1012.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"1032.8\" y=\"160.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text></svg>" ], "text/plain": [ "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x7f097cccdaf0>" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_circ1 = build_ansatz(3, 1)\n", "test_circ1_inv = dagger(test_circ1)\n", "test_circ2 = compile_circuit(test_circ1)\n", "\n", "test_circ_all = test_circ1_inv + test_circ2\n", "\n", "test_circ_all.svg()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "==================graph message==================\n", "0 \t [4] \t red \t -theta5\n", "1 \t [3] \t red \t -theta4\n", "2 \t [5] \t red \t -theta3\n", "3 \t [1, 4, 6] \t green \t 0.0\n", "4 \t [0, 3, 7] \t red \t 0.0\n", "5 \t [2, 6, 8] \t green \t 0.0\n", "6 \t [3, 5, 10] \t red \t 0.0\n", "7 \t [4, 8, 9] \t green \t 0.0\n", "8 \t [5, 7, 11] \t red \t 0.0\n", "9 \t [7, 18] \t red \t -theta2\n", "10 \t [6, 15] \t red \t -theta1\n", "11 \t [8, 12] \t red \t -theta0\n", "12 \t [11, 13] \t yellow \t 0.0\n", "13 \t [12, 14] \t green \t theta0\n", "14 \t [13, 22] \t yellow \t 0.0\n", "15 \t [10, 16] \t yellow \t 0.0\n", "16 \t [15, 17] \t green \t theta1\n", "17 \t [16, 24] \t yellow \t 0.0\n", "18 \t [9, 19] \t yellow \t 0.0\n", "19 \t [18, 20] \t green \t theta2\n", "20 \t [19, 21] \t yellow \t 0.0\n", "21 \t [20, 22, 26] \t green \t 0.0\n", "22 \t [14, 21, 23] \t red \t 0.0\n", "23 \t [22, 24, 27] \t green \t 0.0\n", "24 \t [17, 23, 25] \t red \t 0.0\n", "25 \t [24, 26, 30] \t green \t 0.0\n", "26 \t [21, 25, 33] \t red \t 0.0\n", "27 \t [23, 28] \t yellow \t 0.0\n", "28 \t [27, 29] \t green \t theta3\n", "29 \t [28] \t yellow \t 0.0\n", "30 \t [25, 31] \t yellow \t 0.0\n", "31 \t [30, 32] \t green \t theta4\n", "32 \t [31] \t yellow \t 0.0\n", "33 \t [26, 34] \t yellow \t 0.0\n", "34 \t [33, 35] \t green \t theta5\n", "35 \t [34] \t yellow \t 0.0\n", "\n", "\n" ] } ], "source": [ "# 将测试线路绘制成ZX图\n", "test_g = draw_graph(test_circ_all)\n", "test_g.print()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "化简之前:\n", "Not sure!\n", "化简之后:\n", "Equivalent!\n" ] } ], "source": [ "# 化简测试线路\n", "print(\"化简之前:\")\n", "test_g.equiv()\n", "\n", "simplify(test_g)\n", "\n", "print(\"化简之后:\")\n", "test_g.equiv()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "化简功能测试通过,最后就可以化简完整线路的ZX图,化简结果显示编译前后的两个线路是等价的。" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "化简之前:\n", "Not sure!\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "化简之后:\n", "Equivalent!\n" ] } ], "source": [ "# 化简完整线路\n", "print(\"化简之前:\")\n", "g.equiv()\n", "\n", "simplify(g) # 化简\n", "\n", "print(\"化简之后:\")\n", "g.equiv()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第四\n", "\n", "若ZX演算无法确定则实例化参数。\n", "\n", "对于两个不等价的线路,ZX演算不能直接给出不等价的判定结果。这时,需要对线路中的参数进行实例化,判断实例化之后的两个线路是否等价。" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"376.8\" height=\"200.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect x=\"0\" y=\"0.0\" width=\"376.8\" height=\"200.0\" fill=\"#ffffff\" /><text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q0: </text><text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q1: </text><text x=\"20.0\" y=\"160.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q2: </text><line x1=\"48.8\" x2=\"356.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"356.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"356.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><rect x=\"72.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"92.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"72.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 </text><circle cx=\"152.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"152.8\" x2=\"152.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"132.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"138.8\" x2=\"166.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"152.8\" x2=\"152.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"192.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"232.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"232.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta1 </text><circle cx=\"212.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"212.8\" x2=\"212.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"192.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"198.8\" x2=\"226.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"212.8\" x2=\"212.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"312.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"292.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"298.8\" x2=\"326.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"252.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"292.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"292.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta2 </text></svg>" ], "text/plain": [ "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x7f09db55a370>" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 构造反例线路:ZX演算化简后无法确定、实际上不等价的两个线路\n", "neq_circ1 = Circuit()\n", "neq_circ1 += H.on(1)\n", "neq_circ1 += RX(f'theta{0}').on(2)\n", "neq_circ1 += CNOT.on(0, 1)\n", "neq_circ1 += RZ(f'theta{1}').on(0)\n", "neq_circ1 += CNOT.on(2, 1)\n", "neq_circ1 += CNOT.on(0, 1)\n", "neq_circ1 += RX(f'theta{2}').on(2)\n", "\n", "neq_circ1.svg()" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"536.8\" height=\"200.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect x=\"0\" y=\"0.0\" width=\"536.8\" height=\"200.0\" fill=\"#ffffff\" /><text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q0: </text><text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q1: </text><text x=\"20.0\" y=\"160.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q2: </text><line x1=\"48.8\" x2=\"516.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"516.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"516.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><rect x=\"72.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"92.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"72.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 </text><circle cx=\"152.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"152.8\" x2=\"152.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"132.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"138.8\" x2=\"166.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"152.8\" x2=\"152.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"192.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"232.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"232.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta1 </text><circle cx=\"212.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"212.8\" x2=\"212.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"192.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"198.8\" x2=\"226.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"212.8\" x2=\"212.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"312.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"292.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"298.8\" x2=\"326.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"312.8\" x2=\"312.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"252.8\" y=\"140.0\" width=\"240.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"372.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"372.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 + theta1 + theta2 </text></svg>" ], "text/plain": [ "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x7f097cde4880>" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "neq_circ2 = Circuit()\n", "neq_circ2 += H.on(1)\n", "neq_circ2 += RX(f'theta{0}').on(2)\n", "neq_circ2 += CNOT.on(0, 1)\n", "neq_circ2 += RZ(f'theta{1}').on(0)\n", "neq_circ2 += CNOT.on(2, 1)\n", "neq_circ2 += CNOT.on(0, 1)\n", "neq_circ2 += RX({f'theta{0}': 1, f'theta{1}': 1, f'theta{2}': 1}).on(2)\n", "\n", "neq_circ2.svg()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "tags": [] }, "outputs": [ { "data": { "image/svg+xml": [ "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"816.8\" height=\"200.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect x=\"0\" y=\"0.0\" width=\"816.8\" height=\"200.0\" fill=\"#ffffff\" /><text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q0: </text><text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q1: </text><text x=\"20.0\" y=\"160.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >q2: </text><line x1=\"48.8\" x2=\"796.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"796.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><line x1=\"48.8\" x2=\"796.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#adb0b8\" stroke-width=\"1\" /><rect x=\"72.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"112.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"112.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta2 </text><circle cx=\"92.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"92.8\" x2=\"92.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"72.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"78.8\" x2=\"106.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"92.8\" x2=\"92.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"192.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"192.8\" x2=\"192.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"172.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"178.8\" x2=\"206.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"192.8\" x2=\"192.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"132.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"172.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"172.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta1 </text><circle cx=\"252.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"252.8\" x2=\"252.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"232.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"238.8\" x2=\"266.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"252.8\" x2=\"252.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"232.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"272.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"272.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >-theta0 </text><rect x=\"292.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"312.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"352.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" /><text x=\"372.8\" y=\"100.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >H </text><rect x=\"332.8\" y=\"140.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"372.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"372.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 </text><circle cx=\"432.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"432.8\" x2=\"432.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"412.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"418.8\" x2=\"446.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"432.8\" x2=\"432.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"472.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"512.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RZ </text><text x=\"512.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta1 </text><circle cx=\"492.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"492.8\" x2=\"492.8\" y1=\"100.0\" y2=\"160.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"472.8\" y=\"140.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"478.8\" x2=\"506.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"492.8\" x2=\"492.8\" y1=\"146.0\" y2=\"174.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><circle cx=\"592.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" /><line x1=\"592.8\" x2=\"592.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" /><rect x=\"572.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" /><line x1=\"578.8\" x2=\"606.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><line x1=\"592.8\" x2=\"592.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" /><rect x=\"532.8\" y=\"140.0\" width=\"240.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" /><text x=\"652.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >RX </text><text x=\"652.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >theta0 + theta1 + theta2 </text></svg>" ], "text/plain": [ "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x7f097cdec6d0>" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "neq_circ1_inv = dagger(neq_circ1)\n", "neq_circ_all = neq_circ1_inv + neq_circ2 # 构造完整反例线路\n", "neq_circ_all.svg()" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "化简之前:\n", "Not sure!\n", "化简之后:\n", "Not sure!\n" ] } ], "source": [ "# 将反例线路绘制成ZX图并进行化简\n", "neq_g = draw_graph(neq_circ_all)\n", "print(\"化简之前:\")\n", "neq_g.equiv()\n", "\n", "simplify(neq_g)\n", "\n", "print(\"化简之后:\")\n", "neq_g.equiv()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "对于反例线路,ZX演算化简之后,ZX图中仍有未删掉的顶点,于是ZX演算无法确定其等价性,需要实例化参数进行验证。\n", "\n", "实例化参数步骤分为两步:\n", "\n", "第一步,根据映射函数实例化参数,直接比较实例化之后两个线路的矩阵形式是否等价,若不等价则停止;\n", "\n", "第二步,若映射函数实例化未得到不等价的结果,则随机实例化参数,再直接比较实例化之后两个线路的矩阵形式是否等价,若不等价则最终判定两个线路不等价,否则,最终判定两个线路等价。" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "# 映射函数实例化参数\n", "def map_para(n, r):\n", " para = {}\n", " for i in range(n):\n", " para[f'theta{i}'] = (2*np.pi/((i+1)*r)-np.pi)\n", " return para\n", "\n", "\n", "# 随机实例化参数\n", "def random_para(n):\n", " para = {}\n", " for i in range(n):\n", " para[f'theta{i}'] = (np.random.uniform(np.pi, -np.pi))\n", " return para" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "tags": [] }, "outputs": [], "source": [ "# 实例化参数验证两个线路是否等价,验证r轮\n", "def verify_by_para(circ1, circ2, r):\n", " n = len(list(set(circ1.params_name+circ2.params_name))) # 线路中一共n个参数\n", " flag = True # 记录前r-1轮验证是否有结果\n", " for i in range(r-1): # 前r-1轮指定参数\n", " para = map_para(n, i+1)\n", "\n", " # 直接比较两个实例化之后的线路的矩阵形式是否等价\n", " if np.array_equal(circ1.matrix(para), circ2.matrix(para)):\n", " continue\n", " else:\n", " print('Not equivalent!') # 在任一情况下两个线路的矩阵不等价,即表示这两个线路不等价\n", " flag = False # 验证已有结果,结束\n", " break\n", "\n", " if flag: # 前r-1轮没有结果,最后一轮随机参数\n", " para = random_para(n)\n", " if np.array_equal(circ1.matrix(para), circ2.matrix(para)):\n", " print('Equivalent!')\n", " else:\n", " print('Not equivalent!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "用实例化参数的方法去验证两个反例线路的等价性,结果为不等价。" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Not equivalent!\n" ] } ], "source": [ "verify_by_para(neq_circ1, neq_circ2, 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 最后:将以上过程合并成一个完整的功能" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "tags": [] }, "outputs": [], "source": [ "def ZXcalculus(circ1, circ2):\n", " circ1_inv = dagger(circ1) # 将原始线路左右逆转\n", " circ = circ1_inv + circ2 # 构造完整线路\n", " g = draw_graph(circ) # 将完整线路绘制成ZX图\n", " print(\"化简之前:\")\n", " g.equiv()\n", " simplify(g) # 根据ZX演算规则进行化简\n", " print(\"化简之后:\")\n", " if not g.vertices: # 化简得到两个线路等价的结果\n", " g.equiv()\n", " else: # 化简未能得到结果,需要实例化参数进行验证\n", " g.equiv()\n", " print(\"实例化参数验证:\")\n", " verify_by_para(circ1, circ2, 5)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "<table border=\"1\">\n", " <tr>\n", " <th>Software</th>\n", " <th>Version</th>\n", " </tr>\n", "<tr><td>mindquantum</td><td>0.9.11</td></tr>\n", "<tr><td>scipy</td><td>1.9.3</td></tr>\n", "<tr><td>numpy</td><td>1.23.5</td></tr>\n", "<tr>\n", " <th>System</th>\n", " <th>Info</th>\n", "</tr>\n", "<tr><td>Python</td><td>3.8.17</td></tr><tr><td>OS</td><td>Linux x86_64</td></tr><tr><td>Memory</td><td>16.62 GB</td></tr><tr><td>CPU Max Thread</td><td>16</td></tr><tr><td>Date</td><td>Tue Jan 2 17:38:24 2024</td></tr>\n", "</table>\n" ], "text/plain": [ "<mindquantum.utils.show_info.InfoTable at 0x7f097cce6430>" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.utils.show_info import InfoTable\n", "\n", "InfoTable('mindquantum', 'scipy', 'numpy')" ] } ], "metadata": { "kernelspec": { "display_name": "MindSpore", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.17" } }, "nbformat": 4, "nbformat_minor": 4 }