\n",
"Tip: The newer JupyterLab as opposed to the older Jupyter Notebook uses a different framework for widgets which is currently not compatible with the widgets used in PyZX. It is therefore recommended that you use the classic notebook interface. If you are using JupyterLab you can find this interface by going to 'Help -> Launch Classic Notebook'.\n",
"
\n",
"\n",
"\n",
"We start by importing the library and configuring matplotlib to display the figures in a nice way."
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:55:06.045193Z",
"start_time": "2025-12-20T13:55:06.042626Z"
}
},
"outputs": [],
"source": [
"import sys; sys.path.insert(0, '../..') # So that we import the local copy of pyzx if you have installed from Github\n",
"import random\n",
"import pyzx as zx"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Quantum circuits in PyZX are represented by the `pyzx.circuit.Circuit` class. Files in the supported formats (QASM, QC, Quipper) can easily be imported into PyZX as shown below."
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:39.855745Z",
"start_time": "2025-12-20T13:50:39.849164Z"
}
},
"outputs": [],
"source": [
"circuit_import = zx.Circuit.load(\"../../circuits/Arithmetic_and_Toffoli/adder_8_after_heavy\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"PyZX tries to automatically figure out in which format the circuit is represented. The `pyzx.generate` module supplies several ways to generate random circuits. For example we can create a new random circuit and visualize it "
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:41.092263Z",
"start_time": "2025-12-20T13:50:41.031548Z"
}
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"qubit_amount = 4\n",
"depth = 15\n",
"circ = zx.generate.CNOT_HAD_PHASE_circuit(qubit_amount, depth)\n",
"zx.draw_matplotlib(circ,labels=True,h_edge_draw='box') "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The green and red nodes represent Z- and X-phase gates respectively, the yellow boxes are Hadamard gates, and the vertical lines going between two different colored nodes are CNOT gates.\n",
"\n",
"If you are running inside a Jupyter notebook, circuits can be easily visualized using the zx.draw() function.\n",
"\n",
"This draw function by default uses the D3 Javascript library to draw the diagram. If it doesn't work, use draw_matplotlib() as shown above instead. When not running in a Jupyter notebook `zx.draw` returns a matplotlib figure instead. "
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:55:34.816045Z",
"start_time": "2025-12-20T13:55:34.784811Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"zx.draw(circ, labels=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that the blue lines represent edges that have a Hadamard gate on them.\n",
"\n",
"\n",
"There are two main data structures in PyZX, Circuits and Graphs. A `pyzx.circuit.Circuit` is essentially just a list of gates. The above is an example of a ``Circuit``"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:49.296242Z",
"start_time": "2025-12-20T13:50:49.293991Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[CNOT(2,3), HAD(2), CNOT(0,3), HAD(0), CNOT(3,2), CNOT(1,2), CNOT(2,0), CNOT(1,2), CNOT(1,3), CNOT(3,2), T(0), CNOT(1,3), CNOT(1,2), CNOT(1,2), CNOT(0,2)]\n"
]
}
],
"source": [
"print (circ.gates)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most of the functionality in PyZX works on Graphs instead, which directly represent ZX-diagrams (the drawing function ``zx.draw`` above for instance first converted the circuit into a Graph before drawing it). ZX-diagrams are represented by instances of `BaseGraph`. \n",
"\n",
"To convert a circuit into a ZX-diagram, simply do:\n"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:50.935644Z",
"start_time": "2025-12-20T13:50:50.933574Z"
}
},
"outputs": [],
"source": [
"graph = circ.to_graph()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Internally, a ZX-diagram is just a graph with some additional data:"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:52.918932Z",
"start_time": "2025-12-20T13:50:52.915963Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Graph(35 vertices, 43 edges)\n",
"All edges: [(0, 8), (1, 13), (2, 5), (3, 4), (4, 5), (4, 7), (5, 6), (6, 10), (7, 8), (7, 11), (8, 9), (9, 14), (10, 11), (10, 12), (11, 18), (12, 13), (12, 15), (13, 17), (14, 15), (14, 22), (15, 16), (16, 17), (16, 20), (17, 19), (18, 19), (18, 21), (19, 24), (20, 21), (20, 25), (21, 23), (22, 30), (23, 24), (23, 34), (24, 26), (25, 26), (25, 27), (26, 28), (27, 28), (27, 29), (28, 32), (29, 30), (29, 33), (30, 31)]\n",
"\n",
"The neighbors of a particular vertex: [9, 15, 22]\n"
]
}
],
"source": [
"print(graph)\n",
"print(\"All edges: \", list(graph.edges()))\n",
"print(\"\\nThe neighbors of a particular vertex: \", list(graph.neighbors(14)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can generate a ZX-diagrams directly, instead of needing to convert from a circuit, by using a different generator function:"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:56.074553Z",
"start_time": "2025-12-20T13:50:55.977387Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"circ = zx.generate.cliffords(qubit_amount, depth)\n",
"zx.draw(circ)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using this graph representation we can use the rules of the ZX-calculus to simplify it:"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:57.793790Z",
"start_time": "2025-12-20T13:50:57.787707Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g = circ.copy()\n",
"zx.clifford_simp(g)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:50:59.766878Z",
"start_time": "2025-12-20T13:50:59.724019Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"g.normalize() # Reposition nodes horizontally to look nicer\n",
"zx.draw(g)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's try to see in a bit more detail what goes into rewriting this circuit."
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:53:45.101033Z",
"start_time": "2025-12-20T13:53:44.970782Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from pyzx.simplify import *\n",
"\n",
"g = circ.copy()\n",
"graphs = [zx.draw_matplotlib(graph)]\n",
"names = [\"start\"]\n",
"\n",
"s = spider_simp(g)\n",
"if s: zx.draw(g)\n",
"\n",
"to_gh(g)\n",
"zx.draw(g)\n",
"while True:\n",
" while True:\n",
" i1 = id_simp(g)\n",
" i2 = spider_simp(g)\n",
" i3 = pivot_simp(g)\n",
" if i1 or i2 or i3: zx.draw(g)\n",
"\n",
" i4 = lcomp_simp(g)\n",
" if i4: zx.draw(g)\n",
"\n",
" if not (i1 or i2 or i3 or i4): break\n",
"\n",
" i2 = pivot_boundary_simp(g)\n",
" if i2: zx.draw(g)\n",
" if not i2: break\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see, the first few steps are **spider fusion**, where adjacent red nodes and adjacent green nodes are fused together (and their phases added). This step also removes parallel edges between red and green nodes. The next step is to convert all red nodes to green nodes by changing regular edges to hadamard edges.\n",
"\n",
"Now come the steps that do most of the work. These steps are a round of **pivots** followed by **local complementations** and then a round of pivots again. The local complementation rules looks for green nodes with a phase of $\\frac\\pi2$ or $\\frac{3\\pi}2$. By doing a local complementation on this node we can remove the node from the graph. This process is done until no more suitable candidates are found. A pivot consists of a series of three local complementations that is done on two neighboring vertices that have a zero or $\\pi$ phase. A pivot move allows us to remove these two nodes.\n",
"\n",
"Finally we do a round of **identity** simplification which removes phaseless nodes that are connected to precisely two neighbors.\n",
"\n",
"**Note**: Depending on the circuit that was generated, any of these steps might not have been done."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Even though this graph is a lot compacter than the one we started out with, it no longer looks like a circuit. To fix this we need to be clever and *extract* a circuit from the ZX-diagram:"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-20T13:54:55.606635Z",
"start_time": "2025-12-20T13:54:55.597597Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"circ2 = g.copy()\n",
"circ2.normalize()\n",
"circ2 = zx.extract_circuit(circ2)\n",
"zx.draw(circ2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To verify that this circuit is still equal to the original circuit, we can transform them into numpy tensors and compare these tensors for equality:"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t1 = circ.to_tensor()\n",
"t2 = circ2.to_tensor()\n",
"# This checks whether t1 and t2 are equal up to some number: t1 == z*t2 for some complex number z\n",
"zx.compare_tensors(t1,t2,preserve_scalar=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This extraction procedure is sometimes not as good at keeping the number of two-qubit gates low, and will sometimes increase the size of the circuit. PyZX also supplies some Circuit-level optimisers that more consistently reduce the size of the circuit (but are less powerful):"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"c2 = zx.optimize.basic_optimization(circ2.to_basic_gates())\n",
"zx.draw(c2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can represent the circuit in one of several quantum circuit description languages, such as that of QASM:"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OPENQASM 2.0;\n",
"include \"qelib1.inc\";\n",
"qreg q[4];\n",
"h q[3];\n",
"h q[2];\n",
"h q[0];\n",
"h q[2];\n",
"cz q[0], q[2];\n",
"rz(0.5*pi) q[0];\n",
"h q[3];\n",
"h q[0];\n",
"cz q[2], q[3];\n",
"cz q[0], q[2];\n",
"h q[2];\n",
"cz q[1], q[2];\n",
"rz(1.5*pi) q[3];\n",
"h q[3];\n",
"h q[1];\n",
"cz q[2], q[3];\n",
"cz q[0], q[3];\n",
"cz q[0], q[2];\n",
"rz(1.0*pi) q[3];\n",
"h q[3];\n",
"h q[0];\n",
"\n"
]
}
],
"source": [
"print(circ2.to_qasm())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now lets try the same thing with a more complicated Clifford+T circuit."
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"qubit_amount = 6\n",
"depth = 70\n",
"random.seed(1338)\n",
"circ = zx.generate.cliffordT(qubit_amount, depth,p_t=0.2)\n",
"zx.draw(circ)"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"g = circ.copy()\n",
"zx.clifford_simp(g)\n",
"g.normalize()\n",
"zx.draw(g)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Again, let us extract a circuit from this diagram:"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Circuit on 6 qubits with 62 gates.\n",
" 8 is the T-count\n",
" 54 Cliffords among which\n",
" 28 2-qubit gates (2 CNOT, 26 other) and\n",
" 22 Hadamard gates.\n"
]
}
],
"source": [
"g2 = g.copy()\n",
"c = zx.extract_circuit(g2)\n",
"print(c.stats())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can convert this back into a PyZX-graph:"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"zx.draw(c.to_graph())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And verify that it is still equal to the original graph:"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# We can just feed the Circuit objects directly to compare_tensors\n",
"zx.compare_tensors(c, circ)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now lets represent this circuit in the QASM circuit description language:"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OPENQASM 2.0;\n",
"include \"qelib1.inc\";\n",
"qreg q[6];\n",
"cx q[2], q[5];\n",
"cx q[5], q[2];\n",
"cx q[2], q[5];\n",
"cx q[1], q[4];\n",
"cx q[4], q[1];\n",
"cx q[1], q[4];\n",
"h q[5];\n",
"h q[4];\n",
"h q[3];\n",
"h q[1];\n",
"h q[1];\n",
"h q[3];\n",
"cz q[2], q[5];\n",
"cz q[2], q[3];\n",
"cz q[1], q[2];\n",
"h q[2];\n",
"h q[5];\n",
"cz q[2], q[5];\n",
"cz q[2], q[3];\n",
"cz q[1], q[2];\n",
"rz(1.25*pi) q[2];\n",
"h q[0];\n",
"h q[2];\n",
"h q[4];\n",
"cz q[1], q[5];\n",
"cz q[1], q[4];\n",
"cz q[1], q[3];\n",
"cz q[1], q[2];\n",
"cz q[0], q[1];\n",
"rz(0.5*pi) q[1];\n",
"h q[1];\n",
"cz q[1], q[3];\n",
"rz(1.5*pi) q[3];\n",
"h q[3];\n",
"cz q[0], q[5];\n",
"cz q[0], q[4];\n",
"cz q[0], q[3];\n",
"h q[0];\n",
"cx q[0], q[2];\n",
"cz q[3], q[5];\n",
"cz q[2], q[5];\n",
"cz q[0], q[5];\n",
"rz(0.75*pi) q[5];\n",
"h q[5];\n",
"rz(1.25*pi) q[5];\n",
"h q[5];\n",
"cx q[5], q[1];\n",
"cz q[2], q[3];\n",
"rz(1.25*pi) q[2];\n",
"h q[2];\n",
"cz q[0], q[3];\n",
"cz q[0], q[2];\n",
"rz(0.75*pi) q[4];\n",
"rz(0.25*pi) q[0];\n",
"h q[4];\n",
"h q[0];\n",
"cz q[3], q[5];\n",
"cz q[3], q[4];\n",
"cz q[1], q[5];\n",
"rz(0.5*pi) q[5];\n",
"h q[5];\n",
"rz(0.75*pi) q[4];\n",
"rz(0.25*pi) q[3];\n",
"h q[2];\n",
"rz(0.5*pi) q[0];\n",
"h q[0];\n",
"\n"
]
}
],
"source": [
"print(c.to_basic_gates().to_qasm())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Optimizing random circuits might not be very useful, so lets look at an optimization on a predefined circuit:"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[NOT(4), HAD(4), CCZ(c1=0,c2=3,t=4), CCZ(c1=2,c2=3,t=4), HAD(4), CNOT(3,4), HAD(4), CCZ(c1=1,c2=2,t=4), HAD(4), CNOT(2,4), HAD(4), CCZ(c1=0,c2=1,t=4), HAD(4), CNOT(1,4), CNOT(0,4)]\n"
]
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"c = zx.Circuit.load('../../circuits/Fast/mod5_4_before') # Circuit.load auto-detects the file format\n",
"print(c.gates) # This circuit is built out of CCZ gates.\n",
"zx.draw(c)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[NOT(4), HAD(4), CNOT(3,4), T*(4), CNOT(0,4), T(4), CNOT(3,4), T*(4), CNOT(0,4), T(3), T(4), CNOT(0,3), T(0), T*(3), CNOT(0,3), CNOT(3,4), T*(4), CNOT(2,4), T(4), CNOT(3,4), T*(4), CNOT(2,4), T(3), T(4), CNOT(2,3), T(2), T*(3), CNOT(2,3), HAD(4), CNOT(3,4), HAD(4), CNOT(2,4), T*(4), CNOT(1,4), T(4), CNOT(2,4), T*(4), CNOT(1,4), T(2), T(4), CNOT(1,2), T(1), T*(2), CNOT(1,2), HAD(4), CNOT(2,4), HAD(4), CNOT(1,4), T*(4), CNOT(0,4), T(4), CNOT(1,4), T*(4), CNOT(0,4), T(1), T(4), CNOT(0,1), T(0), T*(1), CNOT(0,1), HAD(4), CNOT(1,4), CNOT(0,4)]\n",
"Circuit mod5_4_before on 5 qubits with 63 gates.\n",
" 28 is the T-count\n",
" 35 Cliffords among which\n",
" 28 2-qubit gates (28 CNOT, 0 other) and\n",
" 6 Hadamard gates.\n"
]
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\n",
"c = c.to_basic_gates() # Convert it to the Clifford+T gate set.\n",
"print(c.gates)\n",
"print(c.stats())\n",
"zx.draw(c)"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Graph(31 vertices, 46 edges)\n"
]
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"g = c.to_graph()\n",
"zx.simplify.full_reduce(g) # Simplify the ZX-graph\n",
"print(g)\n",
"zx.draw(g)\n"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Circuit on 5 qubits with 62 gates.\n",
" 8 is the T-count\n",
" 54 Cliffords among which\n",
" 28 2-qubit gates (6 CNOT, 22 other) and\n",
" 24 Hadamard gates.\n"
]
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"c2 = zx.extract_circuit(g).to_basic_gates() # Turn graph back into circuit\n",
"print(c2.stats())\n",
"zx.draw(c2)\n"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Circuit on 5 qubits with 31 gates.\n",
" 8 is the T-count\n",
" 23 Cliffords among which\n",
" 18 2-qubit gates (16 CNOT, 2 other) and\n",
" 2 Hadamard gates.\n"
]
},
{
"data": {
"text/html": [
"\n",
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\n",
"c3 = zx.optimize.full_optimize(c2) # Do some further optimization on the circuit\n",
"print(c3.stats())\n",
"zx.draw(c3)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"PyZX can also be run from the command-line for some easy circuit-to-circuit manipulation. In order to optimize a circuit you can run the command \n",
"\n",
"`python -m pyzx opt input_circuit.qasm`\n",
"\n",
"For more information regarding the command-line tools, run ``python -m pyzx --help``."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This concludes this tutorial. For more information about the simplification procedures see [Simplify](simplify.ipynb). The different representations of the graphs and circuits as well as how to create and modify ZX-diagrams are detailed in the other tuorial notebooks.\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}