From f5d1cd9270029130a93eff9df865f13005775d55 Mon Sep 17 00:00:00 2001 From: Kanav Setia Date: Sun, 17 May 2026 17:37:20 -0500 Subject: [PATCH 1/2] Add IBM 'Use a Quantum Computer Today' notebooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qBraid-flavored adaptations of Olivia Lanes' four lesson notebooks from IBM Quantum Learning. Surfaced from the Start Here panel's new Qiskit tab in the lab extension. Adaptations vs upstream: - drop !pip install (qiskit/qiskit-ibm-runtime/qiskit-aer/matplotlib ship with the qBraid Lab base env) - drop QiskitRuntimeService.save_account(...) (token is injected from qBraid Vault when you've connected IBM Quantum) - IBM MDX tags (, , ) → plain markdown so the cells render correctly in Jupyter - absolute URLs for IBM Quantum docs/composer links Co-Authored-By: Claude Opus 4.7 (1M context) --- IBM-Course/01-quantum-computing-context.ipynb | 251 +++++++++ IBM-Course/02-quantum-mechanics-basics.ipynb | 415 +++++++++++++++ .../03-your-first-quantum-experiment.ipynb | 485 ++++++++++++++++++ ...d-and-run-your-first-quantum-program.ipynb | 384 ++++++++++++++ IBM-Course/README.md | 31 ++ 5 files changed, 1566 insertions(+) create mode 100644 IBM-Course/01-quantum-computing-context.ipynb create mode 100644 IBM-Course/02-quantum-mechanics-basics.ipynb create mode 100644 IBM-Course/03-your-first-quantum-experiment.ipynb create mode 100644 IBM-Course/04-build-and-run-your-first-quantum-program.ipynb create mode 100644 IBM-Course/README.md diff --git a/IBM-Course/01-quantum-computing-context.ipynb b/IBM-Course/01-quantum-computing-context.ipynb new file mode 100644 index 0000000..7bcb45f --- /dev/null +++ b/IBM-Course/01-quantum-computing-context.ipynb @@ -0,0 +1,251 @@ +{ + "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": [ + "# Quantum computing context\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/y_1SiE1tlTk?si=xzEYyCLSlFHDLdRz) 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/y_1SiE1tlTk](https://youtu.be/y_1SiE1tlTk).\n", + "\n", + "You began this course by diving right into running your first quantum circuit, and learning how the laws of quantum mechanics are used to create quantum states, gates, and circuits. Now, let's zoom out a bit. In this section, we will explore quantum computing through different frameworks that will help you navigate conversations, headlines, and articles about quantum computing with a more critical eye.\n", + "\n", + "There is no doubt that there is a lot of excitement about quantum computing, and the possibilities this technology could offer. One might even go so far as to call it \"hype.\" As is always the case when there is hype around a new discovery, it can be hard to tell fact from fiction. With that in mind, it is best to start with what quantum computing is not:\n", + "\n", + "* Quantum computing is not going to replace traditional, classical computers \u2014 nor is it going to end up in a \"quantum cell phone\"\n", + "* It is not a way to \"simultaneously check all possible answers at the same time\"\n", + "* It is not universally better than classical computers for all tasks\n", + "* It is not in a war with AI\n", + "* It is not useless until we achieve fault tolerance or error correction\n", + "* It isn't magic\n", + "\n", + "Hopefully that did not steer you away from this course entirely or make you think there is actually nothing of value here. Quite the contrary! Quantum computing has the potential to be immensely powerful \u2014 but only for certain applications. Luckily, those applications include areas of active research that could fundamentally transform the way we approach important problems, such as chemistry simulations, materials exploration, and analysis of large data sets. Before we explore these application areas, let's first dig into some of these misconceptions in more detail.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Scaling\n", + "\n", + "Another common misconception regarding quantum computers is that the more qubits they have, the more powerful they are. While this is not necessarily wrong, it does not paint the full picture. While scaling up in quantity is certainly a crucial element, it is no more important than quality of the qubits themselves. Quality is measured in a number of ways, one of the most important being coherence and dephasing times, or $T_1$ and $T_2$, respectively. These are measurements of how long quantum information in a qubit can remain stable. When the first superconducting qubits were demonstrated, this number was on the order of nanoseconds (Nakamura et al., 1999); now, we regularly produce qubits that have stable coherence times of hundreds of microseconds.\n", + "\n", + "Another critical component we point to when we look to see how quantum computers are improving is speed. To measure speed we use something called Circuit Layer Operations per Second (CLOPS). CLOPS incorporates both the time to run a circuit as well as the real-time and near-time classical computation, enabling it to serve as a holistic single measure of speed.\n", + "\n", + "![Diagram showing the three key metrics for quantum computing progress: quantity (number of qubits), quality (coherence times), and speed (CLOPS)](https://quantum.cloud.ibm.com/learning/images/courses/use-a-qc-today/quantum-computing-context/scaling.avif)\n", + "\n", + "All three of these elements together are needed to continue building the path towards a fault-tolerant, universal quantum computer. That's why, when looking at the IBM Quantum\u00ae roadmap, you'll notice that some jumps between processors do not have huge increases in qubit count. For example, notice the modest qubit increase between Heron and Nighthawk, because that is not the real focus of that improvement. Instead, Nighthawk implements a new connectivity topology that will allow for different error correction codes.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Error correction versus error mitigation\n", + "\n", + "Error correction remains one of the biggest long-term goals for researchers in quantum computing. It is based on the premise that qubits will always remain somewhat noisy and prone to errors, and if we want to run large-scale algorithms, like Shor's for example, we will need the ability to detect and correct for these errors in real time. There are many types of error-correcting codes, and we refer you to other courses (such as the [Foundations of quantum error correction](https://quantum.cloud.ibm.com/learning/courses/foundations-of-quantum-error-correction) course) if you want to dive more deeply into them.\n", + "\n", + "Error mitigation, on the other hand, is already being used regularly to improve quantum computing results. The idea behind error mitigation is that we accept that errors will occur, and try to predict their behavior to reduce the effects of those errors. There are many error mitigation techniques; many require multiple runs on a quantum computer plus some classical post-processing. It is unlikely that error correction will completely replace error mitigation. Instead, we predict both will be used together to return the best possible results from quantum computers.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Quantum computing components\n", + "\n", + "Earlier, we mentioned that it is a common misconception that quantum computers will one day replace classical computers. This is distinctly not the case; quantum computers and classical computers are not actually at war trying to replace one another. In fact, as noted in the previous section, quantum computers need classical computers to function, for a variety of reasons. When we talk about \"computers\" broadly, we are usually assuming they include all components like a CPU, RAM, memory, and so on. Conversely, a quantum computer does not have all these components. Oftentimes when people talk about a quantum computer, they actually are referring to the QPU, or Quantum Processing Unit, which takes over the processing role from the CPU. The QPU itself is not a general-purpose computer. It does not run an operating system, manage memory, or handle user interfaces. Its sole role is to manipulate qubits according to carefully controlled quantum operations before returning measurement results to a classical system.\n", + "\n", + "In practice, today's quantum computers are best understood as hybrid systems. A classical computer orchestrates the workflow \u2014 preparing inputs, compiling quantum circuits, scheduling jobs, and post-processing results \u2014 while the QPU executes only the quantum portion of the computation. Even as quantum hardware advances, this division of labor is expected to persist, with progress focusing on tighter integration and faster communication between classical systems and QPUs rather than eliminating classical components altogether.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Likely application areas of quantum computing\n", + "\n", + "We broadly sort the areas we believe quantum computing will be most impactful into four categories: optimization, Hamiltonian simulation, Partial Differential Equations (PDEs), and machine learning.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Hamiltonian simulation\n", + "\n", + "This topic is all about simulating quantum mechanical processes found in nature. At its core, it involves two broad tasks: finding the ground state energy of a system described by its Hamiltonian, which encodes the total energy and interactions within the system, and simulating how that system evolves over time (quantum dynamics).\n", + "\n", + "This is one of the most natural application areas for quantum computers: quantum systems are notoriously difficult to simulate on classical computers, because the size of the quantum state space grows exponentially with the number of particles. Quantum computers, by contrast, represent quantum states directly, making them well-suited \u2014 at least in principle \u2014 for these types of problems.\n", + "\n", + "Key application areas include:\n", + "\n", + "* Chemistry and materials science: predicting molecular structure, reaction pathways, binding energies, and material properties\n", + "* Condensed matter physics: studying strongly correlated systems, phase transitions, and exotic quantum states\n", + "* High-energy and nuclear physics: modeling particle interactions\n", + "\n", + "In the long term, advances in Hamiltonian simulation could enable:\n", + "\n", + "* More accurate drug discovery and catalyst design\n", + "* Discovery of new materials for batteries\n", + "* Deeper insight into fundamental physical phenomena\n", + "\n", + "Many of the most well-studied quantum algorithms, such as [SQD](https://quantum.cloud.ibm.com/learning/courses/quantum-diagonalization-algorithms), were developed specifically with Hamiltonian simulation in mind. As a result, this category is often viewed as one of the most scientifically compelling and theoretically grounded use cases for quantum computing.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Optimization\n", + "\n", + "Optimization problems involve finding the best solution from a large set of possible solutions, subject to constraints. These problems appear across science, engineering, and industry, and often become computationally intractable as the problem size grows.\n", + "\n", + "Examples include:\n", + "\n", + "* Scheduling and routing (for example, supply chains, traffic flow, airline scheduling)\n", + "* Portfolio optimization and risk management (finance)\n", + "* Resource allocation and logistics\n", + "* Combinatorial problems such as graph partitioning and max-cut\n", + "\n", + "Many optimization problems are categorized as NP-hard in complexity theory, meaning that classical algorithms typically rely on heuristics or approximations for large instances. Because qubits behave differently from classical bits, we can model solutions differently. This might let us explore solution spaces faster or more completely than classical algorithms.\n", + "\n", + "Common quantum approaches include:\n", + "\n", + "* Variational algorithms, such as the Quantum Approximate Optimization Algorithm (QAOA)\n", + "* Hybrid classical\u2013quantum workflows, where classical solvers guide and refine quantum subroutines\n", + "\n", + "While it is still an open question when \u2014 or for which problems \u2014 quantum optimization will deliver a clear advantage over state-of-the-art classical methods, optimization remains a major area of interest due to its ubiquity and the natural mapping between optimization objectives and quantum Hamiltonians.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Partial Differential Equations (PDEs)\n", + "\n", + "Partial differential equations describe how physical quantities change across space and time. They underpin many of the most important models in science and engineering, including fluid dynamics, electromagnetism, heat transfer, and financial modeling.\n", + "\n", + "Examples include:\n", + "\n", + "* Navier\u2013Stokes equations for fluid flow\n", + "* Schr\u00f6dinger and wave equations\n", + "* Maxwell's equations\n", + "* Black\u2013Scholes and related financial PDEs\n", + "\n", + "Solving PDEs numerically on classical computers often requires fine spatial grids and long time evolutions, leading to high computational cost and memory usage.\n", + "\n", + "Quantum algorithms for PDEs typically rely on the following:\n", + "\n", + "* Mapping PDEs to large systems of linear equations\n", + "* Quantum linear algebra subroutines, such as the HHL algorithm and its variants\n", + "* Hybrid workflows where classical preprocessing and postprocessing surround quantum cores\n", + "\n", + "In theory, certain quantum approaches can offer exponential or polynomial speedups under specific assumptions (such as efficient state preparation and readout). In practice, PDE solving is expected to be a longer-term application, closely tied to progress in fault-tolerant quantum computing and quantum\u2013classical integration with high-performance computing (HPC) systems.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Machine learning\n", + "\n", + "Quantum machine learning (QML) explores how quantum computers might enhance or accelerate aspects of machine learning and data analysis. This includes both of the following:\n", + "\n", + "* Using quantum computers to explore classification problems with different classification behavior than classical algorithms\n", + "* Developing new models that are inherently quantum in nature\n", + "\n", + "Proposed applications include the following:\n", + "\n", + "* Classification and clustering\n", + "* Kernel methods and feature maps\n", + "* Optimization subroutines within training loops\n", + "\n", + "Many QML algorithms leverage the following:\n", + "\n", + "* Parameterized quantum circuits as trainable models\n", + "* Variational optimization techniques\n", + "* Quantum kernels that implicitly operate in high-dimensional feature spaces\n", + "\n", + "However, machine learning is a particularly challenging area for quantum advantage. Classical machine learning is extremely mature, and quantum models must contend with issues such as data loading, noise, and scaling.\n", + "\n", + "As a result, current research focuses on these areas:\n", + "\n", + "* Identifying specific regimes where quantum models might outperform classical ones\n", + "* Exploring QML as part of hybrid workflows rather than standalone replacements\n", + "* Understanding expressivity, trainability, and generalization of quantum models\n", + "\n", + "Quantum machine learning remains an active research area, with potential long-term impact \u2014 but also significant open questions about when and where practical advantage will emerge.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "This lesson has made it clear that quantum advantage isn't about replacing computers. It's about expanding what's computable. It is one of the most ambitious engineering projects humans have ever attempted. And like all ambitious projects, it's messy, slow, and pretty amazing.\n", + "\n", + "If you want a follow-up on how these algorithms actually work, the next lesson will show you where to go from here based on your interests and career goals.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\u00a9 IBM Corp., 2017-2026" + ] + } + ], + "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 +} diff --git a/IBM-Course/02-quantum-mechanics-basics.ipynb b/IBM-Course/02-quantum-mechanics-basics.ipynb new file mode 100644 index 0000000..f053682 --- /dev/null +++ b/IBM-Course/02-quantum-mechanics-basics.ipynb @@ -0,0 +1,415 @@ +{ + "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": [ + "# Quantum mechanics basics\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/lKFElrwEZrU?si=jdygTwHALqlrJAez) 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/lKFElrwEZrU](https://youtu.be/lKFElrwEZrU).\n", + "\n", + "In the previous lesson, we learned how to produce an entangled state of two qubits, known as a \"Bell state.\" When we measured the state, we saw that the measurements of the two qubits were *correlated*: when one was measured to be `0` then the other was also measured `0` and when one was `1` the other was measured `1`, too. We saw that this is a hallmark of quantum entanglement. Today we'll dig deeper into this state and what it reveals about the quantum physics fundamental to quantum computing.\n", + "\n", + "## The Bell state\n", + "\n", + "Many of the quantum phenomena that make quantum computers behave differently from classical computers are already present in the deceptively simple Bell state we produced in the previous lesson. Let's bring back that Bell state circuit:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import QuantumCircuit\n", + "\n", + "qc = QuantumCircuit(2)\n", + "qc.h(0)\n", + "qc.cx(0, 1)\n", + "qc.measure_all()\n", + "qc.draw(\"mpl\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The image above represents the quantum circuit for making the Bell state $\\vert\\Phi^+\\rangle$. The two black horizontal lines represent our two qubits, and the boxes and other symbols on those lines represent gates or operations performed on the corresponding qubits. The gray double line is a classical information bus that allows us to store the classical information that we obtain by measuring the two qubits. We're going to dig into the details of this circuit and the resulting Bell state in order to understand the basics of quantum computing.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The math of quantum computing\n", + "\n", + "### Quantum state representation\n", + "\n", + "First, we need a common language in which to discuss quantum states and circuits. There are a couple different ways to represent quantum states. The first is with **Dirac notation**. In Dirac notation, the state looks like this:\n", + "\n", + "$$\n", + "\\vert \\Phi^+\\rangle =\\frac{1}{\\sqrt{2}} ( \\vert 00 \\rangle + \\vert 11 \\rangle )\n", + "$$\n", + "\n", + "Here, the state is written inside angle brackets and vertical bars. The two terms each represent the two possible measurement outcomes of the state. So when we measure this state, we will either find that both of the qubits are in the state `0` or that both are in the state `1`. The $\\frac{1}{\\sqrt{2}}$ is called a \"normalization constant.\" It is there to ensure that the sum of the squares each of the coefficients in the state all add up to $1$. We'll discuss why this is the case later, in the section about measurements.\n", + "\n", + "The second way to represent a state is in the standard language of linear algebra: as a vector, where each entry of the vector represents a different possible measurement outcome. In this notation, our Bell state would be written like this:\n", + "\n", + "$$\n", + "\\vert\\phi^+\\rangle = \\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 1 \\end{pmatrix} ~.\n", + "$$\n", + "\n", + "By convention, the entries of the vector are ordered as follows:\n", + "\n", + "* The first entry corresponds to the two-qubit state $\\vert00\\rangle$\n", + "* The second to $\\vert01\\rangle$\n", + "* The third to $\\vert10\\rangle$\n", + "* The fourth to $\\vert11\\rangle$\n", + "\n", + "As expected, in the Bell state vector $\\vert\\Phi^+\\rangle$, the first and fourth entries are nonzero, while the second and third entries are zero. The normalization constant $1/\\sqrt{2}$ ensures that the length of the vector is $1$.\n", + "\n", + "#### A note on the ordering of qubits\n", + "\n", + "Qiskit uses **little endian** ordering. This means that the rightmost qubit is considered the first (or least significant) qubit, and the leftmost qubit is the most significant qubit. So, when we write a state like $\\vert01\\rangle$:\n", + "\n", + "* the rightmost bit corresponds to qubit $0$, and is in the state $\\vert1\\rangle$.\n", + "* the leftmost bit corresponds to qubit $1$, and is in the state $\\vert0\\rangle$.\n", + "\n", + "### Gate representation\n", + "\n", + "Just as states can be represented as **vectors**, gates can be represented as **matrices**. A gate acts on a state by transforming its vector into a new vector.\n", + "\n", + "Each gate corresponds to a specific matrix that dictates how the state will be transformed. We apply this transformation by multiplying the gate matrix and the original state vector, with the gate matrix to the left of the state vector, like this:\n", + "\n", + "$$\n", + "U |\\psi\\rangle\n", + "$$\n", + "\n", + "where $U$ represents the gate matrix and $|\\psi\\rangle$ represents the state vector.\n", + "\n", + "Let's look at the Hadamard gate as an example. The Hadamard gate is a single-qubit gate (the red box labelled \"H\" in the circuit diagram above) that transforms the state $\\vert0\\rangle$ to $\\frac{1}{\\sqrt{2}}(\\vert0\\rangle+\\vert1\\rangle)$ and the state $\\vert1\\rangle$ to $\\frac{1}{\\sqrt{2}}(\\vert0\\rangle-\\vert1\\rangle)$. In matrix notation, the Hadamard looks like:\n", + "\n", + "$$\n", + "H = \\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 & 1 \\\\ 1 & -1 \\end{pmatrix} ~.\n", + "$$\n", + "\n", + "#### Check your understanding\n", + "\n", + "Use matrix multiplication to show that the Hadamard matrix transforms the states as expected. (If needed, you can [learn how to do matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication).)\n", + "\n", + "
\n", + "Answer\n", + "\n", + "$$\n", + " H |0\\rangle = \\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 & 1 \\\\ 1 & -1 \\end{pmatrix} \\begin{pmatrix} 1 \\\\ 0 \\end{pmatrix} = \\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 \\\\ 1 \\end{pmatrix} ~\\checkmark\n", + " $$\n", + "\n", + " $$\n", + " H |1\\rangle = \\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 & 1 \\\\ 1 & -1 \\end{pmatrix} \\begin{pmatrix} 0 \\\\ 1 \\end{pmatrix} = \\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 \\\\ -1 \\end{pmatrix} ~\\checkmark\n", + " $$\n", + "\n", + "
\n", + "\n", + "There are a few things to keep in mind about gate matrices:\n", + "\n", + "1. They are always square, $N \\times N$ matrices, where $N$ is also the dimension of the state vector it is applied to. For example, when you only have a single qubit, the state vector is two-dimensional, representing the two possible states 0 and 1 of the qubit. In this case, the dimensions of gate matrix applied to this system would be $2\\times 2$.\n", + "2. Quantum gates are *reversible*. In other words, you can find another matrix that is the gate's *inverse*, which undoes the action of the gate and transforms the qubits back to their original state.\n", + "3. Quantum gates also preserve the length of the vectors they transform. Quantum state vectors will always have length $1$ (guaranteed by the normalization constants we discussed earlier). The gates do not lengthen or shorten them, but simply rotate them.\n", + "\n", + "These are all properties of *unitary matrices*. If you're curious about more of the mathematical properties of unitary matrices, you can read more about them in John Watrous's lesson on [multiple systems](https://quantum.cloud.ibm.com/learning/courses/basics-of-quantum-information/multiple-systems/introduction) in the Basics of Quantum Information course.\n", + "\n", + "### How measurements work\n", + "\n", + "When we measure a quantum state, the result is always one of the possible outcomes (for a single qubit, either `0` or `1`). Which outcome we get is random, but the quantum state tells us the probabilities of each outcome.\n", + "\n", + "The entries in the state vector determine these probabilities. To get the probability of a particular outcome, we take the *square of the entry* corresponding to that outcome. For example, if a qubit is in the state:\n", + "\n", + "$$\n", + "|\\psi\\rangle = \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 \\\\\n", + "1\n", + "\\end{pmatrix}\n", + "= \\frac{1}{\\sqrt{2}}(|0\\rangle + |1\\rangle),\n", + "$$\n", + "\n", + "the first entry (corresponding to `0`) is $1/\\sqrt{2}$, and the second entry (corresponding to `1`) is also $1/\\sqrt{2}$. Squaring these numbers gives\n", + "\n", + "$$\n", + "\\left(\\frac{1}{\\sqrt{2}}\\right)^2 = \\frac{1}{2} = 0.5,\n", + "$$\n", + "\n", + "which means there is a 50% chance of measuring `0` and a 50% chance of measuring `1`.\n", + "\n", + "Recall that the sum of all the squared entries always adds up to 1. This makes sense because when we measure, we are guaranteed to get some outcome, so the probabilities of all possible outcomes must total 100%.\n", + "\n", + "After measurement, the qubit **collapses** to the observed outcome, and any previous superposition is lost. The qubit now behaves like a classical bit. Measurements are fundamentally different from quantum gates. While gates change quantum states in a **deterministic and reversible** manner, measurement is **inherently random and irreversible**.\n", + "\n", + "### Measurement in different bases\n", + "\n", + "By default, when you measure a qubit in a quantum circuit, you are measuring the qubit's state only along one axis. This is called the computational basis, or $Z$ basis, which is defined by the states $\\vert 0\\rangle$ and $\\vert 1\\rangle$. You can think of the $\\vert 0\\rangle$ state as a vector pointing straight up, and the $\\vert 1\\rangle$ state as a vector pointing straight down. So, a measurement in the $Z$ basis answers the question, \u201cIs the qubit's state pointing up or down?\u201d\n", + "\n", + "But this is not the only kind of question we can ask of a qubit. A qubit's state vector does not only point either up or down. A superposition of $\\vert 0\\rangle$ and $\\vert 1\\rangle$ will result in a state vector that points in any direction in three-dimensional space \u2014 what direction precisely depends on the relative amplitudes and phases of the two parts of the superposition. So, while a standard, $Z$-basis measurement asks \"up or down?\" you can also ask \"left or right?\" or \"forward or backward?\"\n", + "\n", + "These questions correspond to measuring in different bases. Each basis has its own set of two basis vectors, which define the two possible measurement outcomes in that basis (like $\\vert 0\\rangle$ or $\\vert 1\\rangle$ for the $Z$-basis).\n", + "\n", + "* Z basis measurement outcomes collapse to $\\vert 0\\rangle$ or $\\vert 1\\rangle$\n", + "* X basis measurement outcomes collapse to $\\vert +\\rangle$ or $\\vert -\\rangle$\n", + "* Y basis measurement outcomes collapse to $\\vert i\\rangle$ or $\\vert -i\\rangle$\n", + "\n", + "where\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "\\lvert +\\rangle &= \\frac{1}{\\sqrt{2}}(\\lvert 0\\rangle + \\lvert 1\\rangle) \\\\\n", + "\\lvert -\\rangle &= \\frac{1}{\\sqrt{2}}(\\lvert 0\\rangle - \\lvert 1\\rangle) \\\\\n", + "\\lvert i\\rangle &= \\frac{1}{\\sqrt{2}}(\\lvert 0\\rangle + i\\lvert 1\\rangle) \\\\\n", + "\\lvert -i\\rangle &= \\frac{1}{\\sqrt{2}}(\\lvert 0\\rangle - i\\lvert 1\\rangle)\n", + "\\end{aligned}\n", + "$$\n", + "\n", + "where $i=\\sqrt{\u22121}$ is the imaginary unit. Here we're seeing for the first time superpositions with a *phase* difference between the two parts. Phase is typically written as $e^{i\\theta}$, where $\\theta$ is the angle of a quantum state's amplitude in the complex plane \u2014 a two-dimensional plane where the horizontal axis represents real numbers and the vertical axis represents imaginary ones. You can think of it more intuitively as how shifted one wave is relative to another: are their peaks aligned, or is one wave shifted so its peak meets the other's trough?\n", + "\n", + "### Pauli matrices and observables\n", + "\n", + "There are three matrices, the so-called Pauli matrices, that relate to these three different basis choices $X$, $Y$, and $Z$:\n", + "\n", + "$$\n", + "X = \\begin{pmatrix} 0 & 1 \\\\ 1 & 0 \\end{pmatrix}, \\quad\n", + "Y = \\begin{pmatrix} 0 & -i \\\\ i & 0 \\end{pmatrix}, \\quad\n", + "Z = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix}.\n", + "$$\n", + "\n", + "How exactly do these relate to the measurement bases? At first glance, these look like ordinary gate matrices \u2014 and they are. Each Pauli matrix can act on a qubit and change its state:\n", + "\n", + "* **Pauli-X** flips $|0\\rangle$ and $|1\\rangle$, like a classical NOT gate.\n", + "* **Pauli-Z** leaves $|0\\rangle$ unchanged but multiplies $|1\\rangle$ by $-1$, changing the relative phase.\n", + "* **Pauli-Y** flips the qubit and introduces a phase.\n", + "\n", + "But Pauli matrices have a second, equally important interpretation. In quantum mechanics, any measurable quantity is called an *observable*, and observables are represented by matrices. The Pauli matrices correspond to measurements along three different axes, and their eigenstates correspond to the two possible measurement outcomes along each axis. (If you aren't familiar with the term eigenstate, that's okay \u2014 they are just special vectors associated with a given matrix.)\n", + "\n", + "* $Z$ \u2192 measurement in the Z basis ($|0\\rangle$, $|1\\rangle$)\n", + "* $X$ \u2192 measurement in the X basis ($|+\\rangle$, $|-\\rangle$)\n", + "* $Y$ \u2192 measurement in the Y basis ($|i\\rangle$, $|-i\\rangle$)\n", + "\n", + "This explains why Pauli matrices seem to do double duty. They both act on states (as gates) and define measurement directions (as observables). Both roles come from the same underlying mathematics.\n", + "\n", + "So how, in practice, do you measure in the X or Y basis? By default, our quantum computers are only set up to measure in the Z basis. So, you need to change bases by rotating the qubit's state vector in such a way that the information you're interested in, either X or Y, is now pointing in the Z direction. Then, you just perform a Z measurement as usual.\n", + "\n", + "For example, measuring in the X basis can be done by applying a Hadamard gate, and then measuring in the Z basis. The Hadamard rotates the state so that \u201cX-information\u201d becomes \u201cZ-information.\u201d After that, a normal measurement does the job.\n", + "\n", + "You will see more of the Pauli matrices in the next lesson, when we apply our new quantum-circuit-writing skills to a real problem in quantum physics.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Bell state circuit\n", + "\n", + "Now that we have a starting point \u2014 we know that states can be represented by vectors, gates can be represented by matrices, and measurements cause a state to \"collapse\" \u2014 let's walk through the circuit that creates and measures the Bell state above.\n", + "\n", + "We start with the initial state of two qubits in $|00\\rangle$:\n", + "\n", + "$$\n", + "|00\\rangle =\n", + "\\begin{pmatrix}\n", + "1 \\\\\n", + "0 \\\\\n", + "0 \\\\\n", + "0\n", + "\\end{pmatrix}\n", + "$$\n", + "\n", + "### Create the superposition\n", + "\n", + "The circuit begins by applying a Hadamard gate to qubit 0. As we saw in the previous section, the Hadamard takes the qubit from a definite state, either $|0\\rangle$ or $|1\\rangle$, into a combination of both of those states. Recall that the Hadamard gate is:\n", + "\n", + "$$\n", + "H = \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 & 1 \\\\\n", + "1 & -1\n", + "\\end{pmatrix}\n", + "$$\n", + "\n", + "To apply it to the first qubit in a two-qubit system, we use an expanded 4x4 matrix that applies $H$ to qubit 0 while leaving qubit 1 unchanged. Think of it as \u201capply $H$ to the first qubit and don\u2019t touch the second qubit\u201d:\n", + "\n", + "$$\n", + "H_0 =\n", + "\\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 & 1 & 0 & 0 \\\\\n", + "1 & -1 & 0 & 0 \\\\\n", + "0 & 0 & 1 & 1 \\\\\n", + "0 & 0 & 1 & -1\n", + "\\end{pmatrix}\n", + "$$\n", + "\n", + "Then we multiply this by the initial state vector:\n", + "\n", + "$$\n", + "H_0 |00\\rangle\n", + "=\n", + "\\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 & 1 & 0 & 0 \\\\\n", + "1 & -1 & 0 & 0 \\\\\n", + "0 & 0 & 1 & 1 \\\\\n", + "0 & 0 & 1 & -1\n", + "\\end{pmatrix}\n", + "\\begin{pmatrix}\n", + "1 \\\\\n", + "0 \\\\\n", + "0 \\\\\n", + "0\n", + "\\end{pmatrix}\n", + "=\n", + "\\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 \\\\\n", + "1 \\\\\n", + "0 \\\\\n", + "0\n", + "\\end{pmatrix}\n", + "=\n", + "\\frac{1}{\\sqrt{2}}(|00\\rangle + |01\\rangle)\n", + "$$\n", + "\n", + "Now qubit 0 is in a superposition state.\n", + "\n", + "#### More on quantum superposition\n", + "\n", + "A quantum superposition of the type above is often described as the qubit being in both states at the same time. However, when we measure this superposition state, the outcome is always $0$ or $1$ \u2014 we can never directly observe the superposition itself. In fact, the phrase \u201cthe qubit is in both states at the same time\u201d can be misleading. A more precise way to describe it is that a superposition is a mathematical description of the quantum state that allows us to calculate the probabilities of different measurement outcomes. Some people think superpositions are physically real, but this is a philosophical interpretation that cannot be tested; quantum mechanics only predicts the probabilities of measurement results.\n", + "\n", + "Unlike a classical probability distribution, a quantum superposition also allows the different components to interfere with each other, like overlapping waves that can amplify or cancel each other. This interference is what allows quantum algorithms to produce patterns of measurement outcomes that would be impossible with classical randomness alone.\n", + "\n", + "***\n", + "\n", + "### Entangle the qubits\n", + "\n", + "Next, a controlled-NOT (CNOT) gate (shown as the blue dot, vertical line, and circle with the plus sign connecting the two qubits) is applied. This gate entangles the two qubits together. After this step, the state of one qubit cannot be described independently of the other.\n", + "\n", + "The CNOT gate flips qubit 1 (called the target qubit) only if qubit 0 (called the control qubit) is in the state $\\vert 1\\rangle $. Its matrix is:\n", + "\n", + "$$\n", + "\\text{CNOT} =\n", + "\\begin{pmatrix}\n", + "1 & 0 & 0 & 0 \\\\\n", + "0 & 0 & 0 & 1 \\\\\n", + "0 & 0 & 1 & 0 \\\\\n", + "0 & 1 & 0 & 0\n", + "\\end{pmatrix}\n", + "$$\n", + "\n", + "Apply it to the state from Step 1:\n", + "\n", + "$$\n", + "\\begin{pmatrix}\n", + "1 & 0 & 0 & 0 \\\\\n", + "0 & 0 & 0 & 1 \\\\\n", + "0 & 0 & 1 & 0 \\\\\n", + "0 & 1 & 0 & 0\n", + "\\end{pmatrix} \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 \\\\\n", + "1 \\\\\n", + "0 \\\\\n", + "0\n", + "\\end{pmatrix}\n", + "=\n", + "\\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 \\\\\n", + "0 \\\\\n", + "0 \\\\\n", + "1\n", + "\\end{pmatrix}\n", + "=\n", + "\\frac{1}{\\sqrt{2}}(|00\\rangle + |11\\rangle)\n", + "$$\n", + "\n", + "Now the qubits are entangled: measuring one immediately determines the other.\n", + "\n", + "#### More on quantum entanglement\n", + "\n", + "Entanglement, like superposition, is a quantum phenomenon that has no classical analog. In classical systems, two correlated bits could have their values linked, but each bit still has a definite value \u2014 even if we don\u2019t know it. For example, if two coins are glued together so they always land the same way, one coin being heads immediately tells you the other is heads. But before we look, each coin is already in a definite state.\n", + "\n", + "With entangled qubits, the situation is fundamentally different. Before measurement, neither qubit has a definite value on its own. Only the pair has a well-defined state. Measuring one qubit instantly affects the probabilities for the other, no matter how far apart they are. This is a purely quantum effect: it cannot be explained by classical statistics or hidden information about the individual qubits.\n", + "\n", + "### Measure the states\n", + "\n", + "Finally, both qubits are measured. When we measure, the quantum state collapses to one of the classically allowed states:\n", + "\n", + "* `00` with probability $|1/\\sqrt{2}|^2 = 0.5$.\n", + "* `11` with probability $|1/\\sqrt{2}|^2 = 0.5$.\n", + "\n", + "This reproduces the correlated measurement outcomes we observed in the circuit in Lesson 1.\n", + "\n", + "## Conclusion\n", + "\n", + "In this lesson, we've taken a whirlwind tour of the quantum mechanical concepts and mathematical tools needed to confidently and independently run quantum circuits on a quantum computer. We introduced how quantum states are represented, how gates transform those states, how measurement works, and how superposition and entanglement arise naturally from simple circuits.\n", + "\n", + "In Lesson 3, we'll put these ideas into practice by walking through the full workflow of solving a toy problem on a quantum computer and interpreting the results.\n", + "\n", + "#### Learning objective\n", + "\n", + "Recall the learning objective from Lesson 1, where we challenged you to change the circuit to create the $\\Psi^-$ Bell state. Now, using that circuit, work through the matrix algebra and confirm that your circuit produces the desired state. (Hint: you'll need to figure out the matrix form of a NOT or X gate.)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\u00a9 IBM Corp., 2017-2026" + ] + } + ], + "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 +} diff --git a/IBM-Course/03-your-first-quantum-experiment.ipynb b/IBM-Course/03-your-first-quantum-experiment.ipynb new file mode 100644 index 0000000..67179ad --- /dev/null +++ b/IBM-Course/03-your-first-quantum-experiment.ipynb @@ -0,0 +1,485 @@ +{ + "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": [ + "# Your first quantum experiment\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/kniiVC538nY?si=13OJnaO5jyAUmoPQ) 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/kniiVC538nY](https://youtu.be/kniiVC538nY).\n", + "\n", + "By now, you've run your first quantum circuit and learned the basics of quantum computing: how quantum states are represented, how gates act on those states, and how quantum features like superposition and entanglement are involved. Now it's time to put all of this into practice and solve your first problem on a quantum computer.\n", + "\n", + "We'll explore the broader landscape of quantum-suitable problems in a later lesson. For now, we'll focus on a problem in the domain of nature simulation: using a quantum computer as a cleaner, more controllable stand-in for a natural quantum system. In fact, this was the first application Richard Feynman envisioned for quantum computers in the 1980s. As he famously put it: \"Nature isn't classical, dammit, and if you want to make a simulation of nature, you'd better make it quantum mechanical...\"\n", + "\n", + "In this lesson, we'll follow that principle to simulate the interaction between two spins, which you can think of as tiny magnets. Depending on the sign of their interaction, they might prefer to align and point in the same direction, or anti-align and point in opposite directions. We'll focus on the latter case because it often leads to more interesting \u2014 and more challenging \u2014 behavior. Once we understand this small two-qubit system, we'll show how the same ideas scale up, allowing quantum computers to take advantage of their exponential scaling when simulating large spin systems.\n", + "\n", + "## Two interacting magnets\n", + "\n", + "For this problem, we're going to use two qubits, one for each spin in our model. Each spin can be pointing up (qubit state $|0\\rangle$), down (qubit state $|1\\rangle$), or in a superposition of the two states.\n", + "\n", + "If the spins have an *antiferromagnetic* interaction, it means they want to anti-align, so when one is up, the other wants to be down, and vice-versa.\n", + "\n", + "Now suppose there is also a magnetic field pointing from left to right in our system. Because this field points across the usual up-down direction of the spins, it is called a transverse field. This field can flip spins, which causes the lowest energy configuration to be a specific superposition of up-and-down spin arrangements rather than any single definite spin pattern.\n", + "\n", + "We can describe all of these effects using a mathematical object called a Hamiltonian. The Hamiltonian tells us the energy of the system for a given arrangement of spins:\n", + "\n", + "$$\n", + "H = J Z_1 Z_0 + h_x (X_1 + X_0)\n", + "$$\n", + "\n", + "where $J$ is a coefficient controlling the strength of the interaction between spins and $h_x$ is a coefficient for the strength of the external magnetic field. $Z_1 Z_0$ rewards or penalizes the spins depending on whether they are aligned or anti-aligned, and $X_0$ and $X_1$ represent the spin-flipping effect of the magnetic field.\n", + "\n", + "In physics, systems tend to settle into the state with the lowest possible energy, called the ground state. Finding this lowest-energy state is a common problem, but it requires optimization techniques that are beyond the scope of this lesson.\n", + "\n", + "Instead, we will ask a simpler question: If we prepare the spins in a particular state, what is the energy of that state?\n", + "\n", + "To answer this, we will:\n", + "\n", + "1. Prepare the spins in a state of our choosing\n", + "2. Measure the energy of that state using the Hamiltonian above\n", + "\n", + "This is exactly the kind of calculation that appears inside larger quantum algorithms, such as variational algorithms, which you can explore in later courses.\n", + "\n", + "## Qiskit implementation\n", + "\n", + "Before jumping into writing code, we need a bit of context setting. When we run a quantum circuit, we always end by measuring the qubits. But there are two different kinds of questions we might want to ask about the result of that measurement: Sometimes, we just want to know what the state of the qubit is. Other times, we want to know, given the quantum state, what is the value of a physical quantity, like energy?\n", + "\n", + "In Qiskit, these two types of questions are handled by two different tools, called primitives.\n", + "\n", + "`Sampler` answers the first kind of question. It runs the circuit many times and tells us how often we measure each possible outcome, like `00`, `01`, `10`, or `11`. The result is a histogram that shows the probability of each measurement outcome.\n", + "\n", + "`Estimator` answers the second kind of question. Instead of giving us a histogram, it combines many measurements behind the scenes to compute a single number, such as the energy of the state according to a Hamiltonian we provide.\n", + "\n", + "To help you understand when and why we would use each of these tools, we'll walk through two complete workflows (called \"Qiskit patterns\") applied to the same two-qubit system.\n", + "\n", + "#### Qiskit patterns workflow\n", + "\n", + "The Qiskit patterns workflow is a general framework we use to solve quantum problems with Qiskit. It breaks a quantum computing task into four steps:\n", + "\n", + "1. Map the problem to a model that can be represented by quantum circuits\n", + "2. Optimize the circuit to be run on a specific backend\n", + "3. Execute the optimized circuit on the selected backend\n", + "4. Post-process the raw measurement data\n", + "\n", + "### Experiment 1: Use `Sampler` to measure the state\n", + "\n", + "#### Map\n", + "\n", + "In general, the mapping step is where we figure out how to represent a real-world problem in terms of qubits, operators, and measurements. In many applications, this is the trickiest and most involved part of the workflow \u2014 even simple questions, like \"what does each qubit represent?\" do not always have straightforward answers.\n", + "\n", + "In this experiment, however, the mapping is deliberately simple. Each physical degree of freedom maps directly onto a single qubit. Because of this one-to-one correspondence, the mapping step reduces to choosing the quantum state we want to prepare and writing a circuit that prepares and measures that state.\n", + "\n", + "Here, we'll prepare an entangled Bell state, similar to the one we made in the very first lesson of this course:\n", + "\n", + "$$\n", + "\\vert\\Psi\\rangle = \\frac{1}{\\sqrt{2}}(\\vert 10\\rangle - \\vert 01\\rangle)\n", + "$$\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Import Qiskit primitives\n", + "from qiskit import QuantumCircuit\n", + "\n", + "# Make state\n", + "qc = QuantumCircuit(2)\n", + "qc.h(0)\n", + "qc.cx(0, 1)\n", + "qc.x(1)\n", + "qc.z(0)\n", + "\n", + "# Measure state\n", + "qc.measure_all()\n", + "\n", + "# Draw circuit\n", + "qc.draw(\"mpl\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Optimize\n", + "\n", + "Before we run our circuit on a quantum computer (or a simulator if you have exhausted your free time on real quantum computers for the month), we need to prepare it for execution. This step is called optimization. (Note: this use of the word \"optimization\" can be confusing. In quantum computing, optimization problems refer to a specific class of problems. Here, we're using optimization to describe a required preparation step that every quantum circuit goes through before it can be run efficiently on hardware.)\n", + "\n", + "During optimization:\n", + "\n", + "1. We choose the backend \u2014 either a real quantum computer or a simulator.\n", + "2. We assign our circuit's qubits to physical qubits on the device.\n", + "3. We rewrite the circuit using only the gates that the quantum computer can actually perform.\n", + "4. Optionally implement error mitigation and suppression techniques to reduce the effects of noise.\n", + "\n", + "In Qiskit, this is handled automatically by the transpiler. Once you pick your backend, the transpiler does all the work to make your circuit ready for execution, so you don't have to manually adjust the gates or qubit assignments. The transpiler also offers different optimization levels, which can help reduce errors if needed. The optimization is done in stages called 'passes'. So this optimization will be handled by the `pass_manager` in the code below. To learn more about errors and error mitigation, see Olivia Lane's [Quantum Computing in Practice](https://quantum.cloud.ibm.com/learning/courses/quantum-computing-in-practice) course.\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": [ + "# Load the Qiskit Runtime service\n", + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "\n", + "## Load the Qiskit Runtime service\n", + "# # service = QiskitRuntimeService()\n", + "# Use the least busy backend, or uncomment the loading of a specific backend like \"ibm_brisbane\".\n", + "backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)\n", + "# backend = service.backend(\"ibm_brisbane\")\n", + "print(backend.name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Transpile the circuit and optimize for running on the quantum computer selected\n", + "# Step 2: Transpile\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "\n", + "target = backend.target\n", + "pm = generate_preset_pass_manager(target=target, optimization_level=3)\n", + "qc_isa = pm.run(qc)\n", + "\n", + "qc_isa.draw(\"mpl\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Execute\n", + "\n", + "Now we're ready to execute! We'll load Sampler, then send the job to the backend.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load the Runtime primitive and session\n", + "from qiskit_ibm_runtime import SamplerV2 as Sampler\n", + "\n", + "sampler = Sampler(mode=backend)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or, if you're using a simulator, you can uncomment and run this cell instead:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "## Load the backend sampler\n", + "# from qiskit.primitives import BackendSamplerV2\n", + "\n", + "## Load the Aer simulator and generate a noise model based on the currently-selected backend.\n", + "# from qiskit_aer import AerSimulator\n", + "# from qiskit_aer.noise import NoiseModel\n", + "\n", + "# noise_model = NoiseModel.from_backend(backend)\n", + "\n", + "## Define a simulator using Aer, and use it in Sampler.\n", + "# backend_sim = AerSimulator(noise_model=noise_model)\n", + "# sampler_sim = BackendSamplerV2(backend=backend_sim)\n", + "\n", + "## Alternatively, load a fake backend with generic properties and define a simulator.\n", + "## backend_gen = GenericBackendV2(num_qubits=18)\n", + "## sampler_gen = BackendSamplerV2(backend=backend_gen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "job = sampler.run([qc_isa], shots=100)\n", + "# job = sampler_sim.run([qc_isa]) # uncomment if you want to run on a simulator\n", + "res = job.result()\n", + "counts = res[0].data.meas.get_counts()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Post-process\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.visualization import plot_histogram\n", + "\n", + "print(\"counts = \", counts)\n", + "plot_histogram(counts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that the majority of counts are in either `01` or `10`, meaning that when one qubit was measured to be `0`, the other was `1`, and vice-versa. This is consistent with the Bell state $\\vert \\Psi^- \\rangle$ we prepared.\n", + "\n", + "### Experiment 2: Use `Estimator` to measure the energy\n", + "\n", + "Now that we've seen how to sample a quantum state, let's use Estimator to compute the energy of our Bell state $\\vert \\Psi^- \\rangle = \\frac{1}{\\sqrt{2}}(\\vert 01 \\rangle - \\vert 10 \\rangle)$.\n", + "\n", + "#### Map\n", + "\n", + "As a reminder, the energy of the system is determined by the interaction between the spins ($J$) and the external magnetic field ($h_x$) as captured by the Hamiltonian:\n", + "\n", + "$$\n", + "H = J Z_1 Z_0 + h_x (X_1 + X_0)\n", + "$$\n", + "\n", + "Each term in the Hamiltonian tells us how a certain combination of spins contributes to the energy. In Qiskit, we can represent these terms as Pauli operators, which are just labels for simple actions on qubits:\n", + "\n", + "* $Z_1 Z_0$ acts with a $Z$ on both qubits.\n", + "* $X_0$ acts with $X$ on qubit 0.\n", + "* $X_1$ acts with $X$ on qubit 1.\n", + "\n", + "A `SparsePauliOp` in Qiskit is a way to store a list of these Pauli operators along with their numerical coefficients. These Pauli operators are the observables that we want the quantum computer to measure \u2014 the quantities that tell us about the system. Using `Estimator`, we can compute the average value of each observable on our state and combine them according to the coefficients in the Hamiltonian to get the total energy.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Import Qiskit primitives\n", + "from qiskit.quantum_info import SparsePauliOp\n", + "\n", + "# Parameters\n", + "J = 1.0 # antiferromagnetic coupling (J<0)\n", + "hx = -0.5 # transverse field strength\n", + "\n", + "# 1. Define the Hamiltonian H = J Z1 Z2 + hx (X1 + X2)\n", + "obs = SparsePauliOp.from_list([(\"ZZ\", J), (\"XI\", hx), (\"IX\", hx)])\n", + "\n", + "# Make state\n", + "qc = QuantumCircuit(2)\n", + "qc.h(0)\n", + "qc.cx(0, 1)\n", + "qc.x(1)\n", + "qc.z(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that we omitted the `qc.measure_all()` line in our code. This is because with `Estimator`, we don't need to specify where to measure in the circuit. We will just tell it which observables we want estimated, and Qiskit takes care of the measurements behind the scenes.\n", + "\n", + "#### Optimize\n", + "\n", + "The optimization step proceeds as before, with the addition of making sure our observables are also written in a way that the quantum computer can understand.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Transpile the circuit and optimize for running on the quantum computer selected\n", + "# Step 2: Transpile\n", + "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", + "\n", + "target = backend.target\n", + "pm = generate_preset_pass_manager(target=target, optimization_level=3)\n", + "qc_isa = pm.run(qc)\n", + "obs_isa = obs.apply_layout(layout=qc_isa.layout)\n", + "\n", + "qc_isa.draw(\"mpl\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Execute\n", + "\n", + "In the Execute step, we'll load `Estimator`, then send the circuit plus the list of observables that we want it to estimate to the quantum computer.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load the Runtime primitive and session\n", + "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", + "\n", + "estimator = Estimator(mode=backend)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load the backend sampler\n", + "\n", + "# noise_model = NoiseModel.from_backend(backend)\n", + "\n", + "# Use Aer simulator in Estimator\n", + "# estimator_sim = BackendEstimatorV2(backend=backend_sim)\n", + "\n", + "# Alternatively, load a fake backend with generic properties and define a simulator.\n", + "# backend_gen = GenericBackendV2(num_qubits=18)\n", + "# estimator_gen = BackendEstimatorV2(backend=backend_gen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pubs = [(qc_isa, obs_isa)]\n", + "job = estimator.run([[qc_isa, obs_isa]])\n", + "res = job.result()\n", + "\n", + "# Uncomment lines below to run the job on the Aer simulator with noise model from real backend\n", + "# job = estimator_sim.run([[qc_isa,obs_isa]])\n", + "# res=job.result()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Post-process\n", + "\n", + "Finally, in the post-processing step, we simply print the energy calculated behind the scenes by `Estimator`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(res[0].data.evs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is the energy of our state!\n", + "\n", + "## Conclusion\n", + "\n", + "In this lesson, we learned how to prepare a simple two-qubit quantum state representing two interacting spins. We saw how to use `Sampler` to observe the distribution of measurement outcomes and how to use `Estimator` to calculate the energy of the state according to the Hamiltonian. Along the way, we saw how the Hamiltonian encodes the interactions between spins and the effects of an external field, and how different states can have different energies.\n", + "\n", + "### Extension to many spins\n", + "\n", + "So far, we have only looked at two spins, which is simple enough to analyze by hand. In real physical systems, such as in a magnet or other complex material, there are often many interacting spins. When the number of spins increases, the Hamiltonian becomes more complex and finding the lowest-energy state becomes much harder. This is where quantum computers can help: by preparing different states and estimating their energies, we can explore low-energy configurations more efficiently than classical computers for large systems.\n", + "\n", + "A natural extension of this experiment would be to increase the number of qubits to represent more spins and adjust the way the spins are prepared to try to find the lowest-energy state. This approach is the essence of variational methods, which you can learn about in the [Variational Quantum Algorithms](https://quantum.cloud.ibm.com/learning/courses/variational-algorithm-design) course.\n", + "\n", + "There are also other quantum approaches to studying ground-state energies that go beyond variational techniques. These methods are not covered here, but are introduced in the [Quantum Diagonalization Algorithms](https://quantum.cloud.ibm.com/learning/courses/quantum-diagonalization-algorithms) course if you're interested in learning more.\n", + "\n", + "#### Learning objective\n", + "\n", + "Go back to the beginning of Experiment 2 and retry it with a different superposition state. Can you find a state with even lower energy than the one we used?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\u00a9 IBM Corp., 2017-2026" + ] + } + ], + "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 +} diff --git a/IBM-Course/04-build-and-run-your-first-quantum-program.ipynb b/IBM-Course/04-build-and-run-your-first-quantum-program.ipynb new file mode 100644 index 0000000..04404cc --- /dev/null +++ b/IBM-Course/04-build-and-run-your-first-quantum-program.ipynb @@ -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", + "
\n", + "Answer\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", + "
\n", + "\n", + "In plain language, what does entanglement give you?\n", + "\n", + "
\n", + "Answer\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", + "
\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", + "
\n", + "Answer\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", + "
\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", + "
\n", + "Answer\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", + "
\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", + "
\n", + "Answer\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", + "
\n", + "\n", + "On an ideal simulator, which two bitstrings should dominate the histogram?\n", + "\n", + "
\n", + "Answer\n", + "\n", + "00 and 11 should dominate.\n", + "\n", + "
\n", + "\n", + "Why wouldn't a perfect simulator always have the exact same number of 00 counts as 11 counts?\n", + "\n", + "
\n", + "Answer\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", + "
\n", + "\n", + "Why might a real quantum computer show some 01 or 10 results even though the simulator didn't?\n", + "\n", + "
\n", + "Answer\n", + "\n", + "Because real devices have noise. Gates and measurements are not perfect, and that can introduce occasional errors.\n", + "\n", + "
\n", + "\n", + "What is one practical difference between simulators and real quantum computers besides noise?\n", + "\n", + "
\n", + "Answer\n", + "\n", + "Quantum computers can involve queue time, limited availability, and device-specific constraints that affect how circuits run.\n", + "\n", + "
\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" + ] + } + ], + "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 +} diff --git a/IBM-Course/README.md b/IBM-Course/README.md new file mode 100644 index 0000000..2fd2aa7 --- /dev/null +++ b/IBM-Course/README.md @@ -0,0 +1,31 @@ +# IBM Quantum: Use a Quantum Computer Today + +qBraid Lab versions of the four lessons in IBM Quantum Learning's +[*Use a Quantum Computer Today*](https://quantum.cloud.ibm.com/learning/courses/use-a-qc-today) +course by Olivia Lanes. + +| # | Notebook | Video | +|---|---|---| +| 1 | [Quantum Computing Context](01-quantum-computing-context.ipynb) | [youtu.be/y_1SiE1tlTk](https://youtu.be/y_1SiE1tlTk) | +| 2 | [Quantum Mechanics Basics](02-quantum-mechanics-basics.ipynb) | [youtu.be/lKFElrwEZrU](https://youtu.be/lKFElrwEZrU) | +| 3 | [Your First Quantum Experiment](03-your-first-quantum-experiment.ipynb) | [youtu.be/kniiVC538nY](https://youtu.be/kniiVC538nY) | +| 4 | [Build and Run Your First Quantum Program](04-build-and-run-your-first-quantum-program.ipynb) | [youtu.be/vSFv_i_FAXg](https://youtu.be/vSFv_i_FAXg) | + +## What's different from the upstream IBM notebooks + +These are adapted for the qBraid Lab environment. The lesson content is +unchanged, but the setup boilerplate is gone: + +- **No `pip install`** — the qBraid Lab Python 3 kernel ships with + `qiskit`, `qiskit-ibm-runtime`, `qiskit-aer`, and `matplotlib`. +- **No `QiskitRuntimeService.save_account(...)`** — if you've connected + your IBM Quantum account in **Lab → Vault → IBM Quantum**, the bare + `QiskitRuntimeService()` constructor picks up your token automatically. +- **MDX → markdown** — IBM's custom ``, ``, and + `` tags are converted to plain markdown that Jupyter can render. + +## Attribution + +Lesson text and code excerpts © IBM Corp., 2017-2026, reproduced with light +edits as outlined above. Originals at +[quantum.cloud.ibm.com/learning/courses/use-a-qc-today](https://quantum.cloud.ibm.com/learning/courses/use-a-qc-today). From 8a0ac1570082ce0d7da55fd88fd179c487568381 Mon Sep 17 00:00:00 2001 From: Kanav Setia Date: Sun, 17 May 2026 17:53:55 -0500 Subject: [PATCH 2/2] Swap lessons 1 and 4 to match IBM's official ordering IBM Quantum Learning's "Use a Quantum Computer Today" course lists "Build and run your first quantum program" as Lesson 1 (hands-on first, context after), with "Quantum computing context" as Lesson 4. The initial commit had them flipped. Co-Authored-By: Claude Opus 4.7 (1M context) --- ... => 01-build-and-run-your-first-quantum-program.ipynb} | 0 ...g-context.ipynb => 04-quantum-computing-context.ipynb} | 0 IBM-Course/README.md | 8 ++++++-- 3 files changed, 6 insertions(+), 2 deletions(-) rename IBM-Course/{04-build-and-run-your-first-quantum-program.ipynb => 01-build-and-run-your-first-quantum-program.ipynb} (100%) rename IBM-Course/{01-quantum-computing-context.ipynb => 04-quantum-computing-context.ipynb} (100%) diff --git a/IBM-Course/04-build-and-run-your-first-quantum-program.ipynb b/IBM-Course/01-build-and-run-your-first-quantum-program.ipynb similarity index 100% rename from IBM-Course/04-build-and-run-your-first-quantum-program.ipynb rename to IBM-Course/01-build-and-run-your-first-quantum-program.ipynb diff --git a/IBM-Course/01-quantum-computing-context.ipynb b/IBM-Course/04-quantum-computing-context.ipynb similarity index 100% rename from IBM-Course/01-quantum-computing-context.ipynb rename to IBM-Course/04-quantum-computing-context.ipynb diff --git a/IBM-Course/README.md b/IBM-Course/README.md index 2fd2aa7..652d0ba 100644 --- a/IBM-Course/README.md +++ b/IBM-Course/README.md @@ -4,12 +4,16 @@ qBraid Lab versions of the four lessons in IBM Quantum Learning's [*Use a Quantum Computer Today*](https://quantum.cloud.ibm.com/learning/courses/use-a-qc-today) course by Olivia Lanes. +Ordering follows IBM Quantum Learning's official lesson sequence — start +with the hands-on Hello-World lesson, build up the physics in lessons 2 +and 3, and round it off with the conceptual context in lesson 4. + | # | Notebook | Video | |---|---|---| -| 1 | [Quantum Computing Context](01-quantum-computing-context.ipynb) | [youtu.be/y_1SiE1tlTk](https://youtu.be/y_1SiE1tlTk) | +| 1 | [Build and Run Your First Quantum Program](01-build-and-run-your-first-quantum-program.ipynb) | [youtu.be/vSFv_i_FAXg](https://youtu.be/vSFv_i_FAXg) | | 2 | [Quantum Mechanics Basics](02-quantum-mechanics-basics.ipynb) | [youtu.be/lKFElrwEZrU](https://youtu.be/lKFElrwEZrU) | | 3 | [Your First Quantum Experiment](03-your-first-quantum-experiment.ipynb) | [youtu.be/kniiVC538nY](https://youtu.be/kniiVC538nY) | -| 4 | [Build and Run Your First Quantum Program](04-build-and-run-your-first-quantum-program.ipynb) | [youtu.be/vSFv_i_FAXg](https://youtu.be/vSFv_i_FAXg) | +| 4 | [Quantum Computing Context](04-quantum-computing-context.ipynb) | [youtu.be/y_1SiE1tlTk](https://youtu.be/y_1SiE1tlTk) | ## What's different from the upstream IBM notebooks