{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "066d7e4d-a975-4519-b56f-095f861be3ac",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Entradas e saídas do estimador\"\n",
        "description: \"Compreender os formatos de entrada e saída da primitiva Estimator\"\n",
        "---\n",
        "\n",
        "<span id=\"estimator-inputs-and-outputs\" />\n",
        "\n",
        "# Entradas e saídas do estimador\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "23e7dff0-fde5-4c2d-89c2-fc5ab99240fe",
      "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 com base nos seguintes requisitos.\n",
        "    Recomendamos usar essas versões ou 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": "90d0c1e0-28e7-48da-a35f-6016fddea82c",
      "metadata": {},
      "source": [
        "Esta página apresenta uma visão geral das entradas e saídas da primitiva Estimator do Qiskit Runtime, que executa cargas de trabalho nos recursos de computação d IBM Quantum®. O Estimator permite definir com eficiência cargas de trabalho vetorizadas utilizando uma estrutura de dados chamada [**Bloco**](/docs/guides/primitive-input-output#pubs) Primitivo Unificado ( PUB ). Eles são utilizados como entradas para o [`run()`](/docs/api/qiskit-ibm-runtime/estimator-v2#run) método da primitiva Estimator, que executa a carga de trabalho definida como um trabalho. Então, após a conclusão do trabalho, os resultados são retornados em um formato que depende tanto dos PUBs utilizados quanto das opções de execução especificadas na primitiva.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "83a5fdd8-6547-47c7-9441-a7458edc7896",
      "metadata": {},
      "source": [
        "<span id=\"inputs\" />\n",
        "\n",
        "## Entradas\n",
        "\n",
        "Cada PUB tem o seguinte formato:\n",
        "\n",
        "(`<single circuit>`, `<one or more observables>`, `<optional one or more parameter values>`, `<optional precision>`),\n",
        "\n",
        "O parâmetro opcional `parameter values` pode ser uma lista ou um único parâmetro. Os elementos das variáveis observáveis e os valores dos parâmetros são combinados seguindo as regras de difusã NumPy, conforme descrito no tópico [“Entradas e saídas primitivas”](primitive-input-output#broadcasting-rules), e é retornada uma estimativa do valor esperado para cada elemento da forma difundida.\n",
        "\n",
        "<Admonition types=\"note\">\n",
        "  Se a entrada contiver medidas, elas serão ignoradas.\n",
        "</Admonition>\n",
        "\n",
        "Para a primitiva Estimator, um objeto `PUB` pode conter no máximo quatro valores:\n",
        "\n",
        "* Um único elemento `QuantumCircuit`, que pode conter um ou mais [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter) objetos\n",
        "* Uma lista de um ou mais observáveis, que especificam os valores esperados a serem estimados, organizados em uma matriz (por exemplo, um único observável representado como uma matriz de dimensão 0, uma lista de observáveis como uma matriz de dimensão 1 e assim por diante). Os dados podem estar em qualquer um dos `ObservablesArrayLike` formatos, como `Pauli`, `SparsePauliOp` `PauliList`,, ou `str`.\n",
        "  <Admonition type=\"note\" title=\"Variáveis observáveis no trajeto diário\">\n",
        "    * As variáveis observáveis de deslocamento **no mesmo `PUB`** são agrupadas por meio [desse método](/docs/api/qiskit/qiskit.quantum_info.PauliList#group_qubit_wise_commuting).\n",
        "    * Os parâmetros observáveis de deslocamento em diferentes PUBs, mesmo que tenham o mesmo circuito, não são estimados utilizando a mesma medição. Cada PUB representa uma base de mensuração diferente e, portanto, são necessárias mensurações separadas para cada PUB.\n",
        "    * Para garantir que as variáveis observáveis relacionadas ao deslocamento sejam estimadas utilizando a mesma medida, agrupe-as no mesmo `PUB`.\n",
        "  </Admonition>\n",
        "* Um conjunto de valores de parâmetros aos quais o circuito deve ser vinculado. Isso pode ser especificado como um único objeto semelhante a uma matriz, em que o último índice corresponde aos objetos do `Parameter` circuito ou pode ser omitido (ou, de forma equivalente, definido como `None`) caso o circuito não `Parameter` possua objetos.\n",
        "* (Opcionalmente) Uma precisão alvo para os valores esperados a serem estimados\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "846b3109-02a1-4783-ad3f-1c22f753c324",
      "metadata": {},
      "source": [
        "***\n",
        "\n",
        "O código a seguir mostra um exemplo de conjunto de entradas vetorizadas para a `Estimator` primitiva e as executa em um backend do tipo `IBM®` como um único `RuntimeJobV2 ` objeto.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "2f50a9f5-2cc1-4d83-9fe1-1b3a8be0d766",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import (\n",
        "    Parameter,\n",
        "    QuantumCircuit,\n",
        ")\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "\n",
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    EstimatorV2 as Estimator,\n",
        ")\n",
        "\n",
        "import numpy as np\n",
        "\n",
        "# Instantiate runtime service and get\n",
        "# the least busy backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Define a circuit with two parameters.\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.ry(Parameter(\"a\"), 0)\n",
        "circuit.rz(Parameter(\"b\"), 0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.h(0)\n",
        "\n",
        "# Transpile the circuit\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "layout = transpiled_circuit.layout\n",
        "\n",
        "# Now define a sweep over parameter values, the last axis of dimension 2 is\n",
        "# for the two parameters \"a\" and \"b\"\n",
        "params = np.vstack(\n",
        "    [\n",
        "        np.linspace(-np.pi, np.pi, 100),\n",
        "        np.linspace(-4 * np.pi, 4 * np.pi, 100),\n",
        "    ]\n",
        ").T\n",
        "\n",
        "# Define three observables. The inner length-1 lists cause this array of\n",
        "# observables to have shape (3, 1), rather than shape (3,) if they were\n",
        "# omitted.\n",
        "observables = [\n",
        "    [SparsePauliOp([\"XX\", \"IY\"], [0.5, 0.5])],\n",
        "    [SparsePauliOp(\"XX\")],\n",
        "    [SparsePauliOp(\"IY\")],\n",
        "]\n",
        "# Apply the same layout as the transpiled circuit.\n",
        "observables = [\n",
        "    [observable.apply_layout(layout) for observable in observable_set]\n",
        "    for observable_set in observables\n",
        "]\n",
        "\n",
        "# Estimate the expectation value for all 300 combinations of observables\n",
        "# and parameter values, where the pub result will have shape (3, 100).\n",
        "#\n",
        "# This shape is due to our array of parameter bindings having shape\n",
        "# (100, 2), combined with our array of observables having shape (3, 1).\n",
        "estimator_pub = (transpiled_circuit, observables, params)\n",
        "\n",
        "# Instantiate the new Estimator object, then run the transpiled circuit\n",
        "# using the set of parameters and observables.\n",
        "estimator = Estimator(mode=backend)\n",
        "job = estimator.run([estimator_pub])\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "90dccb20-1848-4367-a12d-434110ad5a5c",
      "metadata": {},
      "source": [
        "<span id=\"outputs\" />\n",
        "\n",
        "## Saídas\n",
        "\n",
        "Depois que um ou mais PUBs são enviados a uma QPU para execução e um trabalho é concluído com sucesso, os dados são retornados como um objeto [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) contêiner, acessado por meio da chamada ao `RuntimeJobV2.result()` método.\n",
        "\n",
        "O `PrimitiveResult` contém uma lista iterável de [`PubResult`](/docs/api/qiskit/qiskit.primitives.PubResult) objetos que contêm os resultados da execução de cada PUB.\n",
        "\n",
        "Cada elemento desta lista corresponde a cada objeto `PUB` enviado ao método da `run()` primitiva (por exemplo, um trabalho enviado com 20 PUBs retornará um `PrimitiveResult` objeto que contém uma lista de 20 `PubResult` objetos, um correspondendo a cada objeto `PUB`).\n",
        "\n",
        "Cada primitiva `PubResult` do Estimador contém, no mínimo, uma matriz de valores esperados (`PubResult.data.evs`) e desvios-padrão associados (seja `PubResult.data.stds` ou, `PubResult.data.ensemble_standard_error` dependendo do `resilience_level` utilizado), mas pode conter mais dados, dependendo das opções de mitigação de erros especificadas.\n",
        "\n",
        "Cada `PubResult` objeto possui um atributo `data` e um `metadata` atributo.\n",
        "\n",
        "* O `data` atributo é um campo personalizado [`DataBin`](/docs/api/qiskit/qiskit.primitives.DataBin) que contém os valores reais das medições, os desvios padrão e assim por diante.\n",
        "* O `DataBin` possui vários atributos, dependendo da forma ou estrutura do `PUB` associado, bem como das opções de mitigação de erros especificadas pela primitiva usada para enviar o trabalho (por exemplo, [ZNE](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne) ou [PEC](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec) ).\n",
        "* O `metadata` atributo contém informações sobre o tempo de execução e as opções de mitigação de erros utilizadas (explicadas mais adiante na seção [“Metadados do resultado”](#result-metadata) desta página).\n",
        "\n",
        "A seguir, apresentamos um esboço visual da estrutura `PrimitiveResult` de dados da saída do Estimador:\n",
        "\n",
        "```\n",
        "└── PrimitiveResult\n",
        "    ├── PubResult[0]\n",
        "    │   ├── metadata\n",
        "    │   └── data  ## In the form of a DataBin object\n",
        "    │       ├── evs\n",
        "    │       │   └── List of estimated expectation values in the shape\n",
        "    |       |         specified by the first pub\n",
        "    │       └── stds\n",
        "    │           └── List of calculated standard deviations in the\n",
        "    |                 same shape as above\n",
        "    ├── PubResult[1]\n",
        "    |   ├── metadata\n",
        "    |   └── data  ## In the form of a DataBin object\n",
        "    |       ├── evs\n",
        "    |       │   └── List of estimated expectation values in the shape\n",
        "    |       |        specified by the second pub\n",
        "    |       └── stds\n",
        "    |           └── List of calculated standard deviations in the\n",
        "    |                same shape as above\n",
        "    ├── ...\n",
        "    ├── ...\n",
        "    └── ...\n",
        "```\n",
        "\n",
        "Em termos simples, uma única função retorna um `PrimitiveResult` objeto e contém uma lista de um ou mais `PubResult` objetos. Esses `PubResult` objetos armazenam, então, os dados de medição de cada `PUB` que foi enviado para a tarefa.\n",
        "\n",
        "O trecho de código abaixo descreve o `PrimitiveResult` formato (e os associados `PubResult`) da tarefa criada acima.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "53a4d5ae-109b-452b-bbc5-2d7940c5182c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The result of the submitted job had 1 PUBs and has a value:\n",
            " PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})\n",
            "\n",
            "The associated PubResult of this job has the following data bins:\n",
            " {result[0].data}\n",
            "\n",
            "And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])\n",
            "Recall that this shape is due to our array of parameter binding setshaving shape (100, 2), where 2 is the number of parameters in the circuit, combined with our array of observables having shape (3, 1). \n",
            "\n",
            "The expectation values measured from this PUB are: \n",
            "{result[0].data.evs}\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(\n",
        "    f\"The result of the submitted job had {len(result)} \"\n",
        "    f\"PUBs and has a value:\\n {result}\\n\"\n",
        ")\n",
        "print(\n",
        "    \"The associated PubResult of this job has the following data bins:\\n \"\n",
        "    \"{result[0].data}\\n\"\n",
        ")\n",
        "print(f\"And this DataBin has attributes: {result[0].data.keys()}\")\n",
        "print(\n",
        "    \"Recall that this shape is due to our array of parameter binding sets\"\n",
        "    \"having shape (100, 2), where 2 is the number of parameters in the \"\n",
        "    \"circuit, combined with our array of observables having shape (3, 1). \\n\"\n",
        ")\n",
        "with np.printoptions(threshold=200):\n",
        "    print(\n",
        "        \"The expectation values measured from this PUB are: \\n\"\n",
        "        \"{result[0].data.evs}\\n\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "000ade51-d940-45f9-84ea-16ad283a930f",
      "metadata": {},
      "source": [
        "<span id=\"how-the-estimator-primitive-calculates-error\" />\n",
        "\n",
        "#### Como a primitiva Estimator calcula o erro\n",
        "\n",
        "Além da estimativa da média das variáveis observáveis passadas nos PUBs de entrada (o `evs` campo do `DataBin`), o Estimador também tenta fornecer uma estimativa do erro associado a esses valores esperados. Todas as consultas ao Estimator preencherão o `stds` campo com uma quantidade semelhante ao erro-padrão da média para cada valor esperado, mas algumas opções de mitigação de erros fornecem informações adicionais, tais como `ensemble_standard_error`.\n",
        "\n",
        "Considere um único observável $\\mathcal{O}$. Na ausência de [ZNE](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne), pode-se considerar que cada iteração da execução do Estimador fornece uma estimativa pontual do valor esperado $\\langle \\mathcal{O} \\rangle$. Se as estimativas pontuais estiverem em um vetor `Os`, então o valor retornado em `ensemble_standard_error` é equivalente ao seguinte (em que $\\sigma_{\\mathcal{O}}$ é o [desvio padrão da](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2) estimativa do valor esperado e $N_{shots}$ é o número de iterações):\n",
        "\n",
        "$\\frac{ \\sigma_{\\mathcal{O}} }{ \\sqrt{N_{shots}} },$\n",
        "\n",
        "que trata todas as tomadas como parte de um único conjunto. Se você solicitou [a rotação](/docs/guides/error-mitigation-and-suppression-techniques#pauli-twirling) de portas (`twirling.enable_gates = True`), é possível classificar as estimativas pontuais de $\\langle \\mathcal{O} \\rangle$ em conjuntos que compartilham uma rotação comum. Chamemos esses conjuntos de estimativas `O_twirls`de, e há `num_randomizations` (número de voltas) deles. Então, `stds` é o erro-padrão da média de `O_twirls`, como em\n",
        "\n",
        "$\\frac{ \\sigma_{\\mathcal{O}} }{ \\sqrt{N_{twirls}} },$\n",
        "\n",
        "onde $\\sigma_{\\mathcal{O}}$ é o desvio padrão de `O_twirls` e $N_{twirls}$ é o número de rotações. Quando você não habilita o efeito giratório, `stds` e `ensemble_standard_error` são iguais.\n",
        "\n",
        "Se você ativar o ZNE, os parâmetros `stds` descritos acima passarão a ser pesos em uma regressão não linear para um modelo de extrapolação. O que acaba sendo retornado no `stds` neste caso é a incerteza do modelo ajustado, avaliada com um fator de ruído igual a zero. Quando o ajuste é inadequado ou há grande incerteza no ajuste, o valor relatado `stds` pode se tornar muito elevado. Quando o ZNE está ativado, `pub_result.data.evs_noise_factors` e `pub_result.data.stds_noise_factors` também são preenchidos, para que você possa fazer sua própria extrapolação.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c4341184-a41a-4442-bc05-838c90ea93b8",
      "metadata": {},
      "source": [
        "<span id=\"result-metadata\" />\n",
        "\n",
        "## Metadados do resultado\n",
        "\n",
        "Além dos resultados da execução, tanto o objeto `PrimitiveResult` quanto `PubResult` o objeto contêm um atributo de metadados sobre o trabalho que foi enviado. Os metadados que contêm informações sobre todos os PUBs enviados (como as diversas [opções de tempo de execução](/docs/api/qiskit-ibm-runtime/options) disponíveis) podem ser encontrados no `PrimitiveResult.metatada`, enquanto os metadados específicos de cada PUB se encontram no `PubResult.metadata`.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  No campo de metadados, as implementações de primitivas podem retornar qualquer informação sobre a execução que seja relevante para elas, e não há pares chave-valor garantidos pela primitiva base. Portanto, os metadados retornados podem variar de acordo com as diferentes implementações das primitivas.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "626ba203-44e2-4b8f-b04d-04388b8b1fa1",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The metadata of the PrimitiveResult is:\n",
            "'dynamical_decoupling' : {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'},\n",
            "'twirling' : {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'},\n",
            "'resilience' : {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False},\n",
            "'version' : 2,\n",
            "\n",
            "The metadata of the PubResult result is:\n",
            "'shots' : 4096,\n",
            "'target_precision' : 0.015625,\n",
            "'circuit_metadata' : {},\n",
            "'resilience' : {},\n",
            "'num_randomizations' : 32,\n"
          ]
        }
      ],
      "source": [
        "# Print out the results metadata\n",
        "print(\"The metadata of the PrimitiveResult is:\")\n",
        "for key, val in result.metadata.items():\n",
        "    print(f\"'{key}' : {val},\")\n",
        "\n",
        "print(\"\\nThe metadata of the PubResult result is:\")\n",
        "for key, val in result[0].metadata.items():\n",
        "    print(f\"'{key}' : {val},\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Raw Cell Format",
    "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
}