{ "cells": [ { "cell_type": "markdown", "id": "2304a80e", "metadata": {}, "source": [ "# Noise Model and Noisy Simulations" ] }, { "cell_type": "markdown", "id": "aa04be35", "metadata": {}, "source": [ "*What you will learn:*\n", "\n", "- what types of noise may be involved in a neutral atom QPU;\n", "- how they are described in a `NoiseModel`;\n", "- how to make noisy simulations of a `Sequence` on an emulator `Backend`." ] }, { "cell_type": "markdown", "id": "c8f9d707", "metadata": {}, "source": [ "## Describing noise in neutral-atom QPUs with a NoiseModel" ] }, { "cell_type": "markdown", "id": "d09d1de9", "metadata": {}, "source": [ "Neutral atom QPUs are subject to noise that is going to make the outcome of the execution of your pulser `Sequence` on QPUs different from their theoretical result. The `NoiseModel` class describes the different types of noise to take into account in a neutral-atom QPU. It takes as input parameters that characterize each of these noise types." ] }, { "cell_type": "raw", "id": "ab606b0e", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [], "vscode": { "languageId": "raw" } }, "source": [ ".. autoclass:: pulser.noise_model.NoiseModel\n", " :noindex:" ] }, { "cell_type": "markdown", "id": "725df1eb", "metadata": {}, "source": [ "If you have a `NoiseModel`, you can know the types of noise that it implements checking its property `noise_types`." ] }, { "cell_type": "markdown", "id": "48a43538", "metadata": {}, "source": [ "## How to include noise in your simulations" ] }, { "cell_type": "markdown", "id": "7eae260a", "metadata": {}, "source": [ "When designing your Pulser `Sequence`, taking into account the effects of noise in your simulations is important so that the outcome of the experiment on the QPU is close to what you expect. Here is a step-by-step guide on how to run noisy simulations using Pulser. It extends the [step-by-step guide](./tutorials/backends.nblink) on executing a Pulser `Sequence` on Pulser `Backends`." ] }, { "cell_type": "markdown", "id": "0e52debd", "metadata": {}, "source": [ "### 1. Choosing the type of backend" ] }, { "cell_type": "markdown", "id": "0686bbb7", "metadata": {}, "source": [ "Simulations are performed with an **Emulator Backend**, which can be **local or remote**.\n", "\n", "#### Preparation for noisy simulations:\n", "\n", "Noise parameters are specific to each QPU. To access a particular QPU's specs you'll need a **remote connection** (like [PasqalCloud](./apidoc/_autosummary/pulser_pasqal.PasqalCloud.rst#pulser_pasqal.PasqalCloud)). With it, you can obtain the list of available QPUs through `connection.fetch_available_devices()`. Through this method, you can get the `Device` associated with the QPU. The [Device](./hardware.ipynb) optionally stores a `NoiseModel` in its `noise_model` attribute. When present, you can take into account the specified noise parameters during the design of your sequence." ] }, { "cell_type": "markdown", "id": "4428b694", "metadata": {}, "source": [ "### 2. Creating the pulse Sequence" ] }, { "cell_type": "markdown", "id": "5ff6bdf0", "metadata": {}, "source": [ "The next step is to create the sequence that we want to execute. If you want to take into account all the limitations of the QPU, it is best to use the `Device` associated with the QPU when writing your `Sequence`." ] }, { "cell_type": "markdown", "id": "2dbd38cc", "metadata": {}, "source": [ "### 3. Starting the Backend" ] }, { "cell_type": "markdown", "id": "ddea348f", "metadata": {}, "source": [ "An Emulator Backend takes as input:\n", "- the `Sequence` to simulate, as all the backends.\n", "- a `RemoteConnection` if the emulation backend is a remote backend.\n", "- an `EmulatorConfig`, that sets the parameters of the emulation. This field is optional, emulator backends have a default config.\n", "- a boolean value for `mimic_qpu`, telling whether or not the same tests as when executing a Sequence on a `QPUBackend` should be enforced.\n", "\n", "The `EmulatorConfig` contains two parameters that configure the noise in the simulation:\n", "- `prefer_device_noise_model`: Whether or not to use the noise model of the device of the Sequence. By default, it is False. If you defined your Sequence using the Device of a QPU, set this parameter to True to automatically use the noise model of the chosen QPU.\n", "- `noise_model`: A specific `NoiseModel` defining the noise to include in the simulation, in case `prefer_device_noise_model` is False or the sequence's device does not define a noise model. By default, this `NoiseModel` does not include any noise. If you want to use a different `NoiseModel` for your simulation than the `NoiseModel` of your Sequence's Device, you can provide it here. Possible usecases: \n", " - You have used a [VirtualDevice](./tutorials/virtual_devices.nblink) for your Sequence, and now want to include noise.\n", " - You would like to see how the noise of another QPU would impact your Sequence.\n", " - You would like to see the influence of a certain noise on the execution of your Sequence. NoiseModels are python `dataclasses`, you can modify them with `dataclasses.replace`. For instance, to delete a certain noise parameter \"attr\", you can do `dataclasses.replace(noise_model, attr=None)`." ] }, { "cell_type": "markdown", "id": "42e8b183", "metadata": {}, "source": [ "### 4. Execution\n", "\n", "The execution is always done via the `run` method. It returns a `Results` object that stores the state of the system at each evaluation time. In classical simulation, and under certain kinds of noise, this state is a state-vector.\n", "\n", "However, some noises are stochastic: states are stored as density matrices, computed by averaging over the outcomes of multiple simulations. The number of simulations is determined by `NoiseModel.runs`.\n" ] }, { "cell_type": "markdown", "id": "06c55074", "metadata": {}, "source": [ "### 5. Retrieving the Results" ] }, { "cell_type": "markdown", "id": "dce721f0", "metadata": {}, "source": [ "The returned results are `Results` objects that you can use to get the evolution of some `Observable` at each evaluation times (just like [in noiseless simulation](./tutorials/backends.nblink#5.-Retrieving-the-Results))." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }