{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "1379da5d-023f-42e7-8a3f-ea8c1e3a1d46",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Diagonalização quântica de Krylov baseada em amostras\"\n",
        "description: \"Os assuntos das lições anteriores são combinados para aproveitar as garantias de convergência do QKD e a velocidade do SQD no SKQD.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore arxiv Neel probs eigenvals Hatano */}\n",
        "\n",
        "<span id=\"sample-based-krylov-quantum-diagonalization-skqd\" />\n",
        "\n",
        "# Diagonalização quântica de Krylov baseada em amostras (SKQD)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "97cfd899-4196-4d24-bf16-60bdd3899600",
      "metadata": {},
      "source": [
        "Esta lição sobre Sample-based Krylov quantum diagonalization (SKQD) combina métodos explicados em métodos anteriores. Ele consiste em um único exemplo que utiliza a estrutura de padrões do Qiskit:\n",
        "\n",
        "* Etapa 1: Mapear o problema para circuitos e operadores quânticos\n",
        "* Etapa 2: otimizar para o hardware de destino\n",
        "* Etapa 3: Executar usando as primitivas d IBM Quantum\n",
        "* Etapa 4: Pós-processamento\n",
        "\n",
        "Uma etapa importante do método de diagonalização quântica baseado em amostras é gerar vetores de qualidade para o subespaço. Na lição anterior, usamos o ansatz LUCJ para gerar vetores de subespaço para um Hamiltoniano químico. Nesta lição, usaremos os estados quânticos de Krylov [\\[1\\]](#references), conforme discutido na lição 2. Primeiro, analisaremos como criar o espaço de Krylov em um computador quântico usando operações de evolução do tempo. Em seguida, faremos uma amostragem a partir dele. Projetaremos o sistema Hamiltoniano no subespaço amostrado e o diagonalizaremos para estimar a energia do estado fundamental. O algoritmo converge de forma comprovada e eficiente para o estado fundamental, de acordo com as suposições descritas na lição 2.\n",
        "\n",
        "<span id=\"0-the-krylov-space\" />\n",
        "\n",
        "## 0. O espaço de Krylov\n",
        "\n",
        "Lembre-se de que um espaço de Krylov $\\mathcal{K}^r$ de ordem $r$ é o espaço abrangido pelos vetores obtidos pela multiplicação das potências mais altas de uma matriz $A$, até $r-1$, com um vetor de referência $\\vert v \\rangle$.\n",
        "\n",
        "$$\n",
        "\\mathcal{K}^r = \\left\\{ \\vert v \\rangle, A \\vert v \\rangle, A^2 \\vert v \\rangle, ..., A^{r-1} \\vert v \\rangle \\right\\}\n",
        "$$\n",
        "\n",
        "Se a matriz $A$ for o Hamiltoniano $H$, o espaço correspondente será chamado de *espaço de Krylov de potência* $\\mathcal{K}_P$. No caso de $A$ ser o operador de evolução temporal gerado pelo Hamiltoniano $U=e^{-iH(dt)}$, o espaço é chamado de espaço de Krylov unitário $\\mathcal{K}_U$. O subespaço de Krylov de potência não pode ser gerado diretamente em um computador quântico, pois $H$ não é um operador unitário. Em vez disso, podemos usar o operador de evolução temporal $U = e^{-iH(dt)}$, que pode ser mostrado como [garantia de convergência](https://arxiv.org/abs/2110.07492) semelhante à do espaço de Krylov de potência. As potências de $U$ tornam-se, então, etapas de tempo diferentes $U^k = e^{-iH(k dt)}$ onde $k = 0, 1, 2, ..., (r-1)$.\n",
        "\n",
        "$$\n",
        "\\mathcal{K}_U^r = \\left\\{ \\vert \\psi \\rangle, U \\vert \\psi \\rangle, U^2 \\vert \\psi \\rangle, ..., U^{r-1} \\vert \\psi \\rangle \\right\\}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "864a0ce7-d094-48ea-9cf0-2a7e38791815",
      "metadata": {},
      "source": [
        "<span id=\"1-map-problem-to-quantum-circuits-and-operators\" />\n",
        "\n",
        "## 1. Mapear o problema para circuitos e operadores quânticos\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5888e3e8-51a1-426a-9023-c137aa9c6c83",
      "metadata": {},
      "source": [
        "Nesta lição, consideramos o Hamiltoniano para a cadeia antiferromagnética XX-Z spin-1/2 com $L = 22$ locais com a condição de limite periódico:\n",
        "\n",
        "$$\n",
        "    H = \\sum_{i, j}^{N} J_{xy} (X_{i} X_{j} + Y_{i} Y_{j}) + Z_{i} Z_{j}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "f0d3e153-17da-4457-b1d2-2a35d31aea3a",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import CouplingMap\n",
        "from qiskit_addon_utils.problem_generators import generate_xyz_hamiltonian\n",
        "\n",
        "num_spins = 22\n",
        "coupling_map = CouplingMap.from_ring(num_spins)\n",
        "H_op = generate_xyz_hamiltonian(coupling_map, coupling_constants=(0.3, 0.3, 1.0))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b0660e0d-5521-4095-a810-949729421b57",
      "metadata": {},
      "source": [
        "Para construir o espaço de Krylov, precisamos de três ingredientes principais:\n",
        "\n",
        "1. Uma opção de dimensão de Krylov ( $r$ ) e etapa de tempo ( $dt$ ).\n",
        "2. Um estado inicial (de referência) (vetor $\\vert v \\rangle$ acima) com sobreposição polinomial com o estado-alvo (solo), em que o estado-alvo é esparso. Esse requisito de sobreposição polinomial é o mesmo do algoritmo de estimativa de fase quântica.\n",
        "3. Operadores de evolução temporal $U^{k}=e^{-iH(k * dt)}$ ( $k = 0, 1, 2, ..., r-1$ ).\n",
        "\n",
        "Para um valor escolhido de $r$ (e, $dt$ ), criaremos $r$ circuitos quânticos separados e coletaremos amostras deles. Cada circuito quântico é criado unindo a representação do circuito quântico do estado de referência e o operador de evolução do tempo para um valor $k$.\n",
        "\n",
        "Uma dimensão de Krylov maior melhora a convergência da energia estimada. Nesta lição, definimos a dimensão como $5$ para ilustrar a tendência de convergência.\n",
        "\n",
        "A Ref [\\[2\\]](#references) mostrou que uma etapa de tempo suficientemente pequena para o KQD é $\\pi / \\vert \\vert H \\vert \\vert$, e que é preferível subestimar esse valor em vez de superestimá-lo. Por outro lado, escolher $dt$ para ser muito pequeno leva a um condicionamento pior do subespaço de Krylov, já que os vetores da base de Krylov diferem menos de um intervalo de tempo para outro. Além disso, embora essa escolha de $dt$ seja comprovadamente adequada para a convergência do SKQD, nesse contexto baseado em amostragem, a escolha ideal de $dt$ na prática é um tópico de estudo em andamento. Nesta lição, definimos $dt = 0.15$.\n",
        "\n",
        "Além da dimensão de Krylov e da etapa de tempo, precisamos definir o número de etapas de Trotter para a evolução do tempo. O uso de poucas etapas leva a erros de trotterização maiores, enquanto muitas etapas levam a circuitos mais profundos. Nesta lição, definimos o número de etapas de Trotter como $6$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "52eb15e3-e06c-4820-bad1-80fb7c05feee",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Set parameters for quantum Krylov algorithm\n",
        "krylov_dim = 5  # size of krylov subspace\n",
        "dt = 0.15\n",
        "num_trotter_steps = 6"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a716ea3e-b3d6-42de-8ed5-331e6416e586",
      "metadata": {},
      "source": [
        "Em seguida, precisamos escolher um estado de referência $\\vert \\psi \\rangle$ que tenha alguma sobreposição com o estado fundamental. Para esse hamiltoniano, usamos o estado *Neel* com alternância de 1s e 0s $\\vert ...101...010...101 \\rangle$ como nosso estado de referência.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "53347df7-b43c-4859-a9ea-a3dea2a44184",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Prep `Neel` state as the reference state for evolution\n",
        "from qiskit import QuantumCircuit\n",
        "\n",
        "qc_state_prep = QuantumCircuit(num_spins)\n",
        "for i in range(num_spins):\n",
        "    if i % 2 == 0:\n",
        "        qc_state_prep.x(i)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6952aaf2-c598-4ce9-8dc5-e63f0725de10",
      "metadata": {},
      "source": [
        "Por fim, precisamos mapear o operador de evolução temporal para um circuito quântico. Isso foi feito na lição 2, mas aqui utilizaremos os métodos do Qiskit, especificamente um método chamado *synthesis (síntese* ). Há diferentes métodos para sintetizar operadores matemáticos em circuitos quânticos com portas quânticas. Muitas dessas técnicas estão disponíveis no [módulo de síntese do Qiskit](/docs/api/qiskit/synthesis). Usaremos a abordagem [`LieTrotter`](/docs/api/qiskit/qiskit.synthesis.LieTrotter) abordagem para síntese [\\[3\\]](#references) [\\[4\\]](#references).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c82afe58-a90a-49a9-9dfe-c24b2b5d0a8c",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import QuantumRegister\n",
        "from qiskit.circuit.library import PauliEvolutionGate\n",
        "from qiskit.synthesis import LieTrotter\n",
        "\n",
        "evol_gate = PauliEvolutionGate(\n",
        "    H_op, time=(dt / num_trotter_steps), synthesis=LieTrotter(reps=num_trotter_steps)\n",
        ")  # `U` operator\n",
        "\n",
        "qr = QuantumRegister(num_spins)\n",
        "qc_evol = QuantumCircuit(qr)\n",
        "qc_evol.append(evol_gate, qargs=qr)\n",
        "\n",
        "circuits = []\n",
        "for rep in range(krylov_dim):\n",
        "    circ = qc_state_prep.copy()\n",
        "\n",
        "    # Repeating the `U` operator to implement U^0, U^1, U^2, and so on, for power Krylov space\n",
        "    for _ in range(rep):\n",
        "        circ.compose(other=qc_evol, inplace=True)\n",
        "\n",
        "    circ.measure_all()\n",
        "    circuits.append(circ)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "7ffc3eaa-9563-4c89-9d7b-808a3a37b275",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/quantum-diagonalization-algorithms/qda-5-skqd/extracted-outputs/7ffc3eaa-9563-4c89-9d7b-808a3a37b275-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "circuits[1].decompose().draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "bdbc0881-06b0-49f2-8919-a376aa7f08e3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/quantum-diagonalization-algorithms/qda-5-skqd/extracted-outputs/bdbc0881-06b0-49f2-8919-a376aa7f08e3-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "circuits[2].decompose().draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9b43f693-b6d0-43cb-b982-3f8a3b6e185d",
      "metadata": {},
      "source": [
        "<span id=\"2-optimize-for-target-hardware\" />\n",
        "\n",
        "## 2. Otimize para o hardware de destino\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6ed5a22f-4bdc-4a8d-ad39-5307308d0cc4",
      "metadata": {},
      "source": [
        "Agora que criamos os circuitos, podemos otimizá-los para um hardware de destino. Escolhemos uma QPU em escala de utilidade.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8944305a-0f29-4f97-a04f-43249cdc02ea",
      "metadata": {},
      "outputs": [],
      "source": [
        "import warnings\n",
        "\n",
        "from qiskit import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "warnings.filterwarnings(\"ignore\")\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "# Use the least-busy backend or specify a quantum computer using the syntax commented out below.\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "# backend = service.backend(\"ibm_brisbane\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3ed422ad-04f5-4f1f-a142-f08a0ac0a34b",
      "metadata": {},
      "source": [
        "Agora, transpilamos os circuitos para o backend de destino usando um gerenciador de passes predefinido.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "8a72b655-ccee-4927-8bf2-b99d0b92723a",
      "metadata": {},
      "outputs": [],
      "source": [
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=3)\n",
        "isa_circuits = pm.run(circuits=circuits)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6405ab01-5cec-4a02-8846-f9ba626d9cdc",
      "metadata": {},
      "source": [
        "<span id=\"3-execute-on-target-hardware\" />\n",
        "\n",
        "## 3. Executar no hardware de destino\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6aa67e8c-30db-4e11-9bf2-150c157ec49c",
      "metadata": {},
      "source": [
        "Depois de otimizar os circuitos para execução em hardware, estamos prontos para executá-los no hardware de destino e coletar amostras para a estimativa de energia do estado fundamental.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "0613c95b-e696-4ddb-8f51-dc1714d21a0e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime import SamplerV2 as Sampler\n",
        "\n",
        "sampler = Sampler(mode=backend)\n",
        "job = sampler.run(isa_circuits, shots=100_000)  # Takes approximately 2m 58s of QPU time"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "1c60e828-9359-46c6-84ef-88aecdb85b81",
      "metadata": {},
      "outputs": [],
      "source": [
        "counts_all = [job.result()[k].data.meas.get_counts() for k in range(krylov_dim)]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fa2fcfe0-66ab-4230-9262-9a46ecda034b",
      "metadata": {},
      "source": [
        "<span id=\"4-post-process-results\" />\n",
        "\n",
        "## 4. Resultados pós-processamento\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "75321a43-0740-4d13-bdc4-350b44727b62",
      "metadata": {},
      "source": [
        "Em seguida, agregamos as contagens para aumentar as dimensões de Krylov de forma cumulativa. Usando as contagens cumulativas, abrangeremos subespaços para aumentar a dimensão de Krylov e analisaremos o comportamento da convergência.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "9954125c-5ad8-40e8-affa-4a644354c51f",
      "metadata": {},
      "outputs": [],
      "source": [
        "from collections import Counter\n",
        "\n",
        "counts_cumulative = []\n",
        "for i in range(krylov_dim):\n",
        "    counter = Counter()\n",
        "    for d in counts_all[: i + 1]:\n",
        "        counter.update(d)\n",
        "\n",
        "    counts = dict(counter)\n",
        "    counts_cumulative.append(counts)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "14fcdfc2-b37e-4a9c-9794-7c1fa9a6ab1b",
      "metadata": {},
      "source": [
        "Para projetar e diagonalizar o Hamiltoniano, usamos os recursos de [`qiskit-addon-sqd`](https://qiskit.github.io/qiskit-addon-sqd/). O complemento oferece funcionalidades para projetar Hamiltonianos baseados em cadeias de Pauli em um subespaço e resolve os valores próprios usando `SciPy`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "5ace841d-59c6-4ea1-9ceb-6f6436546093",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_addon_sqd.counts import counts_to_arrays\n",
        "from qiskit_addon_sqd.qubit import solve_qubit"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "104cc0fd-4fa0-469b-bfb8-4089cea5145f",
      "metadata": {},
      "source": [
        "Em princípio, podemos filtrar as cadeias de bits com padrão incorreto antes de abranger o subespaço. Por exemplo, o estado fundamental do Hamiltoniano antiferromagnético desta lição normalmente tem um número igual de spins \"para cima\" e \"para baixo\", ou seja, o número de \"1 \"s na cadeia de bits deve ser exatamente a metade do número total de bits (spins) no sistema. A função a seguir filtra as cadeias de bits com o número incorreto de \"1\" das contagens.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 37,
      "id": "81d728a1-6ab4-4664-a7ca-2017dae10e1a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Filters out bitstrings that do not have specified number (`num_ones`) of `1` bits.\n",
        "def postselect_counts(counts, num_ones):\n",
        "    filtered_counts = {}\n",
        "    for bitstring, freq in counts.items():\n",
        "        if bitstring.count(\"1\") == num_ones:\n",
        "            filtered_counts[bitstring] = freq\n",
        "\n",
        "    return filtered_counts"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d77772f5-fe1c-4a6c-abcb-c2c3c7d7293a",
      "metadata": {},
      "source": [
        "Usando cadeias de bits com o número correto de elétrons para cima/para baixo, abrangemos subespaços e calculamos valores próprios para aumentar a dimensão de Krylov. Dependendo do tamanho do problema e dos recursos clássicos disponíveis, talvez seja necessário adotar a subamostragem (semelhante à [lição sobre SQD](/learning/courses/quantum-diagonalization-algorithms/sqd-implementation) ) para manter a dimensão do subespaço sob controle. Além disso, podemos aplicar a noção de recuperação de configuração semelhante à da Lição 4. Podemos computar a ocupação de elétrons por local a partir de estados próprios reconstruídos e usar as informações para corrigir cadeias de bits com um número incorreto de elétrons up/down. Deixamos isso como um exercício para os leitores interessados.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 38,
      "id": "f0e0f56f-ec56-40b6-b8be-059be35d2ce5",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "num_batches = 10\n",
        "rand_seed = 0\n",
        "scipy_kwargs = {\"k\": 2, \"which\": \"SA\"}\n",
        "\n",
        "ground_state_energies = []\n",
        "for idx, counts in enumerate(counts_cumulative):\n",
        "    counts = postselect_counts(counts, num_ones=num_spins // 2)\n",
        "    bitstring_matrix, probs = counts_to_arrays(counts=counts)\n",
        "\n",
        "    eigenvals, eigenstates = solve_qubit(\n",
        "        bitstring_matrix, H_op, verbose=False, **scipy_kwargs\n",
        "    )\n",
        "    gs_en = np.min(eigenvals)\n",
        "    ground_state_energies.append(gs_en)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "67b2a04b-4e70-45dc-bd21-2c4340c18377",
      "metadata": {},
      "source": [
        "Em seguida, plotamos a energia calculada como uma função da dimensão de Krylov e comparamos com a energia exata. A energia exata é calculada separadamente usando um método clássico de força bruta. Podemos ver que a energia estimada do estado fundamental converge com o aumento da dimensão do espaço de Krylov. Embora a dimensão de Krylov de $5$ seja limitante, os resultados ainda mostram uma convergência impressionante, que deve melhorar com uma dimensão de Krylov maior [\\[1\\]](#references).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 39,
      "id": "debca96a-e0e3-4342-a755-8204dba50d74",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/quantum-diagonalization-algorithms/qda-5-skqd/extracted-outputs/debca96a-e0e3-4342-a755-8204dba50d74-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "exact_gs_en = -23.934184\n",
        "plt.plot(\n",
        "    range(1, krylov_dim + 1),\n",
        "    ground_state_energies,\n",
        "    color=\"blue\",\n",
        "    linestyle=\"-.\",\n",
        "    label=\"estimate\",\n",
        ")\n",
        "plt.plot(\n",
        "    range(1, krylov_dim + 1),\n",
        "    [exact_gs_en] * krylov_dim,\n",
        "    color=\"red\",\n",
        "    linestyle=\"-\",\n",
        "    label=\"exact\",\n",
        ")\n",
        "plt.xticks(range(1, krylov_dim + 1), range(1, krylov_dim + 1))\n",
        "plt.legend()\n",
        "plt.xlabel(\"Krylov space dimension\")\n",
        "plt.ylabel(\"Energy\")\n",
        "plt.ylim([-24, -22.50])\n",
        "plt.title(\n",
        "    \"Estimating Ground state energy with Sample-based Krylov Quantum Diagonalization\"\n",
        ")\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5865567b-cc32-48dd-b7f9-32ce64d7dd7c",
      "metadata": {},
      "source": [
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### Verifique sua compreensão\n",
        "\n",
        "Leia as perguntas abaixo, reflita sobre suas respostas e clique nos triângulos para revelar as soluções.\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"O que poderia ser feito para melhorar a convergência no gráfico acima?\">\n",
        "    **Resposta:**\n",
        "\n",
        "    Aumentar a dimensão de Krylov. Em geral, também é possível aumentar o número de disparos, mas isso já é bastante alto no cálculo acima.\n",
        "  </AccordionItem>\n",
        "\n",
        "  <AccordionItem title=\"Quais são as principais vantagens do SKQD em relação ao (a) SQD e ao (b) KQD?\">\n",
        "    **Resposta:**\n",
        "\n",
        "    Pode haver outras respostas válidas, mas as respostas completas devem incluir o seguinte:\n",
        "\n",
        "    (a) O SKQD vem com garantias de convergência que o SQD não tem. Na SQD, você precisa fazer uma estimativa muito boa para o seu ansatz que tenha uma excelente sobreposição com o suporte do estado fundamental na base computacional, ou precisa introduzir um componente variacional no cálculo para obter uma amostra de uma família de ansatz.\n",
        "\n",
        "    (b) O SKQD requer muito menos tempo de QPU, pois evita o cálculo dispendioso dos elementos da matriz por meio do teste Hadamard.\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a4cf119d-65cf-456c-be0d-731bb7a6799a",
      "metadata": {},
      "source": [
        "<span id=\"5-summary\" />\n",
        "\n",
        "## 5. Resumo\n",
        "\n",
        "* As estimativas de energia do estado fundamental por meio da amostragem dos estados da base de Krylov são muito adequadas aos modelos de rede, incluindo sistemas de spin, problemas de matéria condensada e teorias de calibre de rede. Essa abordagem é muito melhor do que a VQE, porque não exige otimização de muitos parâmetros em um ansatz variacional, como na VQE, ou na SQD baseada em ansatz heurístico (por exemplo, o problema de química na lição anterior).\n",
        "  * Para manter a profundidade do circuito baixa, é aconselhável abordar problemas de rede que sejam passíveis de hardware tolerante a falhas.\n",
        "* O SKQD não incorre em um problema de medição quântica como no VQE. Não há grupos de operadores Pauli comutantes a serem estimados.\n",
        "* O SKQD é resistente a amostras ruidosas, pois é possível utilizar uma rotina de pós-seleção específica para o problema (por exemplo, filtrar cadeias de bits que não se enquadram nos padrões específicos do problema) ou incorrer na sobrecarga clássica da diagonalização (ou seja, diagonalizar em um subespaço maior) para eliminar efetivamente o efeito do ruído.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c52bada7-1912-41f2-a770-3145a947de63",
      "metadata": {},
      "source": [
        "<span id=\"references\" />\n",
        "\n",
        "## Referências\n",
        "\n",
        "\\[1] Jeffery Yu et al, \"Algoritmo centrado em quantum para diagonalização de Krylov baseada em amostra\" (2025). [arxiv:quant-ph/2501.09702](https://arxiv.org/abs/2501.09702).\n",
        "\n",
        "\\[2] Ethan N. Epperly, Lin Lin e Yuji Nakatsukasa. \"Uma teoria da diagonalização do subespaço quântico\". SIAM Journal on Matrix Analysis and Applications 43, 1263-1290 (2022).\n",
        "\n",
        "\\[2] N. Hatano e M. Suzuki, \"Finding Exponential Product Formulas of Higher Orders\" (2005). [arXiv:math-ph/0506007](https://arxiv.org/abs/math-ph/0506007).\n",
        "\n",
        "\\[4] D. Berry, G. Ahokas, R. Cleve e B. Sanders, \"Efficient quantum algorithms for simulating sparse Hamiltonians\" (Algoritmos quânticos eficientes para simular hamiltonianos esparsos) (2006). [arXiv:quant-ph/0508139](https://arxiv.org/abs/quant-ph/0508139).\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
}