microsoft/qdk
Publicmirrored from https://github.com/microsoft/qdkAvailable
samples/nasim/demo.ipynb
364lines · modecode
| 1 | { |
| 2 | "cells": [ |
| 3 | { |
| 4 | "cell_type": "code", |
| 5 | "execution_count": null, |
| 6 | "id": "4b145728", |
| 7 | "metadata": {}, |
| 8 | "outputs": [], |
| 9 | "source": [ |
| 10 | "import time\n", |
| 11 | "import qsharp\n", |
| 12 | "from qsharp_widgets import Circuit, Histogram\n", |
| 13 | "\n", |
| 14 | "import qiskit_aer\n", |
| 15 | "import qiskit_aer.noise\n", |
| 16 | "\n", |
| 17 | "from qsharp.noisy_simulator.qir_runner import Simulator, to_results, QirOps\n", |
| 18 | "from qsharp.noisy_simulator.noise_model import create_default_noise_model, amplitude_damping_kraus\n", |
| 19 | "\n", |
| 20 | "qsharp.init(target_profile=qsharp.TargetProfile.Base)" |
| 21 | ] |
| 22 | }, |
| 23 | { |
| 24 | "cell_type": "code", |
| 25 | "execution_count": null, |
| 26 | "id": "7651348e", |
| 27 | "metadata": { |
| 28 | "vscode": { |
| 29 | "languageId": "qsharp" |
| 30 | } |
| 31 | }, |
| 32 | "outputs": [], |
| 33 | "source": [ |
| 34 | "%%qsharp\n", |
| 35 | "\n", |
| 36 | "operation MyH(q: Qubit) : Unit {\n", |
| 37 | " Rz(3.141592653589793 / 2.0, q);\n", |
| 38 | " SX(q);\n", |
| 39 | " Rz(3.141592653589793 / 2.0, q);\n", |
| 40 | "}\n", |
| 41 | "\n", |
| 42 | "operation MyCX(control: Qubit, target: Qubit) : Unit {\n", |
| 43 | " MyH(target);\n", |
| 44 | " CZ(control, target);\n", |
| 45 | " MyH(target);\n", |
| 46 | "}\n", |
| 47 | "\n", |
| 48 | "operation Main() : Result[] {\n", |
| 49 | " use q = Qubit[2];\n", |
| 50 | "\n", |
| 51 | " MyH(q[0]);\n", |
| 52 | " MyCX(q[0], q[1]);\n", |
| 53 | "\n", |
| 54 | " return MResetEachZ(q);\n", |
| 55 | "}" |
| 56 | ] |
| 57 | }, |
| 58 | { |
| 59 | "cell_type": "code", |
| 60 | "execution_count": null, |
| 61 | "id": "58795cd2", |
| 62 | "metadata": {}, |
| 63 | "outputs": [], |
| 64 | "source": [ |
| 65 | "Circuit(qsharp.circuit(qsharp.code.Main))" |
| 66 | ] |
| 67 | }, |
| 68 | { |
| 69 | "cell_type": "code", |
| 70 | "execution_count": null, |
| 71 | "id": "cf348b7d", |
| 72 | "metadata": {}, |
| 73 | "outputs": [], |
| 74 | "source": [ |
| 75 | "qsharp.run(qsharp.code.Main, shots=10)" |
| 76 | ] |
| 77 | }, |
| 78 | { |
| 79 | "cell_type": "code", |
| 80 | "execution_count": null, |
| 81 | "id": "191e1e73", |
| 82 | "metadata": {}, |
| 83 | "outputs": [], |
| 84 | "source": [ |
| 85 | "qir = qsharp.compile(qsharp.code.Main)\n", |
| 86 | "\n", |
| 87 | "noise = create_default_noise_model()\n", |
| 88 | "sim = Simulator(noise_model=noise)\n", |
| 89 | "results = sim.run(qir, shots=10)\n", |
| 90 | "print(\"\\n\".join(results))" |
| 91 | ] |
| 92 | }, |
| 93 | { |
| 94 | "cell_type": "code", |
| 95 | "execution_count": null, |
| 96 | "id": "0242add4", |
| 97 | "metadata": {}, |
| 98 | "outputs": [], |
| 99 | "source": [ |
| 100 | "noise.add_kraus_operator(\"amp_damp_015\", amplitude_damping_kraus(0.15))\n", |
| 101 | "noise.update_gate_noise(\"sx\", \"amp_damp_015\")\n", |
| 102 | "noise.update_gate_noise(\"rz\", \"amp_damp_015\")\n", |
| 103 | "\n", |
| 104 | "results = sim.run(qir, shots=10)\n", |
| 105 | "print(\"\\n\".join(results))" |
| 106 | ] |
| 107 | }, |
| 108 | { |
| 109 | "cell_type": "code", |
| 110 | "execution_count": null, |
| 111 | "id": "9a897791", |
| 112 | "metadata": {}, |
| 113 | "outputs": [], |
| 114 | "source": [ |
| 115 | "qsharp.init(target_profile=qsharp.TargetProfile.Base)" |
| 116 | ] |
| 117 | }, |
| 118 | { |
| 119 | "cell_type": "code", |
| 120 | "execution_count": null, |
| 121 | "id": "5b6a21cf", |
| 122 | "metadata": { |
| 123 | "vscode": { |
| 124 | "languageId": "qsharp" |
| 125 | } |
| 126 | }, |
| 127 | "outputs": [], |
| 128 | "source": [ |
| 129 | "%%qsharp\n", |
| 130 | "\n", |
| 131 | "/// # Sample\n", |
| 132 | "/// Simulation of a simple Ising model evolution\n", |
| 133 | "/// on a 2D grid with second-order Trotterization.\n", |
| 134 | "///\n", |
| 135 | "/// # Description\n", |
| 136 | "/// This sample demonstrates simulation of an Ising model Hamiltonian\n", |
| 137 | "/// on N1xN2 2D grid using a second-order Trotter-Suzuki approximation.\n", |
| 138 | "/// This sample can be easily simulated classically with 3x3 grid and\n", |
| 139 | "/// about 1000 shots. This sample is suitable for Base Profile.\n", |
| 140 | "/// For the purpose of simplicity this sample intentionally doesn't\n", |
| 141 | "/// post-process results or perform eigenvalue estimation.\n", |
| 142 | "operation Main() : Result[] {\n", |
| 143 | " // Dimensions of a 2D grid is N1 x N2\n", |
| 144 | " let N1 : Int = 3;\n", |
| 145 | " let N2 : Int = 4;\n", |
| 146 | "\n", |
| 147 | " // Total evolution time\n", |
| 148 | " let evolutionTime : Double = 4.0;\n", |
| 149 | " // Number of steps\n", |
| 150 | " let numberOfSteps : Int = 5;\n", |
| 151 | "\n", |
| 152 | " // Coefficient for 2-qubit interactions between neighboring qubits\n", |
| 153 | " let J : Double = 1.0;\n", |
| 154 | " // Coefficient for external field interaction for individual qubits\n", |
| 155 | " let g : Double = 1.4;\n", |
| 156 | "\n", |
| 157 | " // Also try simulating with different strength of external field:\n", |
| 158 | " // let g = 0.2;\n", |
| 159 | " // let g = 1.0;\n", |
| 160 | " // let g = 1.4;\n", |
| 161 | " // let g = 2.0;\n", |
| 162 | "\n", |
| 163 | " // Model evolution\n", |
| 164 | " IsingModel2DEvolution(N1, N2, J, g, evolutionTime, numberOfSteps)\n", |
| 165 | "}\n", |
| 166 | "\n", |
| 167 | "/// # Summary\n", |
| 168 | "/// Simulate simple Ising model evolution\n", |
| 169 | "///\n", |
| 170 | "/// # Description\n", |
| 171 | "/// Simulates state |𝜓⟩ evolution to find |𝜓(t)⟩=U(t)|𝜓(0)⟩.\n", |
| 172 | "/// |𝜓(0)⟩ is taken to be |0...0⟩.\n", |
| 173 | "/// U(t)=e⁻ⁱᴴᵗ, where H is an Ising model Hamiltonian H = -J·Σ'ᵢⱼZᵢZⱼ + g·ΣᵢXᵢ\n", |
| 174 | "/// Here Σ' is taken over all pairs of neighboring qubits <i,j>.\n", |
| 175 | "/// Simulation is done by performing K steps assuming U(t)≈(U(t/K))ᴷ.\n", |
| 176 | "operation IsingModel2DEvolution(\n", |
| 177 | " N1 : Int,\n", |
| 178 | " N2 : Int,\n", |
| 179 | " J : Double,\n", |
| 180 | " g : Double,\n", |
| 181 | " evolutionTime : Double,\n", |
| 182 | " numberOfSteps : Int\n", |
| 183 | ") : Result[] {\n", |
| 184 | "\n", |
| 185 | " // Allocate qubit grid and structure it as a 2D array.\n", |
| 186 | " use qubits = Qubit[N1 * N2];\n", |
| 187 | " let qubitsAs2D = Std.Arrays.Chunks(N2, qubits);\n", |
| 188 | "\n", |
| 189 | " // Compute the time step\n", |
| 190 | " let dt : Double = evolutionTime / Std.Convert.IntAsDouble(numberOfSteps);\n", |
| 191 | "\n", |
| 192 | " let theta_x = - g * dt;\n", |
| 193 | " let theta_zz = J * dt;\n", |
| 194 | "\n", |
| 195 | " // Perform K steps\n", |
| 196 | " for i in 1..numberOfSteps {\n", |
| 197 | "\n", |
| 198 | " // Single-qubit interaction with external field. Half-step.\n", |
| 199 | " for q in qubits {\n", |
| 200 | " Rx(theta_x, q);\n", |
| 201 | " }\n", |
| 202 | "\n", |
| 203 | " // All Rzz gates applied in the following two loops commute so they can be\n", |
| 204 | " // applied in any order. To reduce the depth of the algorithm, Rzz gates\n", |
| 205 | " // between horizontal \"even\" pairs of qubits are applied first - pairs\n", |
| 206 | " // that start at even indices. Then Rzz gates between \"odd\" pairs are\n", |
| 207 | " // applied. That way all Rzz between horizontal \"even\" pairs can potentially\n", |
| 208 | " // be done in parallel. Same is true about horizontal \"odd\" pairs,\n", |
| 209 | " // vertical \"even\" pairs and vertical \"odd\" pairs.\n", |
| 210 | "\n", |
| 211 | " // Horizontal two-qubit interactions.\n", |
| 212 | " for row in 0..N1-1 {\n", |
| 213 | " // Horizontal interactions between \"even\" pairs\n", |
| 214 | " for col in 0..2..N2-2 {\n", |
| 215 | " Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row][col + 1]);\n", |
| 216 | " }\n", |
| 217 | "\n", |
| 218 | " // Horizontal interactions between \"odd\" pairs\n", |
| 219 | " for col in 1..2..N2-2 {\n", |
| 220 | " Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row][col + 1]);\n", |
| 221 | " }\n", |
| 222 | " }\n", |
| 223 | "\n", |
| 224 | " // Vertical two-qubit interactions\n", |
| 225 | " for col in 0..N2-1 {\n", |
| 226 | "\n", |
| 227 | " // Vertical interactions between \"even\" pairs\n", |
| 228 | " for row in 0..2..N1-2 {\n", |
| 229 | " Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row + 1][col]);\n", |
| 230 | " }\n", |
| 231 | "\n", |
| 232 | " // Vertical interactions between \"odd\" pairs\n", |
| 233 | " for row in 1..2..N1-2 {\n", |
| 234 | " Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row + 1][col]);\n", |
| 235 | " }\n", |
| 236 | "\n", |
| 237 | " }\n", |
| 238 | "\n", |
| 239 | " // Single-qubit interaction with external field. Half-step.\n", |
| 240 | " for q in qubits {\n", |
| 241 | " Rx(theta_x, q);\n", |
| 242 | " }\n", |
| 243 | "\n", |
| 244 | " }\n", |
| 245 | "\n", |
| 246 | " MResetEachZ(qubits)\n", |
| 247 | "}\n" |
| 248 | ] |
| 249 | }, |
| 250 | { |
| 251 | "cell_type": "code", |
| 252 | "execution_count": null, |
| 253 | "id": "b9c7e3cf", |
| 254 | "metadata": {}, |
| 255 | "outputs": [], |
| 256 | "source": [ |
| 257 | "circ_data = qsharp.circuit(qsharp.code.Main)\n", |
| 258 | "Circuit(circ_data)" |
| 259 | ] |
| 260 | }, |
| 261 | { |
| 262 | "cell_type": "code", |
| 263 | "execution_count": null, |
| 264 | "id": "8b7f18ab", |
| 265 | "metadata": {}, |
| 266 | "outputs": [], |
| 267 | "source": [ |
| 268 | "start = time.time()\n", |
| 269 | "results = qsharp.run(qsharp.code.Main, shots=10)\n", |
| 270 | "end = time.time()\n", |
| 271 | "print(f\"Execution time: {end - start:.2f} seconds\")\n", |
| 272 | "\n", |
| 273 | "Histogram(results)" |
| 274 | ] |
| 275 | }, |
| 276 | { |
| 277 | "cell_type": "code", |
| 278 | "execution_count": null, |
| 279 | "id": "238d9508", |
| 280 | "metadata": {}, |
| 281 | "outputs": [], |
| 282 | "source": [ |
| 283 | "ising = qsharp.compile(qsharp.code.Main)\n", |
| 284 | "prog = QirOps(ising)\n", |
| 285 | "prog.transpose()\n", |
| 286 | "display(Circuit(prog))" |
| 287 | ] |
| 288 | }, |
| 289 | { |
| 290 | "cell_type": "code", |
| 291 | "execution_count": null, |
| 292 | "id": "73f35076", |
| 293 | "metadata": {}, |
| 294 | "outputs": [], |
| 295 | "source": [ |
| 296 | "# Default noise model predefines common gates but without any noise\n", |
| 297 | "noise = create_default_noise_model()\n", |
| 298 | "\n", |
| 299 | "# Add amplitude damping noise to the noise model\n", |
| 300 | "noise.add_kraus_operator(\"amp_damp_015\", amplitude_damping_kraus(0.01))\n", |
| 301 | "noise.update_gate_noise(\"sx\", \"amp_damp_015\")\n", |
| 302 | "noise.update_gate_noise(\"rz\", \"amp_damp_015\")\n", |
| 303 | "\n", |
| 304 | "# Let's assume moving stuff into the zone for CZ gates is lossy too\n", |
| 305 | "noise.update_gate_loss(\"cz\", 0.005)\n", |
| 306 | "\n", |
| 307 | "# The noisy simulator runs on QIR, so compile to QIR first.\n", |
| 308 | "sim = Simulator(noise_model=noise)\n", |
| 309 | "\n", |
| 310 | "start = time.time()\n", |
| 311 | "results = to_results(sim.run(ising, shots=10))\n", |
| 312 | "end = time.time()\n", |
| 313 | "print(f\"Execution time: {end - start:.2f} seconds\")\n", |
| 314 | "\n", |
| 315 | "Histogram(results)" |
| 316 | ] |
| 317 | }, |
| 318 | { |
| 319 | "cell_type": "code", |
| 320 | "execution_count": null, |
| 321 | "id": "056d6d80", |
| 322 | "metadata": {}, |
| 323 | "outputs": [], |
| 324 | "source": [ |
| 325 | "circ = prog.to_qiskit_circuit()\n", |
| 326 | "\n", |
| 327 | "error = qiskit_aer.noise.amplitude_damping_error(0.15)\n", |
| 328 | "noise = qiskit_aer.noise.NoiseModel()\n", |
| 329 | "noise.add_all_qubit_quantum_error(error, ['sx', 'rz'])\n", |
| 330 | "\n", |
| 331 | "simulator = qiskit_aer.AerSimulator(method='statevector', noise_model=noise)\n", |
| 332 | "start = time.time()\n", |
| 333 | "result = simulator.run(circ, shots=10, memory=True).result()\n", |
| 334 | "memory = result.get_memory(circ)\n", |
| 335 | "end = time.time()\n", |
| 336 | "print(f\"Execution time: {end - start:.2f} seconds\")\n", |
| 337 | "\n", |
| 338 | "shots = to_results(memory)\n", |
| 339 | "Histogram(shots)" |
| 340 | ] |
| 341 | } |
| 342 | ], |
| 343 | "metadata": { |
| 344 | "kernelspec": { |
| 345 | "display_name": ".venv", |
| 346 | "language": "python", |
| 347 | "name": "python3" |
| 348 | }, |
| 349 | "language_info": { |
| 350 | "codemirror_mode": { |
| 351 | "name": "ipython", |
| 352 | "version": 3 |
| 353 | }, |
| 354 | "file_extension": ".py", |
| 355 | "mimetype": "text/x-python", |
| 356 | "name": "python", |
| 357 | "nbconvert_exporter": "python", |
| 358 | "pygments_lexer": "ipython3", |
| 359 | "version": "3.13.5" |
| 360 | } |
| 361 | }, |
| 362 | "nbformat": 4, |
| 363 | "nbformat_minor": 5 |
| 364 | } |
| 365 | |