{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "3a5616bf-6edb-4539-872a-03217649edcb",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Criar um gerenciador de passes para desacoplamento dinâmico\"\n",
        "description: \"Como criar um gerenciador de passagem para desacoplamento dinâmico no Qiskit.\"\n",
        "---\n",
        "\n",
        "<span id=\"create-a-pass-manager-for-dynamical-decoupling\" />\n",
        "\n",
        "# Criar um gerenciador de passes para desacoplamento dinâmico\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5662d8c-46f8-40a8-92b5-af63c32d303f",
      "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",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1ed6dc8d-b6f2-43dc-bb40-ceec0f311764",
      "metadata": {},
      "source": [
        "Esta página demonstra como usar o [`PadDynamicalDecoupling`](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling) para adicionar uma técnica de supressão de erros chamada *desacoplamento dinâmico* ao circuito.\n",
        "\n",
        "O desacoplamento dinâmico funciona adicionando sequências de pulso (conhecidas como *sequências de desacoplamento dinâmico* ) a qubits ociosos para girá-los em torno da esfera de Bloch, o que cancela o efeito dos canais de ruído, suprimindo assim a decoerência. Essas sequências de pulsos são semelhantes aos pulsos de reorientação usados na ressonância magnética nuclear. Para obter uma descrição completa, consulte [A Quantum Engineer's Guide to Superconducting Qubits (Guia do engenheiro quântico para Qubits supercondutores](https://arxiv.org/abs/1904.06560) ).\n",
        "\n",
        "Como a passagem `PadDynamicalDecoupling` opera somente em circuitos programados e envolve portas que não são necessariamente portas de base do nosso alvo, você precisará dos parâmetros [`ALAPScheduleAnalysis`](/docs/api/qiskit/qiskit.transpiler.passes.ALAPScheduleAnalysis) e [`BasisTranslator`](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator) também.\n",
        "\n",
        "Obtenha as `target` informações do `backend` e salve os nomes das operações como, `basis_gates` pois o `target` precisará ser modificado para adicionar informações de temporização para as portas utilizadas no desacoplamento dinâmico.\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.  Seus resultados podem ser diferentes.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "c55c6e3b-4016-4866-b2ec-19793e89d215",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "target = backend.target\n",
        "basis_gates = list(target.operation_names)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b8dfccd9-30c9-48dc-88bc-50af3256f187",
      "metadata": {},
      "source": [
        "Crie um circuito `efficient_su2` como exemplo. Primeiro, transpile o circuito para o backend porque os pulsos de desacoplamento dinâmico precisam ser adicionados depois que o circuito tiver sido transpilado e programado. A dissociação dinâmica geralmente funciona melhor quando há muito tempo ocioso nos circuitos quânticos, ou seja, há qubits que não estão sendo usados enquanto outros estão ativos. Esse é o caso desse circuito porque as portas de dois qubits `ecr` são aplicadas sequencialmente nesse ansatz.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "9479a60c-d5d0-45c7-a93e-a2a488ba8985",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/9479a60c-d5d0-45c7-a93e-a2a488ba8985-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "qc = efficient_su2(12, entanglement=\"circular\", reps=1)\n",
        "pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)\n",
        "qc_t = pm.run(qc)\n",
        "qc_t.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d3ab848d-2782-431c-b028-69a46cf94360",
      "metadata": {},
      "source": [
        "Uma sequência de desacoplamento dinâmico é uma série de portas que compõem a identidade e são espaçadas regularmente no tempo. Por exemplo, comece criando uma sequência simples chamada XY4 que consiste em quatro portas.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "368df772-aee7-4b59-b096-a47e5bc94577",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit.library import XGate, YGate\n",
        "\n",
        "X = XGate()\n",
        "Y = YGate()\n",
        "\n",
        "dd_sequence = [X, Y, X, Y]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d5eafd85-6fea-42ac-8bcb-0abf15635456",
      "metadata": {},
      "source": [
        "Devido ao tempo regular das sequências de desacoplamento dinâmico, as informações sobre o `YGate` devem ser adicionadas ao `target` porque ele *não* é um portão básico, ao passo que o `XGate` é. Sabemos *a priori* que o `YGate` tem a mesma duração e erro que o `XGate`, portanto, podemos simplesmente recuperar essas propriedades do `target` e adicioná-las de volta aos `YGate` objetos. É também por isso que os `basis_gates` foram salvos separadamente, já que estamos adicionando a `YGate` instrução ao, `target` embora não seja um portão base real do `ibm_fez`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "cabac6ca-c845-4c05-8c7d-2940717b3120",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import InstructionProperties\n",
        "\n",
        "y_gate_properties = {}\n",
        "for qubit in range(target.num_qubits):\n",
        "    y_gate_properties.update(\n",
        "        {\n",
        "            (qubit,): InstructionProperties(\n",
        "                duration=target[\"x\"][(qubit,)].duration,\n",
        "                error=target[\"x\"][(qubit,)].error,\n",
        "            )\n",
        "        }\n",
        "    )\n",
        "\n",
        "target.add_instruction(YGate(), y_gate_properties)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d33f64d6-c4e3-4881-a924-f30dfce35106",
      "metadata": {},
      "source": [
        "Os circuitos Ansatz, como o `efficient_su2` , são parametrizados, portanto, devem ter um valor vinculado a eles antes de serem enviados ao backend. Aqui, atribua parâmetros aleatórios.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "788839cc-9378-4c9d-95fd-df0ec6bc2d64",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "qc_t.assign_parameters(\n",
        "    rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "36d54ded-1786-41c0-9c8a-75f339dbd160",
      "metadata": {},
      "source": [
        "Em seguida, execute os passes personalizados. Instanciar o `PassManager` com `ALAPScheduleAnalysis` e `PadDynamicalDecoupling`.  Execute `ALAPScheduleAnalysis` primeiro para adicionar informações de tempo sobre o circuito quântico antes que as sequências de desacoplamento dinâmico com espaçamento regular possam ser adicionadas. Esses passes são executados no circuito com `.run()`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "334796e7-fb37-42fa-be54-4135b485246b",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import PassManager\n",
        "from qiskit.transpiler.passes.scheduling import (\n",
        "    ALAPScheduleAnalysis,\n",
        "    PadDynamicalDecoupling,\n",
        ")\n",
        "\n",
        "dd_pm = PassManager(\n",
        "    [\n",
        "        ALAPScheduleAnalysis(target=target),\n",
        "        PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),\n",
        "    ]\n",
        ")\n",
        "qc_dd = dd_pm.run(qc_t)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b0f68880-066c-4586-a27c-5d0f90d674f7",
      "metadata": {},
      "source": [
        "Use a ferramenta de [`timeline_drawer`](/docs/api/qiskit/qiskit.visualization.timeline_drawer) visualização para ver o tempo do circuito e confirmar que uma sequência regularmente espaçada de `XGate` objetos e `YGate` objetos aparece no circuito.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "7a552621-a96f-4bb8-ae9b-4ab5a65bbb64",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/7a552621-a96f-4bb8-ae9b-4ab5a65bbb64-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import timeline_drawer\n",
        "\n",
        "timeline_drawer(qc_dd, idle_wires=False, target=target)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "836a4094-0e55-4028-9e2e-cdf561d27049",
      "metadata": {},
      "source": [
        "Por fim, como o `YGate` não é um portão de base real do nosso backend, aplique manualmente a passagem `BasisTranslator` (essa é uma passagem padrão, mas é executada antes do agendamento, portanto, precisa ser aplicada novamente). A biblioteca de equivalência de sessão é uma biblioteca de equivalências de circuitos que permite que o transpilador decomponha os circuitos em portas de base, conforme também especificado como um argumento.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f0f4b29d-1c95-47d2-a7ad-8e130eaff74a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/f0f4b29d-1c95-47d2-a7ad-8e130eaff74a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.equivalence_library import (\n",
        "    SessionEquivalenceLibrary as sel,\n",
        ")\n",
        "from qiskit.transpiler.passes import BasisTranslator\n",
        "\n",
        "qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)\n",
        "qc_dd.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fafca471-0042-41f8-964c-606b4ee0d5cd",
      "metadata": {},
      "source": [
        "Agora, `YGate` os objetos estão ausentes do nosso circuito e há informações explícitas de temporização na forma de `Delay` portas. Este circuito transposto com desacoplamento dinâmico está agora pronto para ser enviado para o backend.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "95fee5f9-9e7d-47db-83c2-309ca03d357a",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Para saber como usar a função `generate_preset_passmanager` em vez de escrever seus próprios passes, comece pelo tópico [Definições padrão de transpilação e opções de configuração](defaults-and-configuration-options).\n",
        "  * Experimente o guia [Comparar configurações do transpiler](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings).\n",
        "  * Consulte [a documentação da API Transpile](https://docs.quantum-computing.ibm.com/api/qiskit/transpiler).\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
}