{
  "cells": [
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "f5d21946",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "source": [
        "---\n",
        "title: \"Códigos de repetição\"\n",
        "description: \"Este tutorial demonstra como construir códigos de repetição básicos usando circuitos dinâmicos d IBM, um exemplo de correção básica de erros quânticos (QEC).\"\n",
        "---\n",
        "\n",
        "<span id=\"repetition-codes\" />\n",
        "\n",
        "# Códigos de repetição\n",
        "\n",
        "*Estimativa de uso: menos de 1 minuto em um processador Heron (OBSERVAÇÃO: essa é apenas uma estimativa. Seu tempo de execução pode variar)*\n",
        "\n",
        "<span id=\"background\" />\n",
        "\n",
        "## Segundo plano\n",
        "\n",
        "Para permitir a correção de erros quânticos (QEC) em tempo real, você precisa ser capaz de controlar dinamicamente o fluxo do programa quântico durante a execução, de modo que as portas quânticas possam ser condicionadas aos resultados da medição. Este tutorial executa o código bit-flip, que é uma forma muito simples de QEC. Ele demonstra um circuito quântico dinâmico que pode proteger um qubit codificado de um único erro de inversão de bit e, em seguida, avalia o desempenho do código de inversão de bit.\n",
        "\n",
        "Você pode explorar qubits ancilla adicionais e emaranhamento para medir *estabilizadores* que não transformam as informações quânticas codificadas e, ao mesmo tempo, informá-lo sobre algumas classes de erros que podem ter ocorrido. Um código estabilizador quântico codifica $k$ qubits lógicos em $n$ qubits físicos. Os códigos estabilizadores se concentram criticamente na correção de um conjunto de erros discretos com o apoio do grupo Pauli $\\Pi^n$.\n",
        "\n",
        "Para obter mais informações sobre a QEC, consulte “[Correção](https://arxiv.org/abs/0905.2794) de erros quânticos para iniciantes”.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "88672bd6",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## Requisitos\n",
        "\n",
        "Antes de iniciar este tutorial, verifique se você tem os seguintes itens instalados:\n",
        "\n",
        "* Qiskit SDK v2.0 ou posterior, com suporte [para visualização](/docs/api/qiskit/visualization)\n",
        "* Qiskit Runtime v0.40 ou posterior (`pip install qiskit-ibm-runtime`)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "14c29e8b",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## Instalação\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1b9fd8ad",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [],
      "source": [
        "# Qiskit imports\n",
        "from qiskit import (\n",
        "    QuantumCircuit,\n",
        "    QuantumRegister,\n",
        "    ClassicalRegister,\n",
        ")\n",
        "\n",
        "# qiskit-ibm-runtime\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n",
        "\n",
        "from qiskit_ibm_runtime.circuit import MidCircuitMeasure\n",
        "\n",
        "service = QiskitRuntimeService()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4d01e8d3",
      "metadata": {},
      "source": [
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "## Etapa 1. Mapeie entradas clássicas para um problema quântico\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cdee0b18",
      "metadata": {},
      "source": [
        "<span id=\"build-a-bit-flip-stabilizer-circuit\" />\n",
        "\n",
        "### Construa um circuito estabilizador de inversão de bits\n",
        "\n",
        "O código bit-flip está entre os exemplos mais simples de um código estabilizador. Ele protege o estado contra um único erro de inversão de bit (X) em qualquer um dos qubits de codificação. Considere a ação do erro de inversão de bit $X$, que mapeia $|0\\rangle \\rightarrow |1\\rangle$ e $|1\\rangle \\rightarrow |0\\rangle$ em qualquer um de nossos qubits, então temos $\\epsilon = \\{E_0, E_1, E_2 \\} = \\{IIX, IXI, XII\\}$. O código requer cinco qubits: três são usados para codificar o estado protegido e os dois restantes são usados como auxiliares de medição do estabilizador.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b588703a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Choose the least busy backend that supports `measure_2`.\n",
        "\n",
        "backend = service.least_busy(\n",
        "    filters=lambda b: \"measure_2\" in b.supported_instructions,\n",
        "    operational=True,\n",
        "    simulator=False,\n",
        "    dynamic_circuits=True,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "606dff18",
      "metadata": {},
      "outputs": [],
      "source": [
        "qreg_data = QuantumRegister(3)\n",
        "qreg_measure = QuantumRegister(2)\n",
        "creg_data = ClassicalRegister(3, name=\"data\")\n",
        "creg_syndrome = ClassicalRegister(2, name=\"syndrome\")\n",
        "state_data = qreg_data[0]\n",
        "ancillas_data = qreg_data[1:]\n",
        "\n",
        "\n",
        "def build_qc():\n",
        "    \"\"\"Build a typical error correction circuit\"\"\"\n",
        "    return QuantumCircuit(qreg_data, qreg_measure, creg_data, creg_syndrome)\n",
        "\n",
        "\n",
        "def initialize_qubits(circuit: QuantumCircuit):\n",
        "    \"\"\"Initialize qubit to |1>\"\"\"\n",
        "    circuit.x(qreg_data[0])\n",
        "    circuit.barrier(qreg_data)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def encode_bit_flip(circuit, state, ancillas) -> QuantumCircuit:\n",
        "    \"\"\"Encode bit-flip. This is done by simply adding a cx\"\"\"\n",
        "    for ancilla in ancillas:\n",
        "        circuit.cx(state, ancilla)\n",
        "    circuit.barrier(state, *ancillas)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def measure_syndrome_bit(circuit, qreg_data, qreg_measure, creg_measure):\n",
        "    \"\"\"\n",
        "    Measure the syndrome by measuring the parity.\n",
        "    We reset our ancilla qubits after measuring the stabilizer\n",
        "    so we can reuse them for repeated stabilizer measurements.\n",
        "    Because we have already observed the state of the qubit,\n",
        "    we can write the conditional reset protocol directly to\n",
        "    avoid another round of qubit measurement if we used\n",
        "    the `reset` instruction.\n",
        "    \"\"\"\n",
        "    circuit.cx(qreg_data[0], qreg_measure[0])\n",
        "    circuit.cx(qreg_data[1], qreg_measure[0])\n",
        "    circuit.cx(qreg_data[0], qreg_measure[1])\n",
        "    circuit.cx(qreg_data[2], qreg_measure[1])\n",
        "    circuit.barrier(*qreg_data, *qreg_measure)\n",
        "    circuit.append(MidCircuitMeasure(), [qreg_measure[0]], [creg_measure[0]])\n",
        "    circuit.append(MidCircuitMeasure(), [qreg_measure[1]], [creg_measure[1]])\n",
        "\n",
        "    with circuit.if_test((creg_measure[0], 1)):\n",
        "        circuit.x(qreg_measure[0])\n",
        "    with circuit.if_test((creg_measure[1], 1)):\n",
        "        circuit.x(qreg_measure[1])\n",
        "    circuit.barrier(*qreg_data, *qreg_measure)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def apply_correction_bit(circuit, qreg_data, creg_syndrome):\n",
        "    \"\"\"We can detect where an error occurred and correct our state\"\"\"\n",
        "    with circuit.if_test((creg_syndrome, 3)):\n",
        "        circuit.x(qreg_data[0])\n",
        "    with circuit.if_test((creg_syndrome, 1)):\n",
        "        circuit.x(qreg_data[1])\n",
        "    with circuit.if_test((creg_syndrome, 2)):\n",
        "        circuit.x(qreg_data[2])\n",
        "    circuit.barrier(qreg_data)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def apply_final_readout(circuit, qreg_data, creg_data):\n",
        "    \"\"\"Read out the final measurements\"\"\"\n",
        "    circuit.barrier(qreg_data)\n",
        "    circuit.measure(qreg_data, creg_data)\n",
        "    return circuit"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "dbe02949",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/dbe02949-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/dbe02949-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "def build_error_correction_sequence(apply_correction: bool) -> QuantumCircuit:\n",
        "    circuit = build_qc()\n",
        "    circuit = initialize_qubits(circuit)\n",
        "    circuit = encode_bit_flip(circuit, state_data, ancillas_data)\n",
        "    circuit = measure_syndrome_bit(\n",
        "        circuit, qreg_data, qreg_measure, creg_syndrome\n",
        "    )\n",
        "\n",
        "    if apply_correction:\n",
        "        circuit = apply_correction_bit(circuit, qreg_data, creg_syndrome)\n",
        "\n",
        "    circuit = apply_final_readout(circuit, qreg_data, creg_data)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "circuit = build_error_correction_sequence(apply_correction=True)\n",
        "circuit.draw(output=\"mpl\", style=\"iqp\", cregbundle=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "609c0c47",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-the-problem-for-quantum-execution\" />\n",
        "\n",
        "## Etapa 2. Otimize o problema para execução quântica\n",
        "\n",
        "Para reduzir o tempo total de execução da tarefa, o `Qiskit primitives` aceita apenas circuitos e observáveis que estejam em conformidade com as instruções e a conectividade suportadas pelo sistema de destino (conhecidos como circuitos e observáveis da arquitetura de conjunto de instruções (ISA)).  [Saiba mais sobre transpilação](/docs/guides/transpile).\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "c8ea2716",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "source": [
        "<span id=\"generate-isa-circuits\" />\n",
        "\n",
        "### Gerar circuitos ISA\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "67b55eef",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/67b55eef-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/67b55eef-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(circuit)\n",
        "\n",
        "isa_circuit.draw(\"mpl\", style=\"iqp\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "67acea4f",
      "metadata": {},
      "outputs": [],
      "source": [
        "no_correction_circuit = build_error_correction_sequence(\n",
        "    apply_correction=False\n",
        ")\n",
        "\n",
        "isa_no_correction_circuit = pm.run(no_correction_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bcd61a1f",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-qiskit-primitives\" />\n",
        "\n",
        "## Etapa 3. Execute usando Qiskit primitives\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e68d10d2",
      "metadata": {},
      "source": [
        "Execute a versão com correção aplicada e uma sem correção.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "d53319ba",
      "metadata": {},
      "outputs": [],
      "source": [
        "sampler_no_correction = Sampler(backend)\n",
        "job_no_correction = sampler_no_correction.run(\n",
        "    [isa_no_correction_circuit], shots=1000\n",
        ")\n",
        "result_no_correction = job_no_correction.result()[0]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "df7421d0",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [],
      "source": [
        "sampler_with_correction = Sampler(backend)\n",
        "\n",
        "job_with_correction = sampler_with_correction.run([isa_circuit], shots=1000)\n",
        "result_with_correction = job_with_correction.result()[0]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "1cba37f5",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Data (no correction):\n",
            "{'111': 878, '011': 42, '110': 35, '101': 40, '100': 1, '001': 2, '000': 2}\n",
            "Syndrome (no correction):\n",
            "{'00': 942, '10': 33, '01': 22, '11': 3}\n"
          ]
        }
      ],
      "source": [
        "print(f\"Data (no correction):\\n{result_no_correction.data.data.get_counts()}\")\n",
        "print(\n",
        "    f\"Syndrome (no correction):\\n{result_no_correction.data.syndrome.get_counts()}\"\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "7b7697f2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Data (corrected):\n",
            "{'111': 889, '110': 25, '000': 11, '011': 45, '101': 17, '010': 10, '001': 2, '100': 1}\n",
            "Syndrome (corrected):\n",
            "{'00': 929, '01': 39, '10': 20, '11': 12}\n"
          ]
        }
      ],
      "source": [
        "print(f\"Data (corrected):\\n{result_with_correction.data.data.get_counts()}\")\n",
        "print(\n",
        "    f\"Syndrome (corrected):\\n{result_with_correction.data.syndrome.get_counts()}\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1b652319",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-return-result-in-classical-format\" />\n",
        "\n",
        "## Etapa 4. Pós-processamento, retornar resultado no formato clássico\n",
        "\n",
        "Você pode ver que o código de inversão de bits detectou e corrigiu muitos erros, resultando em menos erros em geral.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "fa59fb42",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [],
      "source": [
        "def decode_result(data_counts, syndrome_counts):\n",
        "    shots = sum(data_counts.values())\n",
        "    success_trials = data_counts.get(\"000\", 0) + data_counts.get(\"111\", 0)\n",
        "    failed_trials = shots - success_trials\n",
        "    error_correction_events = shots - syndrome_counts.get(\"00\", 0)\n",
        "    print(\n",
        "        f\"Bit flip errors were detected/corrected on \"\n",
        "        f\"{error_correction_events}/{shots} trials.\"\n",
        "    )\n",
        "    print(\n",
        "        f\"A final parity error was detected on \"\n",
        "        f\"{failed_trials}/{shots} trials.\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "5b1ff3a3",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Completed bit code experiment data measurement counts (no correction): {'111': 878, '011': 42, '110': 35, '101': 40, '100': 1, '001': 2, '000': 2}\n",
            "Completed bit code experiment syndrome measurement counts (no correction): {'00': 942, '10': 33, '01': 22, '11': 3}\n",
            "Bit flip errors were detected/corrected on 58/1000 trials.\n",
            "A final parity error was detected on 120/1000 trials.\n"
          ]
        }
      ],
      "source": [
        "# non-corrected marginalized results\n",
        "data_result = result_no_correction.data.data.get_counts()\n",
        "marginalized_syndrome_result = result_no_correction.data.syndrome.get_counts()\n",
        "\n",
        "print(\n",
        "    f\"Completed bit code experiment data measurement counts (no correction): \"\n",
        "    f\"{data_result}\"\n",
        ")\n",
        "print(\n",
        "    f\"Completed bit code experiment syndrome measurement counts (no correction): \"\n",
        "    f\"{marginalized_syndrome_result}\"\n",
        ")\n",
        "decode_result(data_result, marginalized_syndrome_result)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "7f1c2d48",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Completed bit code experiment data measurement counts (corrected): {'111': 889, '110': 25, '000': 11, '011': 45, '101': 17, '010': 10, '001': 2, '100': 1}\n",
            "Completed bit code experiment syndrome measurement counts (corrected): {'00': 929, '01': 39, '10': 20, '11': 12}\n",
            "Bit flip errors were detected/corrected on 71/1000 trials.\n",
            "A final parity error was detected on 100/1000 trials.\n"
          ]
        }
      ],
      "source": [
        "# corrected marginalized results\n",
        "corrected_data_result = result_with_correction.data.data.get_counts()\n",
        "corrected_syndrome_result = result_with_correction.data.syndrome.get_counts()\n",
        "\n",
        "print(\n",
        "    f\"Completed bit code experiment data measurement counts (corrected): \"\n",
        "    f\"{corrected_data_result}\"\n",
        ")\n",
        "print(\n",
        "    f\"Completed bit code experiment syndrome measurement counts (corrected): \"\n",
        "    f\"{corrected_syndrome_result}\"\n",
        ")\n",
        "decode_result(corrected_data_result, corrected_syndrome_result)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b66026c4",
      "metadata": {},
      "source": [
        "<span id=\"tutorial-survey\" />\n",
        "\n",
        "## Pesquisa tutorial\n",
        "\n",
        "Responda a esta breve pesquisa para fornecer feedback sobre este tutorial. Suas percepções nos ajudarão a melhorar nossas ofertas de conteúdo e a experiência do usuário.\n",
        "\n",
        "[Link para a pesquisa](https://your.feedback.ibm.com/jfe/form/SV_5onAlfA2Y7ac1FA)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Slideshow",
    "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"
    },
    "hours": 1.5,
    "qpuSeconds": 60
  },
  "nbformat": 4,
  "nbformat_minor": 5
}