{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "fd07a3db-1aa2-4884-98db-6f68765c3edc",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Criar modelos de ruído\"\n",
        "description: \"Aprenda a criar modelos de ruído para o gerenciamento de erros.\"\n",
        "---\n",
        "\n",
        "<span id=\"build-noise-models\" />\n",
        "\n",
        "# Criar modelos de ruído\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "35e9a88b-6872-42b0-ac4f-36bf8898f2fa",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Versões do pacote\">\n",
        "    O código desta página foi desenvolvido usando os seguintes requisitos.\n",
        "    Recomendamos o uso dessas versões ou de versões mais recentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.0\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    qiskit-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "19c35f2c-437a-48b7-8c9f-9ac3526811a7",
      "metadata": {},
      "source": [
        "Esta página mostra como usar o módulo Qiskit Aer [`noise`](https://qiskit.org/ecosystem/aer/apidocs/aer_noise.html) para criar modelos de ruído para simular circuitos quânticos na presença de erros. Isso é útil para emular processadores quânticos com ruído e para estudar os efeitos do ruído na execução de algoritmos quânticos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "85a94e7b-6b43-4a4a-a3b6-a412e1d66c7d",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.403378Z",
          "start_time": "2019-08-19T17:00:41.139269Z"
        }
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit.quantum_info import Kraus, SuperOp\n",
        "from qiskit.visualization import plot_histogram\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_aer import AerSimulator\n",
        "\n",
        "# Import from Qiskit Aer noise module\n",
        "from qiskit_aer.noise import (\n",
        "    NoiseModel,\n",
        "    QuantumError,\n",
        "    ReadoutError,\n",
        "    depolarizing_error,\n",
        "    pauli_error,\n",
        "    thermal_relaxation_error,\n",
        ")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "da49be49-d174-413c-b05d-20236817aac2",
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      },
      "source": [
        "<span id=\"qiskit-aer-noise-module\" />\n",
        "\n",
        "## Módulo `noise` Qiskit Aer\n",
        "\n",
        "O módulo Qiskit Aer `noise` contém classes Python para criar modelos de ruído personalizados para simulação. Há três classes principais:\n",
        "\n",
        "1. A classe `NoiseModel` que armazena um modelo de ruído usado para simulação com ruído.\n",
        "\n",
        "2. A classe `QuantumError` que descreve os erros de porta do CPTP. Eles podem ser aplicados:\n",
        "   * Após o *portão* ou instruções *de reinicialização*\n",
        "   * Instruções antes da *medição*.\n",
        "\n",
        "3. A classe `ReadoutError` que descreve os erros clássicos de leitura.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ea2762d5-7260-4ce9-9e44-2950331ba3e7",
      "metadata": {},
      "source": [
        "<span id=\"initialize-a-noise-model-from-a-backend\" />\n",
        "\n",
        "## Inicializar um modelo de ruído a partir de um backend\n",
        "\n",
        "É possível inicializar um modelo de ruído com parâmetros definidos a partir dos dados de calibração mais recentes de um backend físico.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Nestes exemplos, é utilizado o backend `FakeSherbrooke``qiskit_ibm_runtime` simulado do, mas você pode testá-lo em qualquer backend real ou simulado compatível com o Qiskit.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "b47efd06-6a64-455a-be12-07054e800a34",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "noise_model = NoiseModel.from_backend(backend)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "54f7cb42-dd95-4089-afbb-db9e83d41b50",
      "metadata": {},
      "source": [
        "Isso produzirá um modelo de ruído que se aproxima aproximadamente dos erros que seriam encontrados ao usar esse backend. Se quiser ter um controle mais detalhado sobre os parâmetros do modelo de ruído, será necessário criar seu próprio modelo de ruído, conforme descrito no restante desta página.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "a4940a81-d6ab-4f15-8505-05282c67d823",
      "metadata": {},
      "source": [
        "<span id=\"quantum-errors\" />\n",
        "\n",
        "## Erros quânticos\n",
        "\n",
        "Em vez de lidar diretamente com o `QuantumError` objeto, existem muitas funções auxiliares para gerar automaticamente um tipo específico de erro quântico parametrizado. Elas estão contidas no `noise` módulo e incluem funções para muitos tipos de erros comuns usados na pesquisa em computação quântica. Os nomes das funções e o tipo de erro que elas retornam são:\n",
        "\n",
        "| Função de erro padrão           | Detalhes                                                                                                                                                                                                                                                       |\n",
        "| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n",
        "| `kraus_error`                   | um canal de erro CPTP geral de n qubits dado como uma lista de matrizes Kraus $[K_0, ...]$.                                                                                                                                                                    |\n",
        "| `mixed_unitary_error`           | um erro unitário misto de n-qubit dado como uma lista de matrizes unitárias e probabilidades $[(U_0, p_0),...]$.                                                                                                                                               |\n",
        "| `coherent_unitary_error`        | um erro unitário coerente de n qubits dado como uma única matriz unitária $U$.                                                                                                                                                                                 |\n",
        "| `pauli_error`                   | um canal de erro Pauli de n-qubit (unitário misto) fornecido como uma lista de Pauli's e probabilidades $[(P_0, p_0),...]$                                                                                                                                     |\n",
        "| `depolarizing_error`            | um canal de erro de despolarização de n-qubit parametrizado por uma probabilidade de despolarização $p$.                                                                                                                                                       |\n",
        "| `reset_error`                   | um erro de reinicialização de um único qubit parametrizado pelas probabilidades $p_0, p_1$ de reinicialização para o estado $\\vert0\\rangle$ $\\vert1\\rangle$.                                                                                                   |\n",
        "| `thermal_relaxation_error`      | um canal de relaxamento térmico de um único qubit parametrizado por constantes de tempo de relaxamento $T_1$, $T_2$, tempo de porta $t$ e população térmica de estado excitado $p_1$.                                                                          |\n",
        "| `phase_amplitude_damping_error` | Um canal de erro de amortecimento de amplitude e fase combinada generalizada de um único qubit dado por um parâmetro de amortecimento de amplitude $\\lambda$, um parâmetro de amortecimento de fase $\\gamma$ e uma população térmica de estado excitado $p_1$. |\n",
        "| `amplitude_damping_error`       | Um canal de erro de amortecimento de amplitude generalizado de um único qubit dado por um parâmetro de amortecimento de amplitude $\\lambda$ e uma população térmica de estado excitado $p_1$.                                                                  |\n",
        "| `phase_damping_error`           | Um canal de erro de amortecimento de fase de um único qubit dado por um parâmetro de amortecimento $\\gamma$ de fase.                                                                                                                                           |\n",
        "\n",
        "<span id=\"combine-quantum-errors\" />\n",
        "\n",
        "### Combinar erros quânticos\n",
        "\n",
        "`QuantumError` as instâncias podem ser combinadas usando composição, produto tensorial e expansão tensorial (produto tensorial de ordem inversa) para produzir novos `QuantumErrors` como:\n",
        "\n",
        "* Composição: $\\cal{E}(\\rho)=\\cal{E_2}(\\cal{E_1}(\\rho))$ como `error = error1.compose(error2)`\n",
        "* Produto tensorial: $\\cal{E}(\\rho) =(\\cal{E_1}\\otimes\\cal{E_2})(\\rho)$ como `error = error1.tensor(error2)`\n",
        "* Expandir produto: $\\cal{E}(\\rho) =(\\cal{E_2}\\otimes\\cal{E_1})(\\rho)$ como `error = error1.expand(error2)`\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "cd42ec1c-a971-4dd8-913c-2a4fd4f4a845",
      "metadata": {},
      "source": [
        "<span id=\"example\" />\n",
        "\n",
        "### Exemplo\n",
        "\n",
        "Para construir um erro de inversão de bit de 5% em um único qubit:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "437a8576-084c-499f-af7e-12b0a2fbfcd0",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.420358Z",
          "start_time": "2019-08-19T17:00:43.416062Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 0.05, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ X ├\n",
            "   └───┘\n",
            "  P(1) = 0.95, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ I ├\n",
            "   └───┘\n",
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 0.05, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ Z ├\n",
            "   └───┘\n",
            "  P(1) = 0.95, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ I ├\n",
            "   └───┘\n"
          ]
        }
      ],
      "source": [
        "# Construct a 1-qubit bit-flip and phase-flip errors\n",
        "p_error = 0.05\n",
        "bit_flip = pauli_error([(\"X\", p_error), (\"I\", 1 - p_error)])\n",
        "phase_flip = pauli_error([(\"Z\", p_error), (\"I\", 1 - p_error)])\n",
        "print(bit_flip)\n",
        "print(phase_flip)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "d71ef2d9-e386-4649-9e1c-a7bfe7342687",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.435843Z",
          "start_time": "2019-08-19T17:00:43.432211Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 0.0025000000000000005, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ X ├┤ Z ├\n",
            "   └───┘└───┘\n",
            "  P(1) = 0.0475, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ X ├┤ I ├\n",
            "   └───┘└───┘\n",
            "  P(2) = 0.0475, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ I ├┤ Z ├\n",
            "   └───┘└───┘\n",
            "  P(3) = 0.9025, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ I ├┤ I ├\n",
            "   └───┘└───┘\n"
          ]
        }
      ],
      "source": [
        "# Compose two bit-flip and phase-flip errors\n",
        "bitphase_flip = bit_flip.compose(phase_flip)\n",
        "print(bitphase_flip)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "ffa9fd9c-3d98-4285-8daf-ee22ca2b0d55",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.460191Z",
          "start_time": "2019-08-19T17:00:43.456782Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 2 qubits. Noise circuits:\n",
            "  P(0) = 0.0025000000000000005, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ X ├\n",
            "     ├───┤\n",
            "q_1: ┤ Z ├\n",
            "     └───┘\n",
            "  P(1) = 0.0475, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ I ├\n",
            "     ├───┤\n",
            "q_1: ┤ Z ├\n",
            "     └───┘\n",
            "  P(2) = 0.0475, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ X ├\n",
            "     ├───┤\n",
            "q_1: ┤ I ├\n",
            "     └───┘\n",
            "  P(3) = 0.9025, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ I ├\n",
            "     ├───┤\n",
            "q_1: ┤ I ├\n",
            "     └───┘\n"
          ]
        }
      ],
      "source": [
        "# Tensor product two bit-flip and phase-flip errors with\n",
        "# bit-flip on qubit-0, phase-flip on qubit-1\n",
        "error2 = phase_flip.tensor(bit_flip)\n",
        "print(error2)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "80e275c7-b856-4301-9266-0eb7a783e0f8",
      "metadata": {},
      "source": [
        "<span id=\"convert-to-and-from-quantumchannel-operators\" />\n",
        "\n",
        "### Converter de e para operadores do tipo `QuantumChannel`\n",
        "\n",
        "Também podemos converter para frente e para trás entre os objetos `QuantumError` no Qiskit Aer e os objetos `QuantumChannel` no Qiskit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "2006e158-bea6-4e18-a06c-31b567401b6c",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.482424Z",
          "start_time": "2019-08-19T17:00:43.473779Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Kraus([[[-9.74679434e-01+0.j,  0.00000000e+00+0.j],\n",
            "        [ 0.00000000e+00+0.j, -9.74679434e-01+0.j]],\n",
            "\n",
            "       [[ 0.00000000e+00+0.j,  2.23606798e-01+0.j],\n",
            "        [ 2.23606798e-01+0.j, -4.96506831e-17+0.j]]],\n",
            "      input_dims=(2,), output_dims=(2,))\n"
          ]
        }
      ],
      "source": [
        "# Convert to Kraus operator\n",
        "bit_flip_kraus = Kraus(bit_flip)\n",
        "print(bit_flip_kraus)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "425a9b6f-e078-4a48-ab1c-a5621a8b773a",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.509521Z",
          "start_time": "2019-08-19T17:00:43.503976Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "SuperOp([[1. +0.j, 0. +0.j, 0. +0.j, 0. +0.j],\n",
            "         [0. +0.j, 0.9+0.j, 0. +0.j, 0. +0.j],\n",
            "         [0. +0.j, 0. +0.j, 0.9+0.j, 0. +0.j],\n",
            "         [0. +0.j, 0. +0.j, 0. +0.j, 1. +0.j]],\n",
            "        input_dims=(2,), output_dims=(2,))\n"
          ]
        }
      ],
      "source": [
        "# Convert to Superoperator\n",
        "phase_flip_sop = SuperOp(phase_flip)\n",
        "print(phase_flip_sop)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "97624c98-f1c0-4a9b-be5b-2c664d368e9f",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.794037Z",
          "start_time": "2019-08-19T17:00:43.778223Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 1.0, Circuit = \n",
            "   ┌───────┐\n",
            "q: ┤ kraus ├\n",
            "   └───────┘\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Convert back to a quantum error\n",
        "print(QuantumError(bit_flip_kraus))\n",
        "\n",
        "# Check conversion is equivalent to original error\n",
        "QuantumError(bit_flip_kraus) == bit_flip"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "7f663dfe-e238-418c-bff4-c751468a6678",
      "metadata": {},
      "source": [
        "<span id=\"readout-error\" />\n",
        "\n",
        "### Erro de leitura\n",
        "\n",
        "Os erros clássicos de leitura são especificados por uma lista de vetores de probabilidade $P(A|B)$ de atribuição:\n",
        "\n",
        "* $A$ é o valor do bit clássico *registrado*\n",
        "* $B$ é o valor de bit *verdadeiro* retornado da medição\n",
        "\n",
        "Por exemplo, para um qubit: $ P(A|B) = [P(A|0), P(A|1)]$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "f70f39f8-dec5-46cb-a194-4768cffbd6db",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:44.659598Z",
          "start_time": "2019-08-19T17:00:44.654818Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "ReadoutError([[0.95 0.05]\n",
              " [0.1  0.9 ]])"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Measurement misassignment probabilities\n",
        "p0given1 = 0.1\n",
        "p1given0 = 0.05\n",
        "\n",
        "ReadoutError([[1 - p1given0, p1given0], [p0given1, 1 - p0given1]])"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "e77fcdcd-346c-4f78-83eb-0c32359ba62c",
      "metadata": {},
      "source": [
        "Os erros de leitura também podem ser combinados usando `compose`, `tensor` e `expand`, como nos erros quânticos.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "b2258427-2283-435c-b964-60423c3b0f39",
      "metadata": {},
      "source": [
        "<span id=\"add-errors-to-a-noise-model\" />\n",
        "\n",
        "## Adicionar erros a um modelo de ruído\n",
        "\n",
        "Ao adicionar um erro quântico a um modelo de ruído, devemos especificar o tipo de *instrução* em que ele atua e a quais qubits ele deve ser aplicado. Há dois casos de erros quânticos:\n",
        "\n",
        "1. Erro quântico de todos os qubits\n",
        "2. Erro quântico de qubit específico\n",
        "\n",
        "<span id=\"1-all-qubit-quantum-error\" />\n",
        "\n",
        "### 1. Erro quântico em todos os qubits\n",
        "\n",
        "Isso aplica o mesmo erro a qualquer ocorrência de uma instrução, independentemente de em quais qubits ela atua.\n",
        "\n",
        "Ele é adicionado como `noise_model.add_all_qubit_quantum_error(error, instructions)`:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "0a5ae501-87e5-4930-96c1-b0af2d6993ce",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:45.882254Z",
          "start_time": "2019-08-19T17:00:45.877630Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']\n",
            "  Instructions with noise: ['u1', 'u2', 'u3']\n",
            "  All-qubits errors: ['u1', 'u2', 'u3']"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n"
          ]
        }
      ],
      "source": [
        "# Create an empty noise model\n",
        "noise_model = NoiseModel()\n",
        "\n",
        "# Add depolarizing error to all single qubit u1, u2, u3 gates\n",
        "error = depolarizing_error(0.05, 1)\n",
        "noise_model.add_all_qubit_quantum_error(error, [\"u1\", \"u2\", \"u3\"])\n",
        "\n",
        "# Print noise model info\n",
        "print(noise_model)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "f2f360be-5d7b-435d-980a-e20450a0267f",
      "metadata": {},
      "source": [
        "<span id=\"2-specific-qubit-quantum-error\" />\n",
        "\n",
        "### 2. Erro quântico específico do qubit\n",
        "\n",
        "Isso aplica o erro a qualquer ocorrência de uma instrução que atue em uma lista especificada de qubits. Observe que a ordem do qubit é importante: por exemplo, um erro aplicado aos qubits \\[0, 1] para uma porta de dois qubits é diferente de um erro aplicado aos qubits \\[1, 0].\n",
        "\n",
        "Ele é adicionado como `noise_model.add_quantum_error(error, instructions, qubits)`:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "05d7e61f-75dc-488b-bfab-c00ad87fe1ea",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:46.615959Z",
          "start_time": "2019-08-19T17:00:46.612055Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']\n",
            "  Instructions with noise: ['u1', 'u2', 'u3']\n",
            "  Qubits with noise: [0]\n",
            "  Specific qubit errors: [('u1', (0,)), ('u2', (0,)), ('u3', (0,))]\n"
          ]
        }
      ],
      "source": [
        "# Create an empty noise model\n",
        "noise_model = NoiseModel()\n",
        "\n",
        "# Add depolarizing error to all single qubit u1, u2, u3 gates on qubit 0 only\n",
        "error = depolarizing_error(0.05, 1)\n",
        "noise_model.add_quantum_error(error, [\"u1\", \"u2\", \"u3\"], [0])\n",
        "\n",
        "# Print noise model info\n",
        "print(noise_model)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "c2dc1bb3-66a9-4d63-8341-0c4c45ed89d6",
      "metadata": {},
      "source": [
        "<span id=\"note-on-non-local-qubit-quantum-error\" />\n",
        "\n",
        "### Nota sobre erros quânticos em qubits não locais\n",
        "\n",
        "`NoiseModel` não suporta a adição de erros quânticos em qubits não locais. Devem ser tratados fora do `NoiseModel`. Isso sugere que você deve [escrever sua própria etapa de transpilador](/docs/guides/custom-transpiler-pass) (`TransformationPass`) e executá-la imediatamente antes de iniciar o simulador, caso precise inserir seus erros quânticos no circuito de acordo com suas próprias condições.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "2617effb-ae2e-44a3-8a7b-28b68b756ac6",
      "metadata": {},
      "source": [
        "<span id=\"execute-a-noisy-simulation-with-a-noise-model\" />\n",
        "\n",
        "### Execute uma simulação ruidosa com um modelo de ruído\n",
        "\n",
        "O comando `AerSimulator(noise_model=noise_model)` retorna um simulador configurado para o modelo de ruído fornecido. Além de definir o modelo de ruído do simulador, ele também substitui as portas de base do simulador, de acordo com as portas do modelo de ruído.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "7df257fd-424b-486e-a607-7d4c392b4c98",
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      },
      "source": [
        "<span id=\"noise-model-examples\" />\n",
        "\n",
        "## Exemplos de modelos de ruído\n",
        "\n",
        "A seguir, apresentaremos alguns exemplos de modelos de ruído. Para nossas demonstrações, usamos um circuito de teste simples que gera um estado GHZ de n qubits:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "43df6b1f-b07a-4bf2-bba6-c7ec35eec620",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:48.817405Z",
          "start_time": "2019-08-19T17:00:48.806966Z"
        },
        "slideshow": {
          "slide_type": "fragment"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "        ┌───┐                ░ ┌─┐         \n",
            "   q_0: ┤ H ├──■─────────────░─┤M├─────────\n",
            "        └───┘┌─┴─┐           ░ └╥┘┌─┐      \n",
            "   q_1: ─────┤ X ├──■────────░──╫─┤M├──────\n",
            "             └───┘┌─┴─┐      ░  ║ └╥┘┌─┐   \n",
            "   q_2: ──────────┤ X ├──■───░──╫──╫─┤M├───\n",
            "                  └───┘┌─┴─┐ ░  ║  ║ └╥┘┌─┐\n",
            "   q_3: ───────────────┤ X ├─░──╫──╫──╫─┤M├\n",
            "                       └───┘ ░  ║  ║  ║ └╥┘\n",
            "meas: 4/════════════════════════╩══╩══╩══╩═\n",
            "                                0  1  2  3 "
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n"
          ]
        }
      ],
      "source": [
        "# System Specification\n",
        "n_qubits = 4\n",
        "circ = QuantumCircuit(n_qubits)\n",
        "\n",
        "# Test Circuit\n",
        "circ.h(0)\n",
        "for qubit in range(n_qubits - 1):\n",
        "    circ.cx(qubit, qubit + 1)\n",
        "circ.measure_all()\n",
        "print(circ)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "eea319ec-8764-4d77-8863-c5a2e9ae370a",
      "metadata": {},
      "source": [
        "<span id=\"ideal-simulation\" />\n",
        "\n",
        "### Simulação ideal\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "bc713d11-755e-41e4-94f0-1ed76e3c2469",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:50.560988Z",
          "start_time": "2019-08-19T17:00:50.415545Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/build-noise-models/extracted-outputs/bc713d11-755e-41e4-94f0-1ed76e3c2469-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Ideal simulator and execution\n",
        "sim_ideal = AerSimulator()\n",
        "result_ideal = sim_ideal.run(circ).result()\n",
        "plot_histogram(result_ideal.get_counts(0))"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "ac7111a6-04dc-4068-9044-54d93e745116",
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      },
      "source": [
        "<span id=\"noise-example-1-basic-bit-flip-error-noise-model\" />\n",
        "\n",
        "## Exemplo de ruído 1: Modelo básico de ruído de erro de inversão de bits\n",
        "\n",
        "Vamos considerar um exemplo simples de modelo de ruído de brinquedo comum na pesquisa da teoria da informação quântica:\n",
        "\n",
        "* Ao aplicar uma porta de um único qubit, inverta o estado do qubit com probabilidade `p_gate1`.\n",
        "* Ao aplicar uma porta de dois qubits, aplique erros de um qubit a cada qubit.\n",
        "* Ao redefinir um qubit, redefina para 1 em vez de 0 com probabilidade `p_reset`.\n",
        "* Ao medir um qubit, inverta o estado do qubit com probabilidade `p_meas`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "fee3c383-0499-4d1f-be9f-32b41a31f561",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:51.543615Z",
          "start_time": "2019-08-19T17:00:51.536564Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']\n",
            "  Instructions with noise: ['u2', 'u1', 'measure', 'cx', 'u3', 'reset']\n",
            "  All-qubits errors: ['reset', 'measure', 'u1', 'u2', 'u3', 'cx']\n"
          ]
        }
      ],
      "source": [
        "# Example error probabilities\n",
        "p_reset = 0.03\n",
        "p_meas = 0.1\n",
        "p_gate1 = 0.05\n",
        "\n",
        "# QuantumError objects\n",
        "error_reset = pauli_error([(\"X\", p_reset), (\"I\", 1 - p_reset)])\n",
        "error_meas = pauli_error([(\"X\", p_meas), (\"I\", 1 - p_meas)])\n",
        "error_gate1 = pauli_error([(\"X\", p_gate1), (\"I\", 1 - p_gate1)])\n",
        "error_gate2 = error_gate1.tensor(error_gate1)\n",
        "\n",
        "# Add errors to noise model\n",
        "noise_bit_flip = NoiseModel()\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_reset, \"reset\")\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_meas, \"measure\")\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_gate1, [\"u1\", \"u2\", \"u3\"])\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_gate2, [\"cx\"])\n",
        "\n",
        "print(noise_bit_flip)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "dbf3f5ee-0f66-4a37-b512-038a21ce2ed2",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-noisy-simulation\" />\n",
        "\n",
        "### Execute a simulação ruidosa\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "abeb9f09-d762-406d-983e-0357ade59636",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:52.951874Z",
          "start_time": "2019-08-19T17:00:52.687440Z"
        },
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/build-noise-models/extracted-outputs/abeb9f09-d762-406d-983e-0357ade59636-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Create noisy simulator backend\n",
        "sim_noise = AerSimulator(noise_model=noise_bit_flip)\n",
        "\n",
        "# Transpile circuit for noisy basis gates\n",
        "passmanager = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=sim_noise\n",
        ")\n",
        "circ_tnoise = passmanager.run(circ)\n",
        "\n",
        "# Run and get counts\n",
        "result_bit_flip = sim_noise.run(circ_tnoise).result()\n",
        "counts_bit_flip = result_bit_flip.get_counts(0)\n",
        "\n",
        "# Plot noisy output\n",
        "plot_histogram(counts_bit_flip)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "ced838fa-105d-4bdf-b240-51b78ff18e29",
      "metadata": {},
      "source": [
        "<span id=\"example-2-t1/t2-thermal-relaxation\" />\n",
        "\n",
        "## Exemplo 2: relaxamento térmico de T1/T2\n",
        "\n",
        "Agora, considere um modelo de erro mais realista baseado no relaxamento térmico com o ambiente do qubit:\n",
        "\n",
        "* Cada qubit é parametrizado por uma constante de tempo de relaxamento térmico $T_1$ e uma constante de tempo de defasagem $T_2$.\n",
        "* Observe que devemos ter $T_2 \\le 2 T_1$.\n",
        "* As taxas de erro nas instruções são determinadas por tempos de porta e valores de qubit $T_1$, $T_2$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "b2ab3829-98fa-4b5d-b622-25c155abfdf0",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:54.577456Z",
          "start_time": "2019-08-19T17:00:54.491018Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u2', 'u3']\n",
            "  Instructions with noise: ['u2', 'measure', 'cx', 'u3', 'reset']\n",
            "  Qubits with noise: [0, 1, 2, 3]\n",
            "  Specific qubit errors: [('reset', (0,)), ('reset', (1,)), ('reset', (2,)), ('reset', (3,)), ('measure', (0,)), ('measure', (1,)), ('measure', (2,)), ('measure', (3,)), ('u2', (0,)), ('u2', (1,)), ('u2', (2,)), ('u2', (3,)), ('u3', (0,)), ('u3', (1,)), ('u3', (2,)), ('u3', (3,)), ('cx', (0, 0)), ('cx', (0, 1)), ('cx', (0, 2)), ('cx', (0, 3)), ('cx', (1, 0)), ('cx', (1, 1)), ('cx', (1, 2)), ('cx', (1, 3)), ('cx', (2, 0)), ('cx', (2, 1)), ('cx', (2, 2)), ('cx', (2, 3)), ('cx', (3, 0)), ('cx', (3, 1)), ('cx', (3, 2)), ('cx', (3, 3))]\n"
          ]
        }
      ],
      "source": [
        "# T1 and T2 values for qubits 0-3\n",
        "T1s = np.random.normal(\n",
        "    50e3, 10e3, 4\n",
        ")  # Sampled from normal distribution mean 50 microsec\n",
        "T2s = np.random.normal(\n",
        "    70e3, 10e3, 4\n",
        ")  # Sampled from normal distribution mean 50 microsec\n",
        "\n",
        "# Truncate random T2s <= T1s\n",
        "T2s = np.array([min(T2s[j], 2 * T1s[j]) for j in range(4)])\n",
        "\n",
        "# Instruction times (in nanoseconds)\n",
        "time_u1 = 0  # virtual gate\n",
        "time_u2 = 50  # (single X90 pulse)\n",
        "time_u3 = 100  # (two X90 pulses)\n",
        "time_cx = 300\n",
        "time_reset = 1000  # 1 microsecond\n",
        "time_measure = 1000  # 1 microsecond\n",
        "\n",
        "# QuantumError objects\n",
        "errors_reset = [\n",
        "    thermal_relaxation_error(t1, t2, time_reset) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_measure = [\n",
        "    thermal_relaxation_error(t1, t2, time_measure) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_u1 = [\n",
        "    thermal_relaxation_error(t1, t2, time_u1) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_u2 = [\n",
        "    thermal_relaxation_error(t1, t2, time_u2) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_u3 = [\n",
        "    thermal_relaxation_error(t1, t2, time_u3) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_cx = [\n",
        "    [\n",
        "        thermal_relaxation_error(t1a, t2a, time_cx).expand(\n",
        "            thermal_relaxation_error(t1b, t2b, time_cx)\n",
        "        )\n",
        "        for t1a, t2a in zip(T1s, T2s)\n",
        "    ]\n",
        "    for t1b, t2b in zip(T1s, T2s)\n",
        "]\n",
        "\n",
        "# Add errors to noise model\n",
        "noise_thermal = NoiseModel()\n",
        "for j in range(4):\n",
        "    noise_thermal.add_quantum_error(errors_reset[j], \"reset\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_measure[j], \"measure\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_u1[j], \"u1\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_u2[j], \"u2\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_u3[j], \"u3\", [j])\n",
        "    for k in range(4):\n",
        "        noise_thermal.add_quantum_error(errors_cx[j][k], \"cx\", [j, k])\n",
        "\n",
        "print(noise_thermal)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "a3dd27c5-c032-44b9-ada9-19280e8a0140",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-noisy-simulation\" />\n",
        "\n",
        "### Execute a simulação ruidosa\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "ff52bf52-1323-40fc-a631-2b1889b21b20",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:55.689241Z",
          "start_time": "2019-08-19T17:00:55.515394Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/build-noise-models/extracted-outputs/ff52bf52-1323-40fc-a631-2b1889b21b20-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 17,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Run the noisy simulation\n",
        "sim_thermal = AerSimulator(noise_model=noise_thermal)\n",
        "\n",
        "# Transpile circuit for noisy basis gates\n",
        "passmanager = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=sim_thermal\n",
        ")\n",
        "circ_tthermal = passmanager.run(circ)\n",
        "\n",
        "# Run and get counts\n",
        "result_thermal = sim_thermal.run(circ_tthermal).result()\n",
        "counts_thermal = result_thermal.get_counts(0)\n",
        "\n",
        "# Plot noisy output\n",
        "plot_histogram(counts_thermal)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0df436e1-b43c-41b1-9581-a4d530e51a7b",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Para simular circuitos com ruído, consulte [Simulação exata e com ruído usando primitivas do Qiskit Aer](/docs/guides/simulate-with-qiskit-sdk-primitives).\n",
        "  * Revise a referência [do módulo de ruído Qiskit Aer](https://qiskit.org/ecosystem/aer/apidocs/aer_noise.html).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}