├── .DS_Store ├── LICENSE ├── setup_save_account.ipynb ├── helper_file_1.0.ipynb └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learning-Quantum-Computing-with-Python-and-IBM-Quantum-Second-Edition/HEAD/.DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /setup_save_account.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from qiskit_ibm_runtime import QiskitRuntimeService\n", 10 | " \n", 11 | "# README FIRST: UPDATE WITH YOUR TOKEN ID FIRST BEFORE RUNNING ANY CODE. TOKEN CAN BE FOUND IN YOUR ACCOUNT DETAILS ON THE IBM QUANTUM PLATFORM\n", 12 | "\n", 13 | "#Save an IBM Quantum account and set it as your default account.\n", 14 | "QiskitRuntimeService.save_account(channel=\"ibm_quantum\", token=\"YOUR-API_TOKEN\", set_as_default=True, overwrite=True)\n", 15 | " " 16 | ] 17 | } 18 | ], 19 | "metadata": { 20 | "kernelspec": { 21 | "display_name": "Python 3", 22 | "language": "python", 23 | "name": "python3" 24 | }, 25 | "language_info": { 26 | "codemirror_mode": { 27 | "name": "ipython", 28 | "version": 3 29 | }, 30 | "file_extension": ".py", 31 | "mimetype": "text/x-python", 32 | "name": "python", 33 | "nbconvert_exporter": "python", 34 | "pygments_lexer": "ipython3", 35 | "version": "3.11.9" 36 | } 37 | }, 38 | "nbformat": 4, 39 | "nbformat_minor": 2 40 | } 41 | -------------------------------------------------------------------------------- /helper_file_1.0.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "fc2e29ae-3acb-4a56-a2a0-d04ba37521e7", 6 | "metadata": {}, 7 | "source": [ 8 | "# Quantum helper file\n", 9 | "This file contains various helper functions to allow ease of use and to update as code changes progress and evolve. Rather than changing code across all chapters, this will serve as a single source of reference for all functionality." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 3, 15 | "id": "a43ded54", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "# Load helper file\n", 20 | "%run setup_save_account.ipynb\n" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 4, 26 | "id": "11f3591c-3506-4252-8abc-586e1a17067f", 27 | "metadata": { 28 | "tags": [] 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "# Import libraries and objects\n", 33 | "from qiskit import QuantumCircuit, transpile\n", 34 | "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", 35 | "from qiskit_ibm_runtime import Options\n", 36 | "from qiskit_ibm_runtime import Session\n", 37 | "from qiskit.primitives import StatevectorSampler\n", 38 | "from qiskit.providers.basic_provider import BasicSimulator\n", 39 | "from qiskit.quantum_info import Statevector\n", 40 | "from qiskit_ibm_runtime.fake_provider import FakeManilaV2\n", 41 | "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", 42 | "from qiskit.visualization import *\n", 43 | "\n", 44 | "\n", 45 | "service = QiskitRuntimeService()" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 5, 51 | "id": "f207b68e", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "from qiskit import QuantumCircuit, ClassicalRegister\n", 56 | "from qiskit.providers.fake_provider import GenericBackendV2\n", 57 | "\n", 58 | "def create_circuit(num_qubits, add_measurements):\n", 59 | "\n", 60 | " # Create a circuit with classical control\n", 61 | " meas = ClassicalRegister(num_qubits)\n", 62 | " qc = QuantumCircuit(num_qubits)\n", 63 | " qc.add_register(meas)\n", 64 | " if add_measurements:\n", 65 | " for i in range(num_qubits):\n", 66 | " qc.measure(i, meas[i])\n", 67 | " \n", 68 | " # Define backend with custom basis gates\n", 69 | " #backend = GenericBackendV2(\n", 70 | " # num_qubits=num_qubits,\n", 71 | " # basis_gates=[\"ecr\", \"id\", \"rz\", \"sx\", \"x\"],\n", 72 | " # control_flow=True,\n", 73 | " #)\n", 74 | " \n", 75 | " return qc" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "id": "735525bf", 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "# Run a Statevector simulator: \n", 86 | "def run_sv_simulator(qc):\n", 87 | " from qiskit.quantum_info import Statevector\n", 88 | " statevector = Statevector(qc)\n", 89 | " return statevector \n", 90 | "\n" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "id": "01a7878d", 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [ 100 | "# Run a Unitary simulator: \n", 101 | "def run_unitary_simulator(qc):\n", 102 | " from qiskit.quantum_info import Operator\n", 103 | " result = Operator(qc).data\n", 104 | " return result\n" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": null, 110 | "id": "b350b827", 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "# Run a QASM simulator: \n", 115 | "def run_qasm_simulator(qc):\n", 116 | " from qiskit.providers.basic_provider import BasicSimulator\n", 117 | " backend = BasicSimulator() \n", 118 | " result = backend.run(qc).result()\n", 119 | " return result\n" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 7, 125 | "id": "119dbfb4", 126 | "metadata": {}, 127 | "outputs": [], 128 | "source": [ 129 | "# Execute circuit on the the State vector sampler\n", 130 | "def run_sv_circuit(qc):\n", 131 | " # Run the circuit and return the state vector object result\n", 132 | " stateVectorResult = Statevector(qc)\n", 133 | " #qsphere = stateVectorResult.draw('qsphere')\n", 134 | " #bloch_sphere = stateVectorResult.draw('bloch')\n", 135 | " #circuit_image = qc.draw(output='mpl')\n", 136 | " return stateVectorResult\n", 137 | " " 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 9, 143 | "id": "9abb90eb", 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "# Execute circuit on the Basic Aer qasm simulator, RENAMED from run_qasm_circuit to run_simulated_circuit\n", 148 | "def run_simulated_circuit(qc, backend, options):\n", 149 | " #Check if option object is set\n", 150 | " if options == None:\n", 151 | " options = Options(optimization_level=3)\n", 152 | " \n", 153 | " #Check if backend is defined\n", 154 | " if backend == None:\n", 155 | " backend = BasicSimulator()\n", 156 | " \n", 157 | " transpiled_qc = transpile(qc, backend)\n", 158 | " result = backend.run(transpiled_qc).result()\n", 159 | " \n", 160 | " return transpiled_qc, result\n", 161 | "\n", 162 | "\n" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": null, 168 | "id": "5a99f1fd", 169 | "metadata": {}, 170 | "outputs": [], 171 | "source": [ 172 | "# Execute circuit on the Basic Aer qasm simulator\n", 173 | "def simulate_on_sampler(qc, backend, options):\n", 174 | "\n", 175 | " # Construct an ideal simulator with Sampler \n", 176 | " from qiskit.primitives import StatevectorSampler\n", 177 | " sampler = StatevectorSampler()\n", 178 | "\n", 179 | " # Transpile circuit\n", 180 | " pm = generate_preset_pass_manager(optimization_level=1)\n", 181 | " transpiled_qc = pm.run(qc)\n", 182 | "\n", 183 | " # Run using sampler\n", 184 | " state_vector_result = sampler.run([qc])\n", 185 | " \n", 186 | " result = state_vector_result.result()\n", 187 | " \n", 188 | " return transpiled_qc, result, state_vector_result\n", 189 | "\n", 190 | "\n", 191 | "\n", 192 | "\n", 193 | "\n" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 10, 199 | "id": "b4fa2390-1bd0-4285-aa34-e2d56fd08ede", 200 | "metadata": { 201 | "tags": [] 202 | }, 203 | "outputs": [], 204 | "source": [ 205 | "# Execute a circuit on a real backend - Sampler\n", 206 | "def execute_circuit(qc, simulator, service, backend, options):\n", 207 | " # If executing on a qasm simulator\n", 208 | " if simulator:\n", 209 | " return run_qasm_circuit(qc, backend, options)\n", 210 | " \n", 211 | " if options == None:\n", 212 | " options = Options(optimization_level=3)\n", 213 | " \n", 214 | " with Session(service=service, backend=backend) as session:\n", 215 | " # Submit a request to the Sampler primitive within the session.\n", 216 | " sampler = Sampler(session=session, options=options)\n", 217 | " job = sampler.run(circuits=qc)\n", 218 | " result = job.result()\n", 219 | " return result\n" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 12, 225 | "id": "e9f7cf98", 226 | "metadata": {}, 227 | "outputs": [], 228 | "source": [ 229 | "# Will run the circuit on the state vector (sv) simulator\n", 230 | "# Returns state vector results, circuit diagram, Sphere & Bloch sphere \n", 231 | "def execute_circuit_sv(quantum_circuit):\n", 232 | " stateVectorResults = run_sv_circuit(quantum_circuit)\n", 233 | " \n", 234 | " #Draw the circuit diagram\n", 235 | " circuit_diagram = quantum_circuit.draw(output=\"mpl\")\n", 236 | " #Draw the Qsphere \n", 237 | " q_sphere = stateVectorResults.draw('qsphere')\n", 238 | " #Draw the Bloch sphere \n", 239 | " bloch_sphere = stateVectorResults.draw('bloch') \n", 240 | " #Return the results, circuit diagram, and QSphere\t\t\n", 241 | " return stateVectorResults, circuit_diagram, q_sphere, bloch_sphere" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 14, 247 | "id": "36177fe7", 248 | "metadata": {}, 249 | "outputs": [], 250 | "source": [ 251 | "# Will execute the circuit on the qasm simulator\n", 252 | "# Returns results, circuit diagram, and histogram \n", 253 | "def execute_circuit_returns(quantum_circuit):\n", 254 | " from qiskit.primitives import Sampler\n", 255 | " sampler = Sampler()\n", 256 | " \n", 257 | " result = sampler.run(quantum_circuit, shots=1024).result()\n", 258 | " quasi_dists = result.quasi_dists\n", 259 | "\n", 260 | " # Convert the output to bit strings\n", 261 | " counts = quasi_dists[0].binary_probabilities()\n", 262 | "\n", 263 | " #Draw the circuit diagram\n", 264 | " circuit_diagram = quantum_circuit.draw(output=\"mpl\")\n", 265 | " #Create a histogram of the counts\n", 266 | " histogram = plot_distribution(counts)\n", 267 | " #Return the results, circuit diagram, and histogram\n", 268 | " return counts, circuit_diagram, histogram\n" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 15, 274 | "id": "dcd52a64", 275 | "metadata": {}, 276 | "outputs": [], 277 | "source": [ 278 | "# Will execute the circuit on the qasm simulator\n", 279 | "# Returns results, circuit diagram, and histogram \n", 280 | "def execute_param_circuit(quantum_circuit, params):\n", 281 | " from qiskit.primitives import Sampler\n", 282 | " sampler = Sampler()\n", 283 | " \n", 284 | " result = sampler.run(quantum_circuit, shots=1024).result()\n", 285 | " quasi_dists = result.quasi_dists\n", 286 | "\n", 287 | " # Convert the output to bit strings\n", 288 | " counts = quasi_dists[0].binary_probabilities()\n", 289 | "\n", 290 | " circuit_diagram = quantum_circuit.draw(output=\"mpl\")\n", 291 | " #Create a histogram of the counts\n", 292 | " histogram = plot_distribution(counts)\n", 293 | " #Return the results, circuit diagram, and histogram\n", 294 | " return counts, circuit_diagram, histogram" 295 | ] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "execution_count": 55, 300 | "id": "5574095d", 301 | "metadata": {}, 302 | "outputs": [ 303 | { 304 | "name": "stdout", 305 | "output_type": "stream", 306 | "text": [ 307 | "The number of bitstrings is: 1024\n", 308 | "The counts are: {'000': 498, '111': 526}\n" 309 | ] 310 | } 311 | ], 312 | "source": [ 313 | "#Flag to set to run test cell below, simply change Flase to True:\n", 314 | "test = True\n", 315 | "if test:\n", 316 | " import qiskit\n", 317 | " from qiskit.primitives import StatevectorSampler\n", 318 | "\n", 319 | " # Construct an ideal simulator with SamplerV2 \n", 320 | " sampler = StatevectorSampler()\n", 321 | "\n", 322 | " # Generate 3-qubit GHZ state\n", 323 | " circuit = qiskit.QuantumCircuit(3)\n", 324 | " circuit.h(0)\n", 325 | " circuit.cx(0, 1)\n", 326 | " circuit.cx(1, 2)\n", 327 | " circuit.measure_all()\n", 328 | "\n", 329 | "\n", 330 | " # Transpile circuit\n", 331 | " pm = generate_preset_pass_manager(optimization_level=1)\n", 332 | " isa_circuit = pm.run(circuit)\n", 333 | "\n", 334 | " # Run using sampler\n", 335 | " result = sampler.run([circuit]).result()\n", 336 | "\n", 337 | " # Access result data for PUB 0\n", 338 | " data_pub = result[0].data\n", 339 | "\n", 340 | " # Access bitstring for the classical register \"meas\"\n", 341 | " bitstrings = data_pub.meas.get_bitstrings()\n", 342 | " print(f\"The number of bitstrings is: {len(bitstrings)}\")\n", 343 | "\n", 344 | " # Get counts for the classical register \"meas\"\n", 345 | " counts = data_pub.meas.get_counts()\n", 346 | " print(f\"The counts are: {counts}\")" 347 | ] 348 | } 349 | ], 350 | "metadata": { 351 | "kernelspec": { 352 | "display_name": "Python 3 (ipykernel)", 353 | "language": "python", 354 | "name": "python3" 355 | }, 356 | "language_info": { 357 | "codemirror_mode": { 358 | "name": "ipython", 359 | "version": 3 360 | }, 361 | "file_extension": ".py", 362 | "mimetype": "text/x-python", 363 | "name": "python", 364 | "nbconvert_exporter": "python", 365 | "pygments_lexer": "ipython3", 366 | "version": "3.11.4" 367 | }, 368 | "widgets": { 369 | "application/vnd.jupyter.widget-state+json": { 370 | "state": {}, 371 | "version_major": 2, 372 | "version_minor": 0 373 | } 374 | } 375 | }, 376 | "nbformat": 4, 377 | "nbformat_minor": 5 378 | } 379 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Learn Quantum Computing with Python and IBM Quantum, Second Edition

3 |

This is the code repository for Learn Quantum Computing with Python and IBM Quantum, Second Edition, published by Packt. 4 |

5 | 6 |

7 | Write your own practical quantum programs with Python 8 |

9 |

10 | Robert Loredo

11 | 12 |

13 | 14 |       15 | Free PDF 16 |       17 | Graphic Bundle 18 |       19 | Amazon 20 |       21 |

22 |
23 |

About the book

24 | 25 | Unity Cookbook, Fifth Edition 26 | 27 | 28 | The IBM Quantum Platform was built to enable developers to learn the basics of quantum computing by providing access to high performant quantum computers and provide documentation and courses to help get up to speed with the latest features in quantum computing. 29 | 30 | Updated with new examples and changes to the platform, this edition begins with an introduction to the IBM Quantum Platform and the Quantum Information Science Kit (Qiskit) SDK. You will become well versed in the IBM Quantum Composer interface as well as running your quantum circuits on a real quantum computer. Along the way, you’ll learn some of the fundamental principles regarding quantum mechanics, qubits, quantum gates, quantum circuits, and the error mitigation techniques that are used to perform operations on qubits. 31 | 32 | As you build on your knowledge, you’ll understand the functionality of IBM Qiskit and the developer-focused resources so you can create your own quantum algorithms. You’ll learn how to monitor and optimize your quantum circuits. Lastly, you’ll look at the fundamental quantum algorithms and understand how they can be applied effectively. 33 | 34 | By the end of this quantum computing book, you'll know how to build quantum algorithms and will have gained a practical understanding of quantum computation that you can apply to your research or business. 35 |
36 |
37 |

Key Learnings

38 | 55 | 56 |
57 | 58 |
59 |

Chapters

60 | 61 | 62 | | Chapters | Colab | Kaggle | Gradient | Studio Lab | 63 | | :-------- | :-------- | :------- | :-------- | :-------- | 64 | | **Chapter 1: Exploring the IBM Quantum Tools** | | | | | 65 | | **Chapter 2: Creating Quantum Circuits with IBM Quantum Composer** | | | | | 66 | | **Chapter 3: Introducing and Installing Qiskit** | | | | | 67 | | **Chapter 4: Understanding Basic Quantum Computing Principles** | | | | | 68 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 69 | | **Chapter 5: Understanding the Quantum Bit (Qubit)** | | | | | 70 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 71 | | **Chapter 6: Understanding Quantum Logic Gates** | | | | | 72 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 73 | | **Chapter 7: Programming with Qiskit** | | | | | 74 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 75 | | **Chapter 8: Optimizing and Visualizing Quantum Circuits** | | | | | 76 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 77 | | **Chapter 9: Simulating Quantum Systems and Noise Models** | | | | | 78 | | **Chapter 10: Suppressing and Mitigating Quantum Noise** | | | | | 79 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 80 | | **Chapter 11: Understanding Quantum Algorithms** | | | | | 81 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 82 | | **Chapter 12: Applying Quantum Algorithms** | | | | | 83 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 84 | | **Chapter 13: Understanding Quantum Utility and Qiskit Patterns** | | | | | 85 | | | Open In Colab
| Open In Kaggle
| Open In Gradient
| Open In Studio Lab
| 86 | | **Chapter 14: Appendix A: Resources** | | | | | 87 | | **Chapter 15: Appendix B: Assessments** | | | | | 88 | 89 | 90 | 91 | 92 | 93 | 94 |
95 | 96 | 97 |
98 |

Requirements for this book

99 | 100 | 105 |
106 | 107 | 108 | 109 |
110 |

Get to know Author

111 | 112 | _Robert Loredo_ Robert Loredo is the IBM Quantum Ambassador Worldwide lead with over 20 years' experience in software architecture and engineering. He is a Qiskit Advocate and Master Inventor, listed as one of the world's most prolific inventors with over 200 patents. He has presented various workshops, lectures, and articles covering quantum computing, artificial intelligence, and bioinformatics worldwide. As an adjunct professor, he has taught cloud computing and software engineering at the Florida International University School of Computer Science. He holds both a bachelor's and a master's degree in Computer and Electrical Engineering from the University of Miami and is currently pursuing his PhD in Computer Science, specializing in Quantum Machine Learning and NeuroInformatics, at Florida International University. As a philanthropist, one of his favorite charities is Doctors without Borders. 113 | 114 | 115 | 116 |
117 |
118 |

Other Related Books

119 | 124 | 125 |
126 | --------------------------------------------------------------------------------