-
Notifications
You must be signed in to change notification settings - Fork 22
Add IBM 'Use a Quantum Computer Today' notebooks (IBM-Course/) #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kanavsetia
wants to merge
2
commits into
main
Choose a base branch
from
ibm
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
384 changes: 384 additions & 0 deletions
384
IBM-Course/01-build-and-run-your-first-quantum-program.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,384 @@ | ||
| { | ||
| "cells": [ | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "## Running this notebook on qBraid Lab\n", | ||
| "\n", | ||
| "This is the qBraid-flavored version of the IBM Quantum Learning lesson.\n", | ||
| "A few things are different from the upstream Colab version:\n", | ||
| "\n", | ||
| "- **No `pip install` needed.** The qBraid Lab Python 3 kernel ships with\n", | ||
| " `qiskit`, `qiskit-ibm-runtime`, `qiskit-aer`, and `matplotlib` ready to use.\n", | ||
| "- **No IBM token setup needed.** If you've connected your IBM Quantum account\n", | ||
| " in the qBraid Vault (Lab \u2192 Vault \u2192 IBM Quantum), `QiskitRuntimeService()`\n", | ||
| " picks up your token automatically \u2014 you don't need\n", | ||
| " `QiskitRuntimeService.save_account(...)`.\n", | ||
| "- **Don't have an IBM Quantum account yet?** Sign up free at\n", | ||
| " [quantum.cloud.ibm.com](https://quantum.cloud.ibm.com/signin) \u2014 the Open\n", | ||
| " Plan gives you 10 minutes of real QPU time per 28-day window. Then add\n", | ||
| " your token to qBraid Vault and rerun this notebook.\n", | ||
| "\n", | ||
| "The lesson content below is reproduced (with light edits) from IBM Quantum\n", | ||
| "Learning, \u00a9 IBM Corp. 2017\u20132026. The original lives at\n", | ||
| "[quantum.cloud.ibm.com/learning/courses/use-a-qc-today](https://quantum.cloud.ibm.com/learning/courses/use-a-qc-today).\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "# Build and run your first quantum program\n", | ||
| "\n", | ||
| "## Introduction\n", | ||
| "\n", | ||
| "In the following video, Olivia Lanes steps you through the content in this lesson. Alternatively, you can open the [YouTube video](https://youtu.be/vSFv_i_FAXg?si=eGOvZ4AuPclZGTqJ) for this lesson in a separate window.\n", | ||
| "\n", | ||
| "> \ud83d\udcfa **Watch the lesson video** \u2014 Olivia Lanes walks you through this material on YouTube: [youtu.be/vSFv_i_FAXg](https://youtu.be/vSFv_i_FAXg).\n", | ||
| "\n", | ||
| "Welcome to *Use a quantum computer today*! The goal of this course is for you to run code on a real quantum computer in the shortest time possible, with no prior background required. Let's get started.\n", | ||
| "\n", | ||
| "This first lesson is a gentle, hands-on introduction to quantum computing that works for curious beginners and busy leaders alike. You'll learn about quantum circuits and write a small quantum program that creates **entanglement**, and run it on a real IBM\u00ae quantum computer. You also have the option to run the same program on a simulator, should you choose to skip running on a real quantum computer.\n", | ||
| "\n", | ||
| "\n", | ||
| "#### Installation and imports\n", | ||
| "\n", | ||
| "The next cell installs Qiskit with the [visualization module](https://quantum.cloud.ibm.com/docs/api/qiskit/visualization) plus two add-ons: **Aer** (fast simulators) and the **IBM Runtime** client (for quantum computer runs).\n", | ||
| "\n", | ||
| "Next, we have a number of imports. The `QuantumCircuit` class is where we define our quantum bits, or qubits, and define operations on those qubits. This is our first quantum term: a **qubit** is the basic building block of quantum computation, just as a bit is the building block of classical computation. We'll learn more about the special properties of qubits as we create our circuit. Next, `plot_histogram` will be used to visualize the results of our quantum circuit. `AerSimulator`, allows us to simulate the quantum circuit on a classical computer. But simulators cannot run quantum circuits at the same scale as real quantum computers; that's why we need real quantum computers. This can be helpful for testing, debugging, or educational purposes; or if you've exhausted your 10 free minutes of QPU time. The `preset_passmanagers` help optimize the circuits to run efficiently on hardware, which becomes really important as our circuits become more complex. `Sampler` and `QiskitRuntimeService` are necessary to actually run the circuit on the quantum computer. More on this later.\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "# Core Qiskit imports\n", | ||
| "from qiskit import QuantumCircuit\n", | ||
| "from qiskit.visualization import plot_histogram\n", | ||
| "from qiskit_aer import AerSimulator\n", | ||
| "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", | ||
| "\n", | ||
| "# IBM Runtime specific imports\n", | ||
| "from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "Next we'll do a quick environment check. We confirm versions and confirm imports.\n", | ||
| "\n", | ||
| "If anything fails here, it's usually a dependency install issue; fixing it now prevents confusing errors later.\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import sys\n", | ||
| "\n", | ||
| "import qiskit\n", | ||
| "import qiskit_aer\n", | ||
| "import qiskit_ibm_runtime\n", | ||
| "\n", | ||
| "print(\"Python:\", sys.version.split()[0])\n", | ||
| "print(\"qiskit:\", qiskit.__version__)\n", | ||
| "print(\"qiskit-aer:\", qiskit_aer.__version__)\n", | ||
| "print(\"qiskit-ibm-runtime:\", qiskit_ibm_runtime.__version__)" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "## A brief side quest: use the Composer\n", | ||
| "\n", | ||
| "Before we write code, it's helpful to see circuits visually. IBM Quantum **Composer** lets you build circuits by dragging gates onto wires. It's a great way to learn what a circuit is doing without getting distracted by syntax.\n", | ||
| "\n", | ||
| "Open the Composer [here](https://quantum.cloud.ibm.com/composer).\n", | ||
| "\n", | ||
| "Once it loads, launch the guided tutorial from the menu: **Help | Build your first circuit**. Work through it at your own pace. As you go, pay attention to how each gate changes what you expect to measure.\n", | ||
| "\n", | ||
| "The tutorial steps through building the \"Hello World\" circuit. It's visualized in what is called a circuit diagram, where the qubits are represented by horizontal lines and the gates acting on those qubits are represented by boxes or other symbols on the lines. This circuit introduces us to a few key features of qubits and quantum computers:\n", | ||
| "\n", | ||
| "First, the red box labeled \"H\" is a Hadamard gate, which creates a **superposition state** of qubit 0. Unlike a bit, which can only be in the state 1 or 0, a qubit state can include both possibilities at once, with certain weights (called amplitudes) attached to each. Superposition doesn't mean you'll ever see both results in one measurement; it means the state is set up so that either outcome can happen when you measure.\n", | ||
| "\n", | ||
| "Second, the circles and vertical line connecting the two qubits is a CNOT gate, which generates **entanglement** between the two qubits. Entanglement is a special kind of link between qubits. When qubits are entangled, the outcomes of measurements can be strongly correlated in a way that doesn't match what we'd expect from ordinary independent coin flips, or from any classical correlation. When two qubits are entangled, measuring one will instantaneously tell you the outcome of measuring the other.\n", | ||
| "\n", | ||
| "Another key idea you'll see in the tutorial is **shots**. Because **measurement** is the moment a qubit stops behaving like a quantum state and gives you a classical readout, a superposition state will probabilistically collapse to either a 0 or a 1 when it's measured. So, to learn about that superposition, you need to measure it many times by running the same circuit to accumulate statistics. These are called shots.\n", | ||
| "\n", | ||
| "#### Check your understanding\n", | ||
| "\n", | ||
| "Think about each question below, then click to reveal the answer.\n", | ||
| "\n", | ||
| "Can you see a superposition directly from a single measurement?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "No. A single measurement always returns a classical value: either 0 or 1. The \"mixture\" idea shows up only in the statistics you see after many runs, also called shots.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n", | ||
| "In plain language, what does entanglement give you?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "It gives you linked outcomes. Measuring one qubit tells you something about the other. This link is stronger than independent randomness and stronger than any purely classical correlation or shared randomness can explain.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n", | ||
| "If a qubit is in a superposition, what do you see in a single measurement, and why do you need many shots?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "In a single measurement you see only one classical result: either 0 or 1. You need many shots because the \"superposition\" shows up as a probability distribution, which you can only estimate by collecting statistics over repeated runs.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n", | ||
| "Look at the measurement histogram of your Hello World circuit in the Composer. What do you see? Why is this a signature of entanglement?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "It shows you a 50% chance of being in the state $|00\\rangle$ and a 50% chance of being in the state $|11\\rangle$. This means that if you measure one to be 0, the other will be 0 and if you measure one to be 1, the other will also be 1. This is a correlation between the two qubits that can be explained by entanglement.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "## Create and run a quantum program using Qiskit\n", | ||
| "\n", | ||
| "Okay, back to coding. We're going to generate the same entangled state as we did in Composer (called the **$\\Phi^+$ (phi-plus) Bell state**) but this time, we'll write the code by hand. We need to build this skill because as we scale to more qubits and more complicated circuits, the Composer won't be able to help us.\n", | ||
| "\n", | ||
| "To build the Bell state circuit, we use an $H$ (Hadamard) gate to put the first qubit into an equal superposition. Then we apply a $CX$ (controlled-NOT) gate, which entangles the two states together. The two qubits are now correlated in a way that has no classical equivalent.\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "# --- Build the Bell circuit (phi-plus) ---\n", | ||
| "bell = QuantumCircuit(2)\n", | ||
| "bell.h(0)\n", | ||
| "bell.cx(0, 1)\n", | ||
| "bell.measure_all() # creates a classical register named \"meas\"\n", | ||
| "\n", | ||
| "bell.draw(\"mpl\")" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "#### Helper function for running circuits\n", | ||
| "\n", | ||
| "Now let's define a helper function that handles the process of running a quantum circuit and retrieving measurement results. This function takes care of transpiling the circuit to match the backend's instruction set, running it through a `Sampler` primitive, and extracting the counts from the results.\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "def run_circuit_and_get_counts(circuit, backend, shots=1000):\n", | ||
| " \"\"\"\n", | ||
| " Runs a quantum circuit on a specified backend and returns the measurement counts.\n", | ||
| "\n", | ||
| " Args:\n", | ||
| " circuit (QuantumCircuit): The quantum circuit to run.\n", | ||
| " backend: The Qiskit backend (real device or simulator).\n", | ||
| " shots (int): The number of shots to run the circuit.\n", | ||
| "\n", | ||
| " Returns:\n", | ||
| " dict: A dictionary of measurement counts.\n", | ||
| " \"\"\"\n", | ||
| " pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n", | ||
| " isa_circuit = pm.run(circuit)\n", | ||
| "\n", | ||
| " sampler = Sampler(mode=backend)\n", | ||
| "\n", | ||
| " job = sampler.run([isa_circuit], shots=shots)\n", | ||
| " result = job.result()\n", | ||
| "\n", | ||
| " return result[0].data.meas.get_counts()" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### Run on a QPU and visualize results\n", | ||
| "\n", | ||
| "Finally, we run the circuit on an IBM quantum processing unit (QPU) in the cloud for 1000 shots and plot the results. IBM QPUs are physical systems that can pick up noise, so gates are slightly imperfect, measurements can be wrong sometimes, and device calibration drifts over time.\n", | ||
| "\n", | ||
| "Running on real quantum computers also introduces practical considerations. Jobs can sit in a queue, because many people may be using the same device. You also have to choose a shot count that balances statistical considerations (more shots equals a higher signal-to-noise ratio) with time/cost constraints.\n", | ||
| "\n", | ||
| "Follow the instructions in the code comments of the next cell. After running the cell, you should see a histogram with approximately equal counts for the $00$ and $11$ bitstrings, with some occurrences of $01$ or $10$ due to noise. The following cell in this notebook runs the same circuit on a simulator, should you choose to skip running on a QPU.\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "> **qBraid Vault note.** The next cell instantiates `QiskitRuntimeService`\n", | ||
| "> without calling `save_account`. On qBraid Lab the IBM Quantum token is\n", | ||
| "> injected from the Vault, so the lookup just works. If it raises\n", | ||
| "> `IBMNotAuthorizedError`, open **Lab \u2192 Vault \u2192 IBM Quantum** and add a\n", | ||
| "> token from [quantum.cloud.ibm.com](https://quantum.cloud.ibm.com).\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "service = QiskitRuntimeService()\n", | ||
| "# Use the least busy backend, or uncomment the loading of a specific backend like \"ibm_fez\".\n", | ||
| "backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)\n", | ||
| "# backend = service.backend(\"ibm_fez\")\n", | ||
| "print(backend.name)" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "counts = run_circuit_and_get_counts(bell, backend, shots=1000)\n", | ||
| "plot_histogram(counts)" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### Run on a simulator and visualize results\n", | ||
| "\n", | ||
| "A simulator is a \"perfect world\" version of quantum computing. Here we run the circuit on a simulator for 1000 shots and plot the results. You should see approximately equal counts for the $00$ and $11$ states, with no occurrences of $01$ or $10$, which is the signature of the Bell state's perfect correlation.\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "backend = AerSimulator()\n", | ||
| "counts = run_circuit_and_get_counts(bell, backend, shots=1000)\n", | ||
| "\n", | ||
| "plot_histogram(counts)" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "#### Check your understanding\n", | ||
| "\n", | ||
| "What are the two gates that create the Bell state here?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "An H gate on qubit 0, followed by a CX gate with qubit 0 as control and qubit 1 as target.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n", | ||
| "On an ideal simulator, which two bitstrings should dominate the histogram?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "00 and 11 should dominate.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n", | ||
| "Why wouldn't a perfect simulator always have the exact same number of 00 counts as 11 counts?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "Even though a simulator is \"perfect\" and leads to a perfect Bell state, it is still simulating an inherently random process, so statistical fluctuations will still occur. It's like flipping a coin 1000 times: even if there is an exact 50-50 chance of the coin landing on heads or tails, that doesn't mean you'll always get exactly 500 instances of heads and 500 of tails.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n", | ||
| "Why might a real quantum computer show some 01 or 10 results even though the simulator didn't?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "Because real devices have noise. Gates and measurements are not perfect, and that can introduce occasional errors.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n", | ||
| "What is one practical difference between simulators and real quantum computers besides noise?\n", | ||
| "\n", | ||
| "<details>\n", | ||
| "<summary>Answer</summary>\n", | ||
| "\n", | ||
| "Quantum computers can involve queue time, limited availability, and device-specific constraints that affect how circuits run.\n", | ||
| "\n", | ||
| "</details>\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "## Conclusion\n", | ||
| "\n", | ||
| "We started by setting up Qiskit in a fresh Colab environment, which is exactly how many real-world notebook workflows begin. We followed that with a journey into quantum computing using the Composer. We then built a simple two-qubit circuit that produces the $\\Phi^+$ Bell state and used repeated sampling and visualized the entanglement as a correlation in the qubit measurement histogram. We also saw how real quantum computers introduce noise and errors.\n", | ||
| "\n", | ||
| "#### Learning objective\n", | ||
| "\n", | ||
| "Now that we've walked through how to create the $\\Phi^+$ Bell state, see if you can edit the code to create one of the other three [Bell states](https://en.wikipedia.org/wiki/Bell_state#Bell_basis). In particular, the $\\Psi^-$ state will be used in an upcoming lesson, so if you figure out how to create it, you'll be ahead of the game.\n", | ||
| "\n" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "\u00a9 IBM Corp., 2017-2026" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Set the final cell to the exact Apache 2.0 footer required by CI. The current last-cell text does not match the repository’s enforced notebook footer format, so the license check fails. 🤖 Prompt for AI Agents |
||
| ] | ||
| } | ||
| ], | ||
| "metadata": { | ||
| "kernelspec": { | ||
| "display_name": "Python 3 [Default]", | ||
| "language": "python", | ||
| "name": "python3" | ||
| }, | ||
| "language_info": { | ||
| "name": "python", | ||
| "mimetype": "text/x-python", | ||
| "file_extension": ".py" | ||
| } | ||
| }, | ||
| "nbformat": 4, | ||
| "nbformat_minor": 5 | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove residual Colab/install wording to match the qBraid flow.
These sections still describe a fresh Colab install path, which conflicts with this notebook’s qBraid-specific “no
pip installneeded” setup and can confuse users.Also applies to: 354-354
🤖 Prompt for AI Agents