{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "e6d26387-f218-4f62-80c4-792103129b99",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Simulação eficiente de circuitos estabilizadores com primitivas Qiskit Aer\"\n",
        "description: \"Como simular circuitos estabilizadores de forma eficiente usando primitivas Qiskit Aer.\"\n",
        "---\n",
        "\n",
        "<span id=\"efficient-simulation-of-stabilizer-circuits-with-qiskit-aer-primitives\" />\n",
        "\n",
        "# Simulação eficiente de circuitos estabilizadores com primitivas Qiskit Aer\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f1bcbbdb-965d-41f0-88dd-bb42834b35b9",
      "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-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "386709ed-183b-4759-bb1b-56cdedf80539",
      "metadata": {},
      "source": [
        "Esta página mostra como usar as primitivas do Qiskit Aer para simular com eficiência os circuitos estabilizadores, inclusive aqueles sujeitos ao ruído Pauli.\n",
        "\n",
        "Os circuitos estabilizadores, também conhecidos como circuitos de Clifford, são uma importante classe restrita de circuitos quânticos que podem ser simulados classicamente de forma eficiente. Há várias maneiras equivalentes de definir circuitos estabilizadores. Uma definição é que um circuito estabilizador é um circuito quântico que consiste apenas nas seguintes portas:\n",
        "\n",
        "* [CX](../api/qiskit/qiskit.circuit.library.CXGate)\n",
        "* [Hadamard](../api/qiskit/qiskit.circuit.library.HGate)\n",
        "* [S](../api/qiskit/qiskit.circuit.library.SGate)\n",
        "* [Medição](../api/qiskit/circuit#qiskit.circuit.Measure)\n",
        "\n",
        "Observe que, usando Hadamard e S, podemos construir qualquer porta de rotação Pauli ( [$R_x$](/docs/api/qiskit/qiskit.circuit.library.RXGate), [$R_y$](/docs/api/qiskit/qiskit.circuit.library.RYGate), e [$R_z$](/docs/api/qiskit/qiskit.circuit.library.RZGate) ) que tenha um ângulo contido no conjunto $\\{0, \\frac{\\pi}{2}, \\pi, \\frac{3\\pi}{2}\\}$ (até a fase global), portanto, também podemos incluir essas portas na definição.\n",
        "\n",
        "Os circuitos estabilizadores são importantes para o estudo da correção de erros quânticos. Sua capacidade de simulação clássica também os torna úteis para verificar a saída de computadores quânticos. Por exemplo, suponha que você queira executar um circuito quântico que usa 100 qubits em um computador quântico. Como você sabe que o computador quântico está se comportando corretamente? Um circuito quântico de 100 qubits está além do alcance da simulação clássica de força bruta. Ao modificar seu circuito para que ele se torne um circuito estabilizador, é possível executar circuitos no computador quântico que tenham uma estrutura semelhante à do circuito desejado, mas que possam ser simulados em um computador clássico. Ao verificar a saída do computador quântico nos circuitos estabilizadores, você pode ter certeza de que ele está se comportando corretamente também nos circuitos não estabilizadores. Consulte [*Evidência da utilidade da computação quântica antes da tolerância a falhas*](https://www.nature.com/articles/s41586-023-06096-3) para obter um exemplo dessa ideia na prática.\n",
        "\n",
        "[A simulação exata e com ruído com primitivos do Qiskit Aer](simulate-with-qiskit-aer) mostra como usar o [Qiskit Aer](https://qiskit.org/ecosystem/aer/) para realizar simulações exatas e com ruído de circuitos quânticos genéricos. Considere o circuito de exemplo usado nesse artigo, um circuito de 8 qubits construído usando [efficient\\_su2](../api/qiskit/qiskit.circuit.library.efficient_su2) :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "2d26ac3e-2a6a-4d73-900f-470200a63154",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/simulate-stabilizer-circuits/extracted-outputs/2d26ac3e-2a6a-4d73-900f-470200a63154-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "n_qubits = 8\n",
        "circuit = efficient_su2(n_qubits)\n",
        "circuit.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9f72e683-a828-456d-a5d4-910758cc9add",
      "metadata": {},
      "source": [
        "Usando o Qiskit Aer, conseguimos simular esse circuito com facilidade. No entanto, suponha que definimos o número de qubits como 500:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "43c8277f-3f0d-4d31-a1c2-e4c541083f5d",
      "metadata": {},
      "outputs": [],
      "source": [
        "n_qubits = 500\n",
        "circuit = efficient_su2(n_qubits)\n",
        "# don't try to draw the circuit because it's too large"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ecd975b0-2ec0-4a99-a0f6-790d43af19fb",
      "metadata": {},
      "source": [
        "Como o custo da simulação de circuitos quânticos aumenta exponencialmente com o número de qubits, um circuito tão grande geralmente excede os recursos até mesmo de um simulador de alto desempenho como o Qiskit Aer. A simulação clássica de circuitos quânticos genéricos torna-se inviável quando o número de qubits excede aproximadamente 50 a 100 qubits. Entretanto, observe que o circuito efficient\\_su2 é parametrizado por ângulos nos portões $R_y$ e $R_z$. Se todos esses ângulos estiverem contidos no conjunto $\\{0, \\frac{\\pi}{2}, \\pi, \\frac{3\\pi}{2}\\}$, então o circuito é um circuito estabilizador e pode ser simulado com eficiência!\n",
        "\n",
        "Na célula a seguir, executamos o circuito com o primitivo Sampler apoiado pelo simulador de circuito estabilizador, usando parâmetros escolhidos aleatoriamente, de modo que o circuito seja garantidamente um circuito estabilizador.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "2210bbe3-1a89-48fe-a4ea-f3c9b1cd37d0",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_aer import AerSimulator\n",
        "from qiskit_aer.primitives import SamplerV2 as Sampler\n",
        "\n",
        "measured_circuit = circuit.copy()\n",
        "measured_circuit.measure_all()\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "params = rng.choice(\n",
        "    [0, np.pi / 2, np.pi, 3 * np.pi / 2],\n",
        "    size=circuit.num_parameters,\n",
        ")\n",
        "\n",
        "# Initialize a Sampler backed by the stabilizer circuit simulator\n",
        "exact_sampler = Sampler(\n",
        "    options=dict(backend_options=dict(method=\"stabilizer\"))\n",
        ")\n",
        "# The circuit needs to be transpiled to the AerSimulator target\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    1, AerSimulator(method=\"stabilizer\")\n",
        ")\n",
        "isa_circuit = pass_manager.run(measured_circuit)\n",
        "pub = (isa_circuit, params)\n",
        "job = exact_sampler.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "counts = pub_result.data.meas.get_counts()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "445694b0-3e5b-4fc2-a610-f86674065045",
      "metadata": {},
      "source": [
        "O simulador de circuito estabilizador também suporta simulação com ruído, mas somente para uma classe restrita de modelos de ruído. Especificamente, qualquer ruído quântico deve ser caracterizado por um canal [de erro Pauli](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.pauli_error.html#qiskit_aer.noise.pauli_error). [O erro de despolarização](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.depolarizing_error.html) se enquadra nessa categoria, portanto, também pode ser simulado. Os canais de ruído clássicos, como o [erro de leitura,](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.ReadoutError.html) também podem ser simulados.\n",
        "\n",
        "A célula de código a seguir executa a mesma simulação anterior, mas, desta vez, especificando um modelo de ruído que adiciona um erro de despolarização de 2% a cada porta CX, bem como um erro de leitura que inverte cada bit medido com 5% de probabilidade.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "71dd8d78-6efd-4c4e-900a-1d73deafe46e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_aer.noise import NoiseModel, depolarizing_error, ReadoutError\n",
        "\n",
        "noise_model = NoiseModel()\n",
        "cx_depolarizing_prob = 0.02\n",
        "bit_flip_prob = 0.05\n",
        "noise_model.add_all_qubit_quantum_error(\n",
        "    depolarizing_error(cx_depolarizing_prob, 2), [\"cx\"]\n",
        ")\n",
        "noise_model.add_all_qubit_readout_error(\n",
        "    ReadoutError(\n",
        "        [\n",
        "            [1 - bit_flip_prob, bit_flip_prob],\n",
        "            [bit_flip_prob, 1 - bit_flip_prob],\n",
        "        ]\n",
        "    )\n",
        ")\n",
        "\n",
        "noisy_sampler = Sampler(\n",
        "    options=dict(\n",
        "        backend_options=dict(method=\"stabilizer\", noise_model=noise_model)\n",
        "    )\n",
        ")\n",
        "job = noisy_sampler.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "counts = pub_result.data.meas.get_counts()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "01b3e796-bd06-419f-a2fc-55c8603f662f",
      "metadata": {},
      "source": [
        "Agora, vamos usar a primitiva Estimator com o apoio do simulador de estabilizador para calcular o valor esperado do observável $ZZ \\cdots Z$. Devido à estrutura especial dos circuitos estabilizadores, é muito provável que o resultado seja 0.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "57fb0674-5bd2-44b0-a28e-e73deff455cf",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.0"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit_aer.primitives import EstimatorV2 as Estimator\n",
        "\n",
        "observable = SparsePauliOp(\"Z\" * n_qubits)\n",
        "\n",
        "exact_estimator = Estimator(\n",
        "    options=dict(backend_options=dict(method=\"stabilizer\")),\n",
        ")\n",
        "isa_circuit = pass_manager.run(circuit)\n",
        "pub = (isa_circuit, observable, params)\n",
        "job = exact_estimator.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "exact_value = float(pub_result.data.evs)\n",
        "exact_value"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d5e6593-06f0-4e1b-a4f0-7b640a74f6c5",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Para simular circuitos com o Qiskit Aer, consulte [Simulação exata e com ruído usando primitivas do Qiskit Aer](/docs/guides/simulate-with-qiskit-sdk-primitives).\n",
        "  * Examine a documentação [do Qiskit Aer](https://qiskit.org/ecosystem/aer/).\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
}