|
6 | 6 | "source": [ |
7 | 7 | "First, import the library.\n", |
8 | 8 | "\n", |
9 | | - "You will also need to have LaTeX installed on your system for rendering the diagrams. We also import official Q# library as we will use it for comparison of the generated diagrams." |
| 9 | + "We will also need to have LaTeX installed on your system for rendering the diagrams. We also import official Q# library as we will use it for comparison of the generated diagrams." |
10 | 10 | ] |
11 | 11 | }, |
12 | 12 | { |
|
29 | 29 | "cell_type": "markdown", |
30 | 30 | "metadata": {}, |
31 | 31 | "source": [ |
32 | | - "Next, load the Jupyter TikZ extension. " |
| 32 | + "Next, let's load the Jupyter TikZ extension. " |
33 | 33 | ] |
34 | 34 | }, |
35 | 35 | { |
|
45 | 45 | "cell_type": "markdown", |
46 | 46 | "metadata": {}, |
47 | 47 | "source": [ |
48 | | - "Now you can write some Q# code. This will be the Q# code for which we will generate a circuit diagram." |
| 48 | + "Now we can write some Q# code. This will be the Q# code for which we will generate a circuit diagram. We will set up two test code snippets - one that consists of a single operation, and another that has an operation calling another operation." |
49 | 49 | ] |
50 | 50 | }, |
51 | 51 | { |
|
55 | 55 | "outputs": [], |
56 | 56 | "source": [ |
57 | 57 | "code_1 = \"\"\"\n", |
| 58 | + "operation Main() : Result[] {\n", |
| 59 | + " use qubits = Qubit[8];\n", |
| 60 | + "\n", |
| 61 | + " // apply Hadamard gate to the first qubit\n", |
| 62 | + " H(qubits[0]);\n", |
| 63 | + "\n", |
| 64 | + " // apply CNOT gates to create entanglement\n", |
| 65 | + " for qubit in qubits[1..Length(qubits) - 1] {\n", |
| 66 | + " CNOT(qubits[0], qubit);\n", |
| 67 | + " }\n", |
| 68 | + "\n", |
| 69 | + " // return measurement results\n", |
| 70 | + " MResetEachZ(qubits)\n", |
| 71 | + "}\n", |
| 72 | + "\"\"\"\n", |
| 73 | + "\n", |
| 74 | + "code_2 = \"\"\"\n", |
58 | 75 | "namespace MyQuantumApp {\n", |
59 | 76 | " @EntryPoint()\n", |
60 | 77 | " operation Run() : (Result, Result) {\n", |
|
71 | 88 | " CNOT(q1, q2);\n", |
72 | 89 | " }\n", |
73 | 90 | "}\n", |
74 | | - "\"\"\"\n", |
75 | | - "\n", |
76 | | - "code_2 = \"\"\"\n", |
77 | | - "operation Main() : Result[] {\n", |
78 | | - " use qubits = Qubit[8];\n", |
79 | | - "\n", |
80 | | - " // apply Hadamard gate to the first qubit\n", |
81 | | - " H(qubits[0]);\n", |
82 | | - "\n", |
83 | | - " // apply CNOT gates to create entanglement\n", |
84 | | - " for qubit in qubits[1..Length(qubits) - 1] {\n", |
85 | | - " CNOT(qubits[0], qubit);\n", |
86 | | - " }\n", |
87 | | - "\n", |
88 | | - " // return measurement results\n", |
89 | | - " MResetEachZ(qubits)\n", |
90 | | - "}\n", |
91 | 91 | "\"\"\"" |
92 | 92 | ] |
93 | 93 | }, |
94 | 94 | { |
95 | 95 | "cell_type": "markdown", |
96 | 96 | "metadata": {}, |
97 | 97 | "source": [ |
98 | | - "Once the Q# code is written, you can use the `quantikz` function to generate and display the circuit diagram directly in the Jupyter notebook." |
| 98 | + "Once the Q# code is written, we can use the `quantikz` function to generate and display the circuit diagram directly in the Jupyter notebook." |
99 | 99 | ] |
100 | 100 | }, |
101 | 101 | { |
|
104 | 104 | "metadata": {}, |
105 | 105 | "outputs": [], |
106 | 106 | "source": [ |
107 | | - "quantikz_diagram_1 = quantikz(code_1)\n", |
108 | | - "quantikz_diagram_2 = quantikz(code_2)\n", |
| 107 | + "quantikz_diagram_1 = quantikz(code_1, options=QuantikzGenerationOptions(group_by_scope=False))\n", |
| 108 | + "quantikz_diagram_2 = quantikz(code_2, options=QuantikzGenerationOptions(group_by_scope=False))\n", |
109 | 109 | "\n", |
110 | 110 | "# for debugging, display the generated LaTeX code\n", |
111 | 111 | "print(quantikz_diagram_1)\n", |
|
116 | 116 | "cell_type": "markdown", |
117 | 117 | "metadata": {}, |
118 | 118 | "source": [ |
119 | | - "Use the TikZ extension to render a PDF from the LaTeX code generated by Q# Bridge." |
| 119 | + "We can now use the TikZ extension to render a PDF from the LaTeX code generated by Q# Bridge to verify the output." |
120 | 120 | ] |
121 | 121 | }, |
122 | 122 | { |
|
143 | 143 | "shell.run_cell_magic('tikz', '-l quantikz', quantikz_diagram_2)" |
144 | 144 | ] |
145 | 145 | }, |
| 146 | + { |
| 147 | + "cell_type": "markdown", |
| 148 | + "metadata": {}, |
| 149 | + "source": [ |
| 150 | + "Notice how the two-operation sample was actually decomposed into its constituent individual gates in the generated diagram - this is because we set `group_by_scope` to `False` in the `QuantikzGenerationOptions` when generating the diagrams." |
| 151 | + ] |
| 152 | + }, |
146 | 153 | { |
147 | 154 | "cell_type": "markdown", |
148 | 155 | "metadata": {}, |
|
158 | 165 | "source": [ |
159 | 166 | "qsharp.init() # this ensures clean state\n", |
160 | 167 | "qsharp.eval(code_1)\n", |
161 | | - "Circuit(qsharp.circuit(\"MyQuantumApp.Run()\")) " |
| 168 | + "Circuit(qsharp.circuit(\"Main()\")) " |
162 | 169 | ] |
163 | 170 | }, |
164 | 171 | { |
|
170 | 177 | "\n", |
171 | 178 | "qsharp.init() # this ensures clean state\n", |
172 | 179 | "qsharp.eval(code_2)\n", |
173 | | - "Circuit(qsharp.circuit(\"Main()\")) " |
| 180 | + "Circuit(qsharp.circuit(\"MyQuantumApp.Run()\")) " |
174 | 181 | ] |
175 | 182 | }, |
176 | 183 | { |
|
179 | 186 | "source": [ |
180 | 187 | "We should see that the diagrams generated using `quantikz` and the built-in `Circuit` widget are identical. This confirms that our LaTeX generation is working correctly!" |
181 | 188 | ] |
| 189 | + }, |
| 190 | + { |
| 191 | + "cell_type": "markdown", |
| 192 | + "metadata": {}, |
| 193 | + "source": [ |
| 194 | + "Q# compiler (and, by extension, Q# Bridge) can also group gates on the circuit into groups scoped by an operation. In our case that would mean a large single block representing `PrepareBellState`.\n", |
| 195 | + "\n", |
| 196 | + "Let's set `group_by_scope` of the `QuantikzGenerationOptions` to `True` and pass that into the `quantikz` function - and see how the generated diagram changes." |
| 197 | + ] |
| 198 | + }, |
| 199 | + { |
| 200 | + "cell_type": "code", |
| 201 | + "execution_count": null, |
| 202 | + "metadata": {}, |
| 203 | + "outputs": [], |
| 204 | + "source": [ |
| 205 | + "quantikz_diagram_3 = quantikz(code_2, options=QuantikzGenerationOptions(group_by_scope=True))\n", |
| 206 | + "\n", |
| 207 | + "# for debugging, display the generated LaTeX code\n", |
| 208 | + "print(quantikz_diagram_3)\n", |
| 209 | + "\n", |
| 210 | + "shell = get_ipython()\n", |
| 211 | + "assert shell is not None\n", |
| 212 | + "\n", |
| 213 | + "shell.run_cell_magic('tikz', '-l quantikz', quantikz_diagram_3)" |
| 214 | + ] |
| 215 | + }, |
| 216 | + { |
| 217 | + "cell_type": "markdown", |
| 218 | + "metadata": {}, |
| 219 | + "source": [ |
| 220 | + "Congratualations! You have successfully generated quantum circuit diagrams from Q# code using Q# Bridge and LaTeX in a Jupyter notebook." |
| 221 | + ] |
182 | 222 | } |
183 | 223 | ], |
184 | 224 | "metadata": { |
|
0 commit comments