{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "7e51aef7-70db-4772-a53f-100af6ad6902",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Ejemplos de estimadores\"\n",
        "description: \"Ejemplos prácticos del uso de la primitiva «Estimator» en Qiskit Runtime.\"\n",
        "---\n",
        "\n",
        "<span id=\"estimator-examples\" />\n",
        "\n",
        "# Ejemplos de estimadores\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "10cf3d45-503c-41c9-b0a1-51c23e32bc5f",
      "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=\"Versiones del paquete\">\n",
        "    El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos.\n",
        "    Recomendamos utilizar estas versiones o posteriores.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.4.0\n",
        "    qiskit-ibm-runtime~=0.46.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3a98beb8-d1df-4daf-80ce-d51e4dc31cfa",
      "metadata": {},
      "source": [
        "Los ejemplos de esta sección muestran algunas formas habituales de utilizar Estimator. Antes de ejecutar estos ejemplos, sigue las instrucciones de [la sección «Instalar Qiskit».](install-qiskit)\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Todos estos ejemplos utilizan las primitivas de Qiskit Runtime, pero también podrías utilizar las primitivas básicas.\n",
        "</Admonition>\n",
        "\n",
        "Con Estimator, calcula e interpreta de forma eficiente los valores esperados de los operadores cuánticos necesarios para numerosos algoritmos. Descubre sus aplicaciones en el modelado molecular, el aprendizaje automático y los problemas de optimización complejos.\n",
        "\n",
        "<span id=\"run-a-single-experiment\" />\n",
        "\n",
        "## Realizar un único experimento\n",
        "\n",
        "Utiliza Estimator para calcular el valor esperado de un par circuito-observable.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "6bc4a6a3-612e-4ad8-9fe3-3d56a4cb9a8f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Expectation value: -0.0564042303172738\n",
            " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import iqp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n",
        "\n",
        "n_qubits = 50\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=n_qubits\n",
        ")\n",
        "\n",
        "mat = np.real(random_hermitian(n_qubits, seed=1234))\n",
        "circuit = iqp(mat)\n",
        "observable = SparsePauliOp(\"Z\" * 50)\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(circuit)\n",
        "isa_observable = observable.apply_layout(isa_circuit.layout)\n",
        "\n",
        "estimator = Estimator(mode=backend)\n",
        "job = estimator.run([(isa_circuit, isa_observable)])\n",
        "result = job.result()\n",
        "\n",
        "print(f\" > Expectation value: {result[0].data.evs}\")\n",
        "print(f\" > Metadata: {result[0].metadata}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c8594feb-0516-4cca-9064-232906b980a4",
      "metadata": {},
      "source": [
        "<span id=\"run-multiple-experiments-in-a-single-job\" />\n",
        "\n",
        "## Ejecutar varios experimentos en un solo trabajo\n",
        "\n",
        "Utilice Estimator para determinar los valores esperados de múltiples pares de variables observables del circuito.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "662e73e9-8454-470a-b6aa-e84343005ca6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>> Expectation values for PUB 0: 0.09218950064020487\n",
            ">>> Standard errors for PUB 0: 0.2666311918779662\n",
            ">>> Expectation values for PUB 1: -0.7159533073929961\n",
            ">>> Standard errors for PUB 1: 0.5443960702392404\n",
            ">>> Expectation values for PUB 2: -0.14271555996035679\n",
            ">>> Standard errors for PUB 2: 0.2714876601210801\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import iqp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n",
        "\n",
        "n_qubits = 50\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=n_qubits\n",
        ")\n",
        "\n",
        "rng = np.random.default_rng()\n",
        "mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]\n",
        "\n",
        "pubs = []\n",
        "circuits = [iqp(mat) for mat in mats]\n",
        "observables = [\n",
        "    SparsePauliOp(\"X\" * 50),\n",
        "    SparsePauliOp(\"Y\" * 50),\n",
        "    SparsePauliOp(\"Z\" * 50),\n",
        "]\n",
        "\n",
        "# Get ISA circuits\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "\n",
        "for qc, obs in zip(circuits, observables):\n",
        "    isa_circuit = pm.run(qc)\n",
        "    isa_obs = obs.apply_layout(isa_circuit.layout)\n",
        "    pubs.append((isa_circuit, isa_obs))\n",
        "\n",
        "estimator = Estimator(backend)\n",
        "job = estimator.run(pubs)\n",
        "job_result = job.result()\n",
        "\n",
        "for idx in range(len(pubs)):\n",
        "    pub_result = job_result[idx]\n",
        "    print(f\">>> Expectation values for PUB {idx}: {pub_result.data.evs}\")\n",
        "    print(f\">>> Standard errors for PUB {idx}: {pub_result.data.stds}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5176c806-e00d-4def-93b4-64216bf8cc64",
      "metadata": {},
      "source": [
        "<span id=\"run-parameterized-circuits\" />\n",
        "\n",
        "## Ejecutar circuitos parametrizados\n",
        "\n",
        "Utiliza Estimator para ejecutar tres experimentos en un solo trabajo, aprovechando los valores de los parámetros para aumentar la reutilización de los circuitos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "3f991c86-8bcd-4d9e-bed1-a6a7ac0cabb6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>> Expectation values: [[ 0.9821299   0.92848415  0.78219632  0.56555001  0.29732126 -0.02496591\n",
            "  -0.30928839 -0.5779298  -0.79292547 -0.92084995 -0.9806856  -0.93075378\n",
            "  -0.80014701 -0.57627916 -0.32496945 -0.00495192  0.29938456  0.56513735\n",
            "   0.80117866  0.92580187  0.98151091]\n",
            " [-0.00330128  0.30949472  0.58123108  0.78549759  0.9357057   0.97903496\n",
            "   0.93240442  0.78879887  0.58267539  0.2948453   0.0041266  -0.29835291\n",
            "  -0.57339055 -0.78075201 -0.92477022 -0.97882863 -0.93075378 -0.79148116\n",
            "  -0.57958044 -0.30557445  0.00598356]\n",
            " [-0.01031649 -0.34250749 -0.59257922 -0.80819387 -0.95159309 -0.99616033\n",
            "  -0.9336424  -0.78054568 -0.57112092 -0.30639977  0.00866585  0.30474913\n",
            "   0.57627916  0.81149515  0.95035511  0.99224006  0.9530374   0.78673557\n",
            "   0.57834246  0.30557445 -0.00866585]\n",
            " [ 0.99616033  0.93446772  0.80344829  0.5841197   0.29401998 -0.01980766\n",
            "  -0.31300232 -0.59361087 -0.81170148 -0.94849814 -0.99327171 -0.93880064\n",
            "  -0.80860653 -0.58019943 -0.30186051  0.01856968  0.29009972  0.59835645\n",
            "   0.80613057  0.94437155  0.98976411]]\n",
            ">>> Standard errors: [[0.00346988 0.00453617 0.00722056 0.00981693 0.01144016 0.01501324\n",
            "  0.01334599 0.01100181 0.00916772 0.00689316 0.00381375 0.00555949\n",
            "  0.00576968 0.01074419 0.01298665 0.01231428 0.0128399  0.00946472\n",
            "  0.00819982 0.00494361 0.00359142]\n",
            " [0.01087106 0.01070164 0.00869617 0.00735853 0.00475886 0.00351362\n",
            "  0.00422178 0.00865889 0.00830071 0.01030088 0.01114086 0.01184411\n",
            "  0.00958307 0.00740947 0.00577496 0.00417023 0.00434772 0.00825295\n",
            "  0.00805684 0.01071724 0.01320466]\n",
            " [0.01346985 0.01132597 0.01143045 0.00729025 0.00490636 0.00287136\n",
            "  0.0051666  0.00718324 0.00899331 0.00980723 0.00957352 0.01211162\n",
            "  0.00932736 0.00658862 0.00555066 0.00271584 0.00581507 0.00778402\n",
            "  0.00935326 0.01223799 0.01214173]\n",
            " [0.00297333 0.00520897 0.00730712 0.01099862 0.01320699 0.01250301\n",
            "  0.0151248  0.00924768 0.00639241 0.00529221 0.00270411 0.00463968\n",
            "  0.00729108 0.00685512 0.00993793 0.0101938  0.01109962 0.01130657\n",
            "  0.00795711 0.00532976 0.00299901]]\n",
            ">>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "\n",
        "from qiskit.circuit import QuantumCircuit, Parameter\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Step 1: Map classical inputs to a quantum problem\n",
        "theta = Parameter(\"θ\")\n",
        "\n",
        "chsh_circuit = QuantumCircuit(2)\n",
        "chsh_circuit.h(0)\n",
        "chsh_circuit.cx(0, 1)\n",
        "chsh_circuit.ry(theta, 0)\n",
        "\n",
        "number_of_phases = 21\n",
        "phases = np.linspace(0, 2 * np.pi, number_of_phases)\n",
        "individual_phases = [[ph] for ph in phases]\n",
        "\n",
        "ZZ = SparsePauliOp.from_list([(\"ZZ\", 1)])\n",
        "ZX = SparsePauliOp.from_list([(\"ZX\", 1)])\n",
        "XZ = SparsePauliOp.from_list([(\"XZ\", 1)])\n",
        "XX = SparsePauliOp.from_list([(\"XX\", 1)])\n",
        "ops = [ZZ, ZX, XZ, XX]\n",
        "\n",
        "# Step 2: Optimize problem for quantum execution.\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "chsh_isa_circuit = pm.run(chsh_circuit)\n",
        "isa_observables = [\n",
        "    operator.apply_layout(chsh_isa_circuit.layout) for operator in ops\n",
        "]\n",
        "\n",
        "# Step 3: Execute using Qiskit primitives.\n",
        "\n",
        "# Reshape observable array for broadcasting\n",
        "reshaped_ops = np.fromiter(isa_observables, dtype=object)\n",
        "reshaped_ops = reshaped_ops.reshape((4, 1))\n",
        "\n",
        "estimator = Estimator(backend, options={\"default_shots\": int(1e4)})\n",
        "job = estimator.run([(chsh_isa_circuit, reshaped_ops, individual_phases)])\n",
        "# Get results for the first (and only) PUB\n",
        "pub_result = job.result()[0]\n",
        "print(f\">>> Expectation values: {pub_result.data.evs}\")\n",
        "print(f\">>> Standard errors: {pub_result.data.stds}\")\n",
        "print(f\">>> Metadata: {pub_result.metadata}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "117454c0-c8df-48cd-8503-f4fd137d6991",
      "metadata": {},
      "source": [
        "<span id=\"use-batches-and-advanced-options\" />\n",
        "\n",
        "## Utiliza lotes y opciones avanzadas\n",
        "\n",
        "Explora el [modo de ejecución](/docs/guides/execution-modes) por lotes y las opciones avanzadas para optimizar el rendimiento de los circuitos en las QPU.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "f009e993-98fe-451c-96f5-738153005543",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Expectation value: -0.03391665163268988\n",
            " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n",
            " > Another Expectation value: -0.011113040458412918\n",
            " > More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import iqp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n",
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    Batch,\n",
        "    EstimatorV2 as Estimator,\n",
        ")\n",
        "\n",
        "n_qubits = 15\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=n_qubits\n",
        ")\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "mat = np.real(random_hermitian(n_qubits, seed=rng))\n",
        "circuit = iqp(mat)\n",
        "mat = np.real(random_hermitian(n_qubits, seed=rng))\n",
        "another_circuit = iqp(mat)\n",
        "observable = SparsePauliOp(\"X\" * n_qubits)\n",
        "another_observable = SparsePauliOp(\"Y\" * n_qubits)\n",
        "\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "isa_circuit = pm.run(circuit)\n",
        "another_isa_circuit = pm.run(another_circuit)\n",
        "isa_observable = observable.apply_layout(isa_circuit.layout)\n",
        "another_isa_observable = another_observable.apply_layout(\n",
        "    another_isa_circuit.layout\n",
        ")\n",
        "\n",
        "# The context manager automatically closes the batch.\n",
        "with Batch(backend=backend) as batch:\n",
        "    estimator = Estimator(mode=batch)\n",
        "\n",
        "    estimator.options.resilience_level = 1\n",
        "\n",
        "    job = estimator.run([(isa_circuit, isa_observable)])\n",
        "    another_job = estimator.run(\n",
        "        [(another_isa_circuit, another_isa_observable)]\n",
        "    )\n",
        "    result = job.result()\n",
        "    another_result = another_job.result()\n",
        "\n",
        "    # first job\n",
        "    print(f\" > Expectation value: {result[0].data.evs}\")\n",
        "    print(f\" > Metadata: {result[0].metadata}\")\n",
        "\n",
        "    # second job\n",
        "    print(f\" > Another Expectation value: {another_result[0].data.evs}\")\n",
        "    print(f\" > More Metadata: {another_result[0].metadata}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e207719d-da1b-4af2-ae63-4cb033865a1b",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendaciones\">\n",
        "  * [Especifica opciones avanzadas de tiempo de ejecución](runtime-options-overview).\n",
        "  * Practica con primitivas siguiendo la [lección](/learning/courses/variational-algorithm-design/cost-functions) sobre la función «Cost» en IBM Quantum® Learning.\n",
        "  * Descubre cómo realizar la transpilación de forma local en la sección «[Transpilación](/docs/guides/transpile/) ».\n",
        "  * Consulta la guía [sobre la configuración del transpilador Compare](/docs/guides/circuit-transpilation-settings).\n",
        "  * Lea «[Migrar a primitivas de `V2`](/docs/guides/v2-primitives) ».\n",
        "  * Ten en cuenta [los límites del trabajo](/docs/guides/job-limits) al enviarlo a una QPU de IBM®.\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
}