Switch to unified view

a b/Code/All PennyLane QML Demos/18 Many Body 208.1s kkawchak.ipynb
1
{
2
 "cells": [
3
  {
4
   "cell_type": "code",
5
   "execution_count": 43,
6
   "metadata": {
7
    "id": "in3VVDRqlMUE",
8
    "tags": []
9
   },
10
   "outputs": [
11
    {
12
     "name": "stdout",
13
     "output_type": "stream",
14
     "text": [
15
      "Time in seconds since beginning of run: 1693283058.6479008\n",
16
      "Tue Aug 29 04:24:18 2023\n"
17
     ]
18
    }
19
   ],
20
   "source": [
21
    "# This cell is added by sphinx-gallery\n",
22
    "# It can be customized to whatever you like\n",
23
    "%matplotlib inline\n",
24
    "# !pip install pennylane\n",
25
    "# !pip install neural_tangents\n",
26
    "# !pip install networkx\n",
27
    "import time\n",
28
    "seconds = time.time()\n",
29
    "print(\"Time in seconds since beginning of run:\", seconds)\n",
30
    "local_time = time.ctime(seconds)\n",
31
    "print(local_time)"
32
   ]
33
  },
34
  {
35
   "cell_type": "markdown",
36
   "metadata": {
37
    "id": "cfjAkbwNlMUF"
38
   },
39
   "source": [
40
    "Machine learning for quantum many-body problems\n",
41
    "===============================================\n",
42
    "\n",
43
    "::: {.meta}\n",
44
    ":property=\\\"og:description\\\": Machine learning for many-body problems\n",
45
    ":property=\\\"og:image\\\":\n",
46
    "<https://pennylane.ai/qml/_images/ml_classical_shadow.png>\n",
47
    ":::\n",
48
    "\n",
49
    "::: {.related}\n",
50
    "tutorial\\_classical\\_shadows Classical Shadows\n",
51
    "tutorial\\_kernel\\_based\\_training Kernel-based training with\n",
52
    "scikit-learn tutorial\\_kernels\\_module Training and evaluating quantum\n",
53
    "kernels\n",
54
    ":::\n",
55
    "\n",
56
    "*Author: Utkarsh Azad --- Posted: 02 May 2022. Last Updated: 09 May\n",
57
    "2022*\n",
58
    "\n",
59
    "Storing and processing a complete description of an $n$-qubit quantum\n",
60
    "mechanical system is challenging because the amount of memory required\n",
61
    "generally scales exponentially with the number of qubits. The quantum\n",
62
    "community has recently addressed this challenge by using the\n",
63
    "`classical shadow <tutorial_classical_shadows>`{.interpreted-text\n",
64
    "role=\"doc\"} formalism, which allows us to build more concise classical\n",
65
    "descriptions of quantum states using randomized single-qubit\n",
66
    "measurements. It was argued in Ref. that combining classical shadows\n",
67
    "with classical machine learning enables using learning models that\n",
68
    "efficiently predict properties of the quantum systems, such as the\n",
69
    "expectation value of a Hamiltonian, correlation functions, and\n",
70
    "entanglement entropies.\n",
71
    "\n",
72
    "![Combining machine learning and classical\n",
73
    "shadows](/demonstrations/ml_classical_shadows/class_shadow_ml.png){.align-center\n",
74
    "width=\"80.0%\"}\n",
75
    "\n",
76
    "In this demo, we describe one of the ideas presented in Ref. for using\n",
77
    "classical shadow formalism and machine learning to predict the\n",
78
    "ground-state properties of the 2D antiferromagnetic Heisenberg model. We\n",
79
    "begin by learning how to build the Heisenberg model, calculate its\n",
80
    "ground-state properties, and compute its classical shadow. Finally, we\n",
81
    "demonstrate how to use\n",
82
    "`kernel-based learning models <tutorial_kernels_module>`{.interpreted-text\n",
83
    "role=\"doc\"} to predict ground-state properties from the learned\n",
84
    "classical shadows. So let\\'s get started!\n",
85
    "\n",
86
    "Building the 2D Heisenberg Model\n",
87
    "--------------------------------\n",
88
    "\n",
89
    "We define a two-dimensional antiferromagnetic [Heisenberg\n",
90
    "model](https://en.wikipedia.org/wiki/Quantum_Heisenberg_model) as a\n",
91
    "square lattice, where a spin-1/2 particle occupies each site. The\n",
92
    "antiferromagnetic nature and the overall physics of this model depend on\n",
93
    "the couplings $J_{ij}$ present between the spins, as reflected in the\n",
94
    "Hamiltonian associated with the model:\n",
95
    "\n",
96
    "$$H = \\sum_{i < j} J_{ij}(X_i X_j + Y_i Y_j + Z_i Z_j) .$$\n",
97
    "\n",
98
    "Here, we consider the family of Hamiltonians where all the couplings\n",
99
    "$J_{ij}$ are sampled uniformly from \\[0, 2\\]. We build a coupling matrix\n",
100
    "$J$ by providing the number of rows $N_r$ and columns $N_c$ present in\n",
101
    "the square lattice. The dimensions of this matrix are $N_s \\times N_s$,\n",
102
    "where $N_s = N_r \\times N_c$ is the total number of spin particles\n",
103
    "present in the model.\n"
104
   ]
105
  },
106
  {
107
   "cell_type": "code",
108
   "execution_count": 44,
109
   "metadata": {
110
    "id": "LWfXJdIBlMUG"
111
   },
112
   "outputs": [],
113
   "source": [
114
    "import itertools as it\n",
115
    "import pennylane.numpy as np\n",
116
    "import numpy as anp\n",
117
    "\n",
118
    "def build_coupling_mats(num_mats, num_rows, num_cols):\n",
119
    "    num_spins = num_rows * num_cols\n",
120
    "    coupling_mats = np.zeros((num_mats, num_spins, num_spins))\n",
121
    "    coup_terms = anp.random.RandomState(24).uniform(0, 2,\n",
122
    "                        size=(num_mats, 2 * num_rows * num_cols - num_rows - num_cols))\n",
123
    "    # populate edges to build the grid lattice\n",
124
    "    edges = [(si, sj) for (si, sj) in it.combinations(range(num_spins), 2)\n",
125
    "                        if sj % num_cols and sj - si == 1 or sj - si == num_cols]\n",
126
    "    for itr in range(num_mats):\n",
127
    "        for ((i, j), term) in zip(edges, coup_terms[itr]):\n",
128
    "            coupling_mats[itr][i][j] = coupling_mats[itr][j][i] = term\n",
129
    "    return coupling_mats"
130
   ]
131
  },
132
  {
133
   "cell_type": "markdown",
134
   "metadata": {
135
    "id": "ZV-J9mFJlMUG"
136
   },
137
   "source": [
138
    "For this demo, we study a model with four spins arranged on the nodes of\n",
139
    "a square lattice. We require four qubits for simulating this model; one\n",
140
    "qubit for each spin. We start by building a coupling matrix `J_mat`\n",
141
    "using our previously defined function.\n"
142
   ]
143
  },
144
  {
145
   "cell_type": "code",
146
   "execution_count": 45,
147
   "metadata": {
148
    "id": "GSqBR9p2lMUG"
149
   },
150
   "outputs": [],
151
   "source": [
152
    "Nr, Nc = 2, 2\n",
153
    "num_qubits = Nr * Nc  # Ns\n",
154
    "J_mat = build_coupling_mats(1, Nr, Nc)[0]"
155
   ]
156
  },
157
  {
158
   "cell_type": "markdown",
159
   "metadata": {
160
    "id": "LMJScKXHlMUG"
161
   },
162
   "source": [
163
    "We can now visualize the model instance by representing the coupling\n",
164
    "matrix as a `networkx` graph:\n"
165
   ]
166
  },
167
  {
168
   "cell_type": "code",
169
   "execution_count": 46,
170
   "metadata": {
171
    "colab": {
172
     "base_uri": "https://localhost:8080/",
173
     "height": 254
174
    },
175
    "id": "PnCxl2OUlMUH",
176
    "outputId": "8383df52-8539-489f-edfc-3064c3cf6eb0"
177
   },
178
   "outputs": [
179
    {
180
     "data": {
181
      "image/png": "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\n",
182
      "text/plain": [
183
       "<Figure size 400x400 with 1 Axes>"
184
      ]
185
     },
186
     "metadata": {},
187
     "output_type": "display_data"
188
    }
189
   ],
190
   "source": [
191
    "import matplotlib.pyplot as plt\n",
192
    "import networkx as nx\n",
193
    "\n",
194
    "G = nx.from_numpy_matrix(np.matrix(J_mat), create_using=nx.DiGraph)\n",
195
    "pos = {i: (i % Nc, -(i // Nc)) for i in G.nodes()}\n",
196
    "edge_labels = {(x, y): np.round(J_mat[x, y], 2) for x, y in G.edges()}\n",
197
    "weights = [x + 1.5 for x in list(nx.get_edge_attributes(G, \"weight\").values())]\n",
198
    "\n",
199
    "plt.figure(figsize=(4, 4))\n",
200
    "nx.draw(\n",
201
    "    G, pos, node_color=\"lightblue\", with_labels=True,\n",
202
    "    node_size=600, width=weights, edge_color=\"firebrick\",\n",
203
    ")\n",
204
    "nx.draw_networkx_edge_labels(G, pos=pos, edge_labels=edge_labels)\n",
205
    "plt.show()"
206
   ]
207
  },
208
  {
209
   "cell_type": "markdown",
210
   "metadata": {
211
    "id": "t0E6JAIIlMUH"
212
   },
213
   "source": [
214
    "We then use the same coupling matrix `J_mat` to obtain the Hamiltonian\n",
215
    "$H$ for the model we have instantiated above.\n"
216
   ]
217
  },
218
  {
219
   "cell_type": "code",
220
   "execution_count": 47,
221
   "metadata": {
222
    "colab": {
223
     "base_uri": "https://localhost:8080/",
224
     "height": 0
225
    },
226
    "id": "A_XDopwwlMUH",
227
    "outputId": "adc70e0d-9aa5-4011-b669-1ef80c5451cd"
228
   },
229
   "outputs": [
230
    {
231
     "name": "stdout",
232
     "output_type": "stream",
233
     "text": [
234
      "Hamiltonian =\n",
235
      "  (0.44013459956570355) [X2 X3]\n",
236
      "+ (0.44013459956570355) [Y2 Y3]\n",
237
      "+ (0.44013459956570355) [Z2 Z3]\n",
238
      "+ (1.399024099899152) [X0 X2]\n",
239
      "+ (1.399024099899152) [Y0 Y2]\n",
240
      "+ (1.399024099899152) [Z0 Z2]\n",
241
      "+ (1.920034606671837) [X0 X1]\n",
242
      "+ (1.920034606671837) [Y0 Y1]\n",
243
      "+ (1.920034606671837) [Z0 Z1]\n",
244
      "+ (1.9997345852477584) [X1 X3]\n",
245
      "+ (1.9997345852477584) [Y1 Y3]\n",
246
      "+ (1.9997345852477584) [Z1 Z3]\n"
247
     ]
248
    }
249
   ],
250
   "source": [
251
    "import pennylane as qml\n",
252
    "\n",
253
    "def Hamiltonian(J_mat):\n",
254
    "    coeffs, ops = [], []\n",
255
    "    ns = J_mat.shape[0]\n",
256
    "    for i, j in it.combinations(range(ns), r=2):\n",
257
    "        coeff = J_mat[i, j]\n",
258
    "        if coeff:\n",
259
    "            for op in [qml.PauliX, qml.PauliY, qml.PauliZ]:\n",
260
    "                coeffs.append(coeff)\n",
261
    "                ops.append(op(i) @ op(j))\n",
262
    "    H = qml.Hamiltonian(coeffs, ops)\n",
263
    "    return H\n",
264
    "\n",
265
    "print(f\"Hamiltonian =\\n{Hamiltonian(J_mat)}\")"
266
   ]
267
  },
268
  {
269
   "cell_type": "markdown",
270
   "metadata": {
271
    "id": "JD6aZtNilMUH"
272
   },
273
   "source": [
274
    "For the Heisenberg model, a property of interest is usually the two-body\n",
275
    "correlation function $C_{ij}$, which for a pair of spins $i$ and $j$ is\n",
276
    "defined as the following operator:\n",
277
    "\n",
278
    "$$\\hat{C}_{ij} = \\frac{1}{3} (X_i X_j + Y_iY_j + Z_iZ_j).$$\n"
279
   ]
280
  },
281
  {
282
   "cell_type": "code",
283
   "execution_count": 48,
284
   "metadata": {
285
    "id": "UVBY4jUglMUH"
286
   },
287
   "outputs": [],
288
   "source": [
289
    "def corr_function(i, j):\n",
290
    "    ops = []\n",
291
    "    for op in [qml.PauliX, qml.PauliY, qml.PauliZ]:\n",
292
    "        if i != j:\n",
293
    "            ops.append(op(i) @ op(j))\n",
294
    "        else:\n",
295
    "            ops.append(qml.Identity(i))\n",
296
    "    return ops"
297
   ]
298
  },
299
  {
300
   "cell_type": "markdown",
301
   "metadata": {
302
    "id": "O0-ZNiNXlMUH"
303
   },
304
   "source": [
305
    "The expectation value of each such operator $\\hat{C}_{ij}$ with respect\n",
306
    "to the ground state $|\\psi_{0}\\rangle$ of the model can be used to build\n",
307
    "the correlation matrix $C$:\n",
308
    "\n",
309
    "$${C}_{ij} = \\langle \\hat{C}_{ij} \\rangle = \\frac{1}{3} \\langle \\psi_{0} | X_i X_j + Y_iY_j + Z_iZ_j | \\psi_{0} \\rangle .$$\n"
310
   ]
311
  },
312
  {
313
   "cell_type": "markdown",
314
   "metadata": {
315
    "id": "VhgAsFyJlMUH"
316
   },
317
   "source": [
318
    "Hence, to build $C$ for the model, we need to calculate its ground state\n",
319
    "$|\\psi_{0}\\rangle$. We do this by diagonalizing the Hamiltonian for the\n",
320
    "model. Then, we obtain the eigenvector corresponding to the smallest\n",
321
    "eigenvalue.\n"
322
   ]
323
  },
324
  {
325
   "cell_type": "code",
326
   "execution_count": 49,
327
   "metadata": {
328
    "id": "W-r82wjjlMUH"
329
   },
330
   "outputs": [],
331
   "source": [
332
    "import scipy as sp\n",
333
    "\n",
334
    "ham = Hamiltonian(J_mat)\n",
335
    "eigvals, eigvecs = sp.sparse.linalg.eigs(ham.sparse_matrix())\n",
336
    "psi0 = eigvecs[:, np.argmin(eigvals)]"
337
   ]
338
  },
339
  {
340
   "cell_type": "markdown",
341
   "metadata": {
342
    "id": "Bft7PBtVlMUH"
343
   },
344
   "source": [
345
    "We then build a circuit that initializes the qubits into the ground\n",
346
    "state and measures the expectation value of the provided set of\n",
347
    "observables.\n"
348
   ]
349
  },
350
  {
351
   "cell_type": "code",
352
   "execution_count": 50,
353
   "metadata": {
354
    "id": "aMmNdfzAlMUH"
355
   },
356
   "outputs": [],
357
   "source": [
358
    "dev_exact = qml.device(\"lightning.qubit\", wires=num_qubits) # for exact simulation\n",
359
    "\n",
360
    "def circuit(psi, observables):\n",
361
    "    psi = psi / np.linalg.norm(psi) # normalize the state\n",
362
    "    qml.QubitStateVector(psi, wires=range(num_qubits))\n",
363
    "    return [qml.expval(o) for o in observables]\n",
364
    "\n",
365
    "circuit_exact = qml.QNode(circuit, dev_exact)"
366
   ]
367
  },
368
  {
369
   "cell_type": "markdown",
370
   "metadata": {
371
    "id": "7_OTMOuMlMUH"
372
   },
373
   "source": [
374
    "Finally, we execute this circuit to obtain the exact correlation matrix\n",
375
    "$C$. We compute the correlation operators $\\hat{C}_{ij}$ and their\n",
376
    "expectation values with respect to the ground state $|\\psi_0\\rangle$.\n"
377
   ]
378
  },
379
  {
380
   "cell_type": "code",
381
   "execution_count": 51,
382
   "metadata": {
383
    "id": "M2SqFe0IlMUI"
384
   },
385
   "outputs": [],
386
   "source": [
387
    "coups = list(it.product(range(num_qubits), repeat=2))\n",
388
    "corrs = [corr_function(i, j) for i, j in coups]\n",
389
    "\n",
390
    "def build_exact_corrmat(coups, corrs, circuit, psi):\n",
391
    "    corr_mat_exact = np.zeros((num_qubits, num_qubits))\n",
392
    "    for idx, (i, j) in enumerate(coups):\n",
393
    "        corr = corrs[idx]\n",
394
    "        if i == j:\n",
395
    "            corr_mat_exact[i][j] = 1.0\n",
396
    "        else:\n",
397
    "            corr_mat_exact[i][j] = (\n",
398
    "                np.sum(np.array([circuit(psi, observables=[o]) for o in corr]).T) / 3\n",
399
    "            )\n",
400
    "            corr_mat_exact[j][i] = corr_mat_exact[i][j]\n",
401
    "    return corr_mat_exact\n",
402
    "\n",
403
    "expval_exact = build_exact_corrmat(coups, corrs, circuit_exact, psi0)"
404
   ]
405
  },
406
  {
407
   "cell_type": "markdown",
408
   "metadata": {
409
    "id": "wRhl6GSvlMUI"
410
   },
411
   "source": [
412
    "Once built, we can visualize the correlation matrix:\n"
413
   ]
414
  },
415
  {
416
   "cell_type": "code",
417
   "execution_count": 52,
418
   "metadata": {
419
    "colab": {
420
     "base_uri": "https://localhost:8080/",
421
     "height": 337
422
    },
423
    "id": "elPohZB_lMUI",
424
    "outputId": "de61464c-fc27-4900-bd66-880b847547f7"
425
   },
426
   "outputs": [
427
    {
428
     "data": {
429
      "image/png": "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\n",
430
      "text/plain": [
431
       "<Figure size 400x400 with 2 Axes>"
432
      ]
433
     },
434
     "metadata": {},
435
     "output_type": "display_data"
436
    }
437
   ],
438
   "source": [
439
    "fig, ax = plt.subplots(1, 1, figsize=(4, 4))\n",
440
    "im = ax.imshow(expval_exact, cmap=plt.get_cmap(\"RdBu\"), vmin=-1, vmax=1)\n",
441
    "ax.xaxis.set_ticks(range(num_qubits))\n",
442
    "ax.yaxis.set_ticks(range(num_qubits))\n",
443
    "ax.xaxis.set_tick_params(labelsize=14)\n",
444
    "ax.yaxis.set_tick_params(labelsize=14)\n",
445
    "ax.set_title(\"Exact Correlation Matrix\", fontsize=14)\n",
446
    "\n",
447
    "bar = fig.colorbar(im, pad=0.05, shrink=0.80    )\n",
448
    "bar.set_label(r\"$C_{ij}$\", fontsize=14, rotation=0)\n",
449
    "bar.ax.tick_params(labelsize=14)\n",
450
    "plt.show()"
451
   ]
452
  },
453
  {
454
   "cell_type": "markdown",
455
   "metadata": {
456
    "id": "X7AxsPAnlMUI"
457
   },
458
   "source": [
459
    "Constructing Classical Shadows\n",
460
    "==============================\n"
461
   ]
462
  },
463
  {
464
   "cell_type": "markdown",
465
   "metadata": {
466
    "id": "NTPT4XUFlMUI"
467
   },
468
   "source": [
469
    "Now that we have built the Heisenberg model, the next step is to\n",
470
    "construct a\n",
471
    "`classical shadow <tutorial_classical_shadows>`{.interpreted-text\n",
472
    "role=\"doc\"} representation for its ground state. To construct an\n",
473
    "approximate classical representation of an $n$-qubit quantum state\n",
474
    "$\\rho$, we perform randomized single-qubit measurements on $T$-copies of\n",
475
    "$\\rho$. Each measurement is chosen randomly among the Pauli bases $X$,\n",
476
    "$Y$, or $Z$ to yield random $n$ pure product states $|s_i\\rangle$ for\n",
477
    "each copy:\n",
478
    "\n",
479
    "$$|s_{i}^{(t)}\\rangle \\in \\{|0\\rangle, |1\\rangle, |+\\rangle, |-\\rangle, |i+\\rangle, |i-\\rangle\\}.$$\n",
480
    "\n",
481
    "$$S_T(\\rho) = \\big\\{|s_{i}^{(t)}\\rangle: i\\in\\{1,\\ldots, n\\},\\ t\\in\\{1,\\ldots, T\\} \\big\\}.$$\n",
482
    "\n",
483
    "Each of the $|s_i^{(t)}\\rangle$ provides us with a snapshot of the state\n",
484
    "$\\rho$, and the $nT$ measurements yield the complete set $S_{T}$, which\n",
485
    "requires just $3nT$ bits to be stored in classical memory. This is\n",
486
    "discussed in further detail in our previous demo about\n",
487
    "`classical shadows <tutorial_classical_shadows>`{.interpreted-text\n",
488
    "role=\"doc\"}.\n"
489
   ]
490
  },
491
  {
492
   "cell_type": "markdown",
493
   "metadata": {
494
    "id": "voRlU_8blMUI"
495
   },
496
   "source": [
497
    "![](/demonstrations/ml_classical_shadows/class_shadow_prep.png){.align-center\n",
498
    "width=\"100.0%\"}\n"
499
   ]
500
  },
501
  {
502
   "cell_type": "markdown",
503
   "metadata": {
504
    "id": "nJd4CxtClMUI"
505
   },
506
   "source": [
507
    "To prepare a classical shadow for the ground state of the Heisenberg\n",
508
    "model, we simply reuse the circuit template used above and reconstruct a\n",
509
    "`QNode` utilizing a device that performs single-shot measurements.\n"
510
   ]
511
  },
512
  {
513
   "cell_type": "code",
514
   "execution_count": 53,
515
   "metadata": {
516
    "id": "puR1Cx8WlMUI"
517
   },
518
   "outputs": [],
519
   "source": [
520
    "dev_oshot = qml.device(\"lightning.qubit\", wires=num_qubits, shots=1)\n",
521
    "circuit_oshot = qml.QNode(circuit, dev_oshot)"
522
   ]
523
  },
524
  {
525
   "cell_type": "markdown",
526
   "metadata": {
527
    "id": "729nluzslMUI"
528
   },
529
   "source": [
530
    "Now, we define a function to build the classical shadow for the quantum\n",
531
    "state prepared by a given $n$-qubit circuit using $T$-copies of\n",
532
    "randomized Pauli basis measurements\n"
533
   ]
534
  },
535
  {
536
   "cell_type": "code",
537
   "execution_count": 54,
538
   "metadata": {
539
    "colab": {
540
     "base_uri": "https://localhost:8080/",
541
     "height": 0
542
    },
543
    "id": "2lKMEDwRlMUI",
544
    "outputId": "73e9bbda-afdd-4cee-fce0-2c611ca063e7"
545
   },
546
   "outputs": [
547
    {
548
     "name": "stdout",
549
     "output_type": "stream",
550
     "text": [
551
      "First five measurement outcomes =\n",
552
      " [[-1.  1.  1. -1.]\n",
553
      " [ 1. -1. -1.  1.]\n",
554
      " [ 1. -1. -1.  1.]\n",
555
      " [ 1.  1.  1. -1.]\n",
556
      " [-1. -1. -1.  1.]]\n",
557
      "First five measurement bases =\n",
558
      " [[2 2 2 1]\n",
559
      " [0 1 0 0]\n",
560
      " [2 2 2 2]\n",
561
      " [1 2 2 2]\n",
562
      " [1 2 2 1]]\n"
563
     ]
564
    }
565
   ],
566
   "source": [
567
    "def gen_class_shadow(circ_template, circuit_params, num_shadows, num_qubits):\n",
568
    "    # prepare the complete set of available Pauli operators\n",
569
    "    unitary_ops = [qml.PauliX, qml.PauliY, qml.PauliZ]\n",
570
    "    # sample random Pauli measurements uniformly\n",
571
    "    unitary_ensmb = np.random.randint(0, 3, size=(num_shadows, num_qubits), dtype=int)\n",
572
    "\n",
573
    "    outcomes = np.zeros((num_shadows, num_qubits))\n",
574
    "    for ns in range(num_shadows):\n",
575
    "        # for each snapshot, extract the Pauli basis measurement to be performed\n",
576
    "        meas_obs = [unitary_ops[unitary_ensmb[ns, i]](i) for i in range(num_qubits)]\n",
577
    "        # perform single shot randomized Pauli measuremnt for each qubit\n",
578
    "        outcomes[ns, :] = circ_template(circuit_params, observables=meas_obs)\n",
579
    "\n",
580
    "    return outcomes, unitary_ensmb\n",
581
    "\n",
582
    "\n",
583
    "outcomes, basis = gen_class_shadow(circuit_oshot, psi0, 100, num_qubits)\n",
584
    "print(\"First five measurement outcomes =\\n\", outcomes[:5])\n",
585
    "print(\"First five measurement bases =\\n\", basis[:5])"
586
   ]
587
  },
588
  {
589
   "cell_type": "markdown",
590
   "metadata": {
591
    "id": "aM9kSgoElMUI"
592
   },
593
   "source": [
594
    "Furthermore, $S_{T}$ can be used to construct an approximation of the\n",
595
    "underlying $n$-qubit state $\\rho$ by averaging over $\\sigma_t$:\n",
596
    "\n",
597
    "$$\\sigma_T(\\rho) = \\frac{1}{T} \\sum_{1}^{T} \\big(3|s_{1}^{(t)}\\rangle\\langle s_1^{(t)}| - \\mathbb{I}\\big)\\otimes \\ldots \\otimes \\big(3|s_{n}^{(t)}\\rangle\\langle s_n^{(t)}| - \\mathbb{I}\\big).$$\n"
598
   ]
599
  },
600
  {
601
   "cell_type": "code",
602
   "execution_count": 55,
603
   "metadata": {
604
    "id": "uhlXzt7IlMUI"
605
   },
606
   "outputs": [],
607
   "source": [
608
    "def snapshot_state(meas_list, obs_list):\n",
609
    "    # undo the rotations done for performing Pauli measurements in the specific basis\n",
610
    "    rotations = [\n",
611
    "        qml.matrix(qml.Hadamard(wires=0)), # X-basis\n",
612
    "        qml.matrix(qml.Hadamard(wires=0)) @ qml.matrix(qml.adjoint(qml.S(wires=0))), # Y-basis\n",
613
    "        qml.matrix(qml.Identity(wires=0)), # Z-basis\n",
614
    "    ]\n",
615
    "\n",
616
    "    # reconstruct snapshot from local Pauli measurements\n",
617
    "    rho_snapshot = [1]\n",
618
    "    for meas_out, basis in zip(meas_list, obs_list):\n",
619
    "        # preparing state |s_i><s_i| using the post measurement outcome:\n",
620
    "        # |0><0| for 1 and |1><1| for -1\n",
621
    "        state = np.array([[1, 0], [0, 0]]) if meas_out == 1 else np.array([[0, 0], [0, 1]])\n",
622
    "        local_rho = 3 * (rotations[basis].conj().T @ state @ rotations[basis]) - np.eye(2)\n",
623
    "        rho_snapshot = np.kron(rho_snapshot, local_rho)\n",
624
    "\n",
625
    "    return rho_snapshot\n",
626
    "\n",
627
    "def shadow_state_reconst(shadow):\n",
628
    "    num_snapshots, num_qubits = shadow[0].shape\n",
629
    "    meas_lists, obs_lists = shadow\n",
630
    "\n",
631
    "    # Reconstruct the quantum state from its classical shadow\n",
632
    "    shadow_rho = np.zeros((2 ** num_qubits, 2 ** num_qubits), dtype=complex)\n",
633
    "    for i in range(num_snapshots):\n",
634
    "        shadow_rho += snapshot_state(meas_lists[i], obs_lists[i])\n",
635
    "\n",
636
    "    return shadow_rho / num_snapshots"
637
   ]
638
  },
639
  {
640
   "cell_type": "markdown",
641
   "metadata": {
642
    "id": "wB7CZQJXlMUI"
643
   },
644
   "source": [
645
    "To see how well the reconstruction works for different values of $T$, we\n",
646
    "look at the\n",
647
    "[fidelity](https://en.wikipedia.org/wiki/Fidelity_of_quantum_states) of\n",
648
    "the actual quantum state with respect to the reconstructed quantum state\n",
649
    "from the classical shadow with $T$ copies. On average, as the number of\n",
650
    "copies $T$ is increased, the reconstruction becomes more effective with\n",
651
    "average higher fidelity values (orange) and lower variance (blue).\n",
652
    "Eventually, in the limit $T\\rightarrow\\infty$, the reconstruction will\n",
653
    "be exact.\n",
654
    "\n",
655
    "![Fidelity of the reconstructed ground state with different shadow sizes\n",
656
    "$T$](/demonstrations/ml_classical_shadows/fidel_snapshot.png){.align-center\n",
657
    "width=\"80.0%\"}\n"
658
   ]
659
  },
660
  {
661
   "cell_type": "markdown",
662
   "metadata": {
663
    "id": "KuzuhucBlMUI"
664
   },
665
   "source": [
666
    "The reconstructed quantum state $\\sigma_T$ can also be used to evaluate\n",
667
    "expectation values $\\text{Tr}(O\\sigma_T)$ for some localized observable\n",
668
    "$O = \\bigotimes_{i}^{n} P_i$, where $P_i \\in \\{I, X, Y, Z\\}$. However,\n",
669
    "as shown above, $\\sigma_T$ would be only an approximation of $\\rho$ for\n",
670
    "finite values of $T$. Therefore, to estimate $\\langle O \\rangle$\n",
671
    "robustly, we use the median of means estimation. For this purpose, we\n",
672
    "split up the $T$ shadows into $K$ equally-sized groups and evaluate the\n",
673
    "median of the mean value of $\\langle O \\rangle$ for each of these\n",
674
    "groups.\n"
675
   ]
676
  },
677
  {
678
   "cell_type": "code",
679
   "execution_count": 56,
680
   "metadata": {
681
    "id": "29rEs_S1lMUI"
682
   },
683
   "outputs": [],
684
   "source": [
685
    "def estimate_shadow_obs(shadow, observable, k=10):\n",
686
    "    shadow_size = shadow[0].shape[0]\n",
687
    "\n",
688
    "    # convert Pennylane observables to indices\n",
689
    "    map_name_to_int = {\"PauliX\": 0, \"PauliY\": 1, \"PauliZ\": 2}\n",
690
    "    if isinstance(observable, (qml.PauliX, qml.PauliY, qml.PauliZ)):\n",
691
    "        target_obs = np.array([map_name_to_int[observable.name]])\n",
692
    "        target_locs = np.array([observable.wires[0]])\n",
693
    "    else:\n",
694
    "        target_obs = np.array([map_name_to_int[o.name] for o in observable.obs])\n",
695
    "        target_locs = np.array([o.wires[0] for o in observable.obs])\n",
696
    "\n",
697
    "    # perform median of means to return the result\n",
698
    "    means = []\n",
699
    "    meas_list, obs_lists = shadow\n",
700
    "    for i in range(0, shadow_size, shadow_size // k):\n",
701
    "        meas_list_k, obs_lists_k = (\n",
702
    "            meas_list[i : i + shadow_size // k],\n",
703
    "            obs_lists[i : i + shadow_size // k],\n",
704
    "        )\n",
705
    "        indices = np.all(obs_lists_k[:, target_locs] == target_obs, axis=1)\n",
706
    "        if sum(indices):\n",
707
    "            means.append(\n",
708
    "                np.sum(np.prod(meas_list_k[indices][:, target_locs], axis=1)) / sum(indices)\n",
709
    "            )\n",
710
    "        else:\n",
711
    "            means.append(0)\n",
712
    "\n",
713
    "    return np.median(means)"
714
   ]
715
  },
716
  {
717
   "cell_type": "markdown",
718
   "metadata": {
719
    "id": "MJrMeks1lMUI"
720
   },
721
   "source": [
722
    "Now we estimate the correlation matrix $C^{\\prime}$ from the classical\n",
723
    "shadow approximation of the ground state.\n"
724
   ]
725
  },
726
  {
727
   "cell_type": "code",
728
   "execution_count": 57,
729
   "metadata": {
730
    "id": "rjSaQJwYlMUI"
731
   },
732
   "outputs": [],
733
   "source": [
734
    "coups = list(it.product(range(num_qubits), repeat=2))\n",
735
    "corrs = [corr_function(i, j) for i, j in coups]\n",
736
    "qbobs = [qob for qobs in corrs for qob in qobs]\n",
737
    "\n",
738
    "def build_estim_corrmat(coups, corrs, num_obs, shadow):\n",
739
    "    k = int(2 * np.log(2 * num_obs)) # group size\n",
740
    "    corr_mat_estim = np.zeros((num_qubits, num_qubits))\n",
741
    "    for idx, (i, j) in enumerate(coups):\n",
742
    "        corr = corrs[idx]\n",
743
    "        if i == j:\n",
744
    "            corr_mat_estim[i][j] = 1.0\n",
745
    "        else:\n",
746
    "            corr_mat_estim[i][j] = (\n",
747
    "                np.sum(np.array([estimate_shadow_obs(shadow, o, k=k+1) for o in corr])) / 3\n",
748
    "            )\n",
749
    "            corr_mat_estim[j][i] = corr_mat_estim[i][j]\n",
750
    "    return corr_mat_estim\n",
751
    "\n",
752
    "shadow = gen_class_shadow(circuit_oshot, psi0, 1000, num_qubits)\n",
753
    "expval_estmt = build_estim_corrmat(coups, corrs, len(qbobs), shadow)"
754
   ]
755
  },
756
  {
757
   "cell_type": "markdown",
758
   "metadata": {
759
    "id": "AtpcKs2dlMUJ"
760
   },
761
   "source": [
762
    "This time, let us visualize the deviation observed between the exact\n",
763
    "correlation matrix ($C$) and the estimated correlation matrix\n",
764
    "($C^{\\prime}$) to assess the effectiveness of classical shadow\n",
765
    "formalism.\n"
766
   ]
767
  },
768
  {
769
   "cell_type": "code",
770
   "execution_count": 58,
771
   "metadata": {
772
    "colab": {
773
     "base_uri": "https://localhost:8080/",
774
     "height": 371
775
    },
776
    "id": "MAviSXyklMUJ",
777
    "outputId": "9187eaa8-7340-49b6-91ac-871d95d1c191"
778
   },
779
   "outputs": [
780
    {
781
     "data": {
782
      "image/png": "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\n",
783
      "text/plain": [
784
       "<Figure size 420x400 with 2 Axes>"
785
      ]
786
     },
787
     "metadata": {},
788
     "output_type": "display_data"
789
    }
790
   ],
791
   "source": [
792
    "fig, ax = plt.subplots(1, 1, figsize=(4.2, 4))\n",
793
    "im = ax.imshow(expval_exact-expval_estmt, cmap=plt.get_cmap(\"RdBu\"), vmin=-1, vmax=1)\n",
794
    "ax.xaxis.set_ticks(range(num_qubits))\n",
795
    "ax.yaxis.set_ticks(range(num_qubits))\n",
796
    "ax.xaxis.set_tick_params(labelsize=14)\n",
797
    "ax.yaxis.set_tick_params(labelsize=14)\n",
798
    "ax.set_title(\"Error in estimating the\\ncorrelation matrix\", fontsize=14)\n",
799
    "\n",
800
    "bar = fig.colorbar(im, pad=0.05, shrink=0.80)\n",
801
    "bar.set_label(r\"$\\Delta C_{ij}$\", fontsize=14, rotation=0)\n",
802
    "bar.ax.tick_params(labelsize=14)\n",
803
    "plt.show()"
804
   ]
805
  },
806
  {
807
   "cell_type": "markdown",
808
   "metadata": {
809
    "id": "CvaBmbD-lMUJ"
810
   },
811
   "source": [
812
    "Training Classical Machine Learning Models\n",
813
    "==========================================\n"
814
   ]
815
  },
816
  {
817
   "cell_type": "markdown",
818
   "metadata": {
819
    "id": "P9L3yo0tlMUJ"
820
   },
821
   "source": [
822
    "There are multiple ways in which we can combine classical shadows and\n",
823
    "machine learning. This could include training a model to learn the\n",
824
    "classical representation of quantum systems based on some system\n",
825
    "parameter, estimating a property from such learned classical\n",
826
    "representations, or a combination of both. In our case, we consider the\n",
827
    "problem of using\n",
828
    "`kernel-based models <tutorial_kernel_based_training>`{.interpreted-text\n",
829
    "role=\"doc\"} to learn the ground-state representation of the Heisenberg\n",
830
    "model Hamiltonian $H(x_l)$ from the coupling vector $x_l$, where\n",
831
    "$x_l = [J_{i,j} \\text{ for } i < j]$. The goal is to predict the\n",
832
    "correlation functions $C_{ij}$:\n",
833
    "\n",
834
    "$$\\big\\{x_l \\rightarrow \\sigma_T(\\rho(x_l)) \\rightarrow \\text{Tr}(\\hat{C}_{ij} \\sigma_T(\\rho(x_l))) \\big\\}_{l=1}^{N}.$$\n",
835
    "\n",
836
    "Here, we consider the following kernel-based machine learning model:\n",
837
    "\n",
838
    "$$\\hat{\\sigma}_{N} (x) = \\sum_{l=1}^{N} \\kappa(x, x_l)\\sigma_T (x_l) = \\sum_{l=1}^{N} \\left(\\sum_{l^{\\prime}=1}^{N} k(x, x_{l^{\\prime}})(K+\\lambda I)^{-1}_{l, l^{\\prime}} \\sigma_T(x_l) \\right),$$\n",
839
    "\n",
840
    "where $\\lambda > 0$ is a regularization parameter in cases when $K$ is\n",
841
    "not invertible, $\\sigma_T(x_l)$ denotes the classical representation of\n",
842
    "the ground state $\\rho(x_l)$ of the Heisenberg model constructed using\n",
843
    "$T$ randomized Pauli measurements, and $K_{ij}=k(x_i, x_j)$ is the\n",
844
    "kernel matrix with $k(x, x^{\\prime})$ as the kernel function.\n",
845
    "\n",
846
    "Similarly, estimating an expectation value on the predicted ground state\n",
847
    "$\\sigma_T(x_l)$ using the trained model can then be done by evaluating:\n",
848
    "\n",
849
    "$$\\text{Tr}(\\hat{O} \\hat{\\sigma}_{N} (x)) = \\sum_{l=1}^{N} \\kappa(x, x_l)\\text{Tr}(O\\sigma_T (x_l)).$$\n",
850
    "\n",
851
    "We train the classical kernel-based models using $N = 70$ randomly\n",
852
    "chosen values of the coupling matrices $J$.\n"
853
   ]
854
  },
855
  {
856
   "cell_type": "code",
857
   "execution_count": 59,
858
   "metadata": {
859
    "id": "awX0qjXKlMUJ"
860
   },
861
   "outputs": [],
862
   "source": [
863
    "# imports for ML methods and techniques\n",
864
    "from sklearn.model_selection import train_test_split, cross_val_score\n",
865
    "from sklearn import svm\n",
866
    "from sklearn.kernel_ridge import KernelRidge"
867
   ]
868
  },
869
  {
870
   "cell_type": "markdown",
871
   "metadata": {
872
    "id": "bQWsJyqGlMUJ"
873
   },
874
   "source": [
875
    "First, to build the dataset, we use the function `build_dataset` that\n",
876
    "takes as input the size of the dataset (`num_points`), the topology of\n",
877
    "the lattice (`Nr` and `Nc`), and the number of randomized Pauli\n",
878
    "measurements ($T$) for the construction of classical shadows. The\n",
879
    "`X_data` is the set of coupling vectors that are defined as a stripped\n",
880
    "version of the coupling matrix $J$, where only non-duplicate and\n",
881
    "non-zero $J_{ij}$ are considered. The `y_exact` and `y_clean` are the\n",
882
    "set of correlation vectors, i.e., the flattened correlation matrix $C$,\n",
883
    "computed with respect to the ground-state obtained from exact\n",
884
    "diagonalization and classical shadow representation (with $T=500$),\n",
885
    "respectively.\n"
886
   ]
887
  },
888
  {
889
   "cell_type": "code",
890
   "execution_count": 60,
891
   "metadata": {
892
    "colab": {
893
     "base_uri": "https://localhost:8080/",
894
     "height": 0
895
    },
896
    "id": "oNjK4cvrlMUJ",
897
    "outputId": "64d55c2a-9d38-4349-dbd6-04ab57db94fc"
898
   },
899
   "outputs": [
900
    {
901
     "data": {
902
      "text/plain": [
903
       "((100, 4), (100, 16), (100, 16))"
904
      ]
905
     },
906
     "execution_count": 60,
907
     "metadata": {},
908
     "output_type": "execute_result"
909
    }
910
   ],
911
   "source": [
912
    "def build_dataset(num_points, Nr, Nc, T=500):\n",
913
    "\n",
914
    "    num_qubits = Nr * Nc\n",
915
    "    X, y_exact, y_estim = [], [], []\n",
916
    "    coupling_mats = build_coupling_mats(num_points, Nr, Nc)\n",
917
    "\n",
918
    "    for coupling_mat in coupling_mats:\n",
919
    "        ham = Hamiltonian(coupling_mat)\n",
920
    "        eigvals, eigvecs = sp.sparse.linalg.eigs(ham.sparse_matrix())\n",
921
    "        psi = eigvecs[:, np.argmin(eigvals)]\n",
922
    "        shadow = gen_class_shadow(circuit_oshot, psi, T, num_qubits)\n",
923
    "\n",
924
    "        coups = list(it.product(range(num_qubits), repeat=2))\n",
925
    "        corrs = [corr_function(i, j) for i, j in coups]\n",
926
    "        qbobs = [x for sublist in corrs for x in sublist]\n",
927
    "\n",
928
    "        expval_exact = build_exact_corrmat(coups, corrs, circuit_exact, psi)\n",
929
    "        expval_estim = build_estim_corrmat(coups, corrs, len(qbobs), shadow)\n",
930
    "\n",
931
    "        coupling_vec = []\n",
932
    "        for coup in coupling_mat.reshape(1, -1)[0]:\n",
933
    "            if coup and coup not in coupling_vec:\n",
934
    "                coupling_vec.append(coup)\n",
935
    "        coupling_vec = np.array(coupling_vec) / np.linalg.norm(coupling_vec)\n",
936
    "\n",
937
    "        X.append(coupling_vec)\n",
938
    "        y_exact.append(expval_exact.reshape(1, -1)[0])\n",
939
    "        y_estim.append(expval_estim.reshape(1, -1)[0])\n",
940
    "\n",
941
    "    return np.array(X), np.array(y_exact), np.array(y_estim)\n",
942
    "\n",
943
    "X, y_exact, y_estim = build_dataset(100, Nr, Nc, 500)\n",
944
    "X_data, y_data = X, y_estim\n",
945
    "X_data.shape, y_data.shape, y_exact.shape"
946
   ]
947
  },
948
  {
949
   "cell_type": "markdown",
950
   "metadata": {
951
    "id": "V18wEzs_lMUK"
952
   },
953
   "source": [
954
    "Now that our dataset is ready, we can shift our focus to the ML models.\n",
955
    "Here, we use two different Kernel functions: (i) Gaussian Kernel and\n",
956
    "(ii) Neural Tangent Kernel. For both of them, we consider the\n",
957
    "regularization parameter $\\lambda$ from the following set of values:\n",
958
    "\n",
959
    "$$\\lambda = \\left\\{ 0.0025, 0.0125, 0.025, 0.05, 0.125, 0.25, 0.5, 1.0, 5.0, 10.0 \\right\\}.$$\n",
960
    "\n",
961
    "Next, we define the kernel functions $k(x, x^{\\prime})$ for each of the\n",
962
    "mentioned kernels:\n"
963
   ]
964
  },
965
  {
966
   "cell_type": "markdown",
967
   "metadata": {
968
    "id": "Seuq-zVflMUK"
969
   },
970
   "source": [
971
    "$$k(x, x^{\\prime}) = e^{-\\gamma||x - x^{\\prime}||^{2}_{2}}. \\tag{Gaussian Kernel}$$\n",
972
    "\n",
973
    "For the Gaussian kernel, the hyperparameter\n",
974
    "$\\gamma = N^{2}/\\sum_{i=1}^{N} \\sum_{j=1}^{N} ||x_i-x_j||^{2}_{2} > 0$\n",
975
    "is chosen to be the inverse of the average Euclidean distance $x_i$ and\n",
976
    "$x_j$. The kernel is implemented using the radial-basis function (rbf)\n",
977
    "kernel in the `sklearn` library.\n"
978
   ]
979
  },
980
  {
981
   "cell_type": "markdown",
982
   "metadata": {
983
    "id": "38VnvOMGlMUK"
984
   },
985
   "source": [
986
    "$$k(x, x^{\\prime}) = k^{\\text{NTK}}(x, x^{\\prime}). \\tag{Neural Tangent Kernel}$$\n",
987
    "\n",
988
    "The neural tangent kernel $k^{\\text{NTK}}$ used here is equivalent to an\n",
989
    "infinite-width feed-forward neural network with four hidden layers and\n",
990
    "that uses the rectified linear unit (ReLU) as the activation function.\n",
991
    "This is implemented using the `neural_tangents` library.\n"
992
   ]
993
  },
994
  {
995
   "cell_type": "code",
996
   "execution_count": 61,
997
   "metadata": {
998
    "colab": {
999
     "base_uri": "https://localhost:8080/",
1000
     "height": 0
1001
    },
1002
    "id": "Ekn9atIZlMUK",
1003
    "outputId": "5b0e44dc-a7aa-40a6-f945-2b56e0c57df4"
1004
   },
1005
   "outputs": [],
1006
   "source": [
1007
    "from neural_tangents import stax\n",
1008
    "init_fn, apply_fn, kernel_fn = stax.serial(\n",
1009
    "    stax.Dense(32),\n",
1010
    "    stax.Relu(),\n",
1011
    "    stax.Dense(32),\n",
1012
    "    stax.Relu(),\n",
1013
    "    stax.Dense(32),\n",
1014
    "    stax.Relu(),\n",
1015
    "    stax.Dense(32),\n",
1016
    "    stax.Relu(),\n",
1017
    "    stax.Dense(1),\n",
1018
    ")\n",
1019
    "kernel_NN = kernel_fn(X_data, X_data, \"ntk\")\n",
1020
    "\n",
1021
    "for i in range(len(kernel_NN)):\n",
1022
    "    for j in range(len(kernel_NN)):\n",
1023
    "        kernel_NN.at[i, j].set((kernel_NN[i][i] * kernel_NN[j][j]) ** 0.5)"
1024
   ]
1025
  },
1026
  {
1027
   "cell_type": "markdown",
1028
   "metadata": {
1029
    "id": "GJbMkW7klMUK"
1030
   },
1031
   "source": [
1032
    "For the above two defined kernel methods, we obtain the best learning\n",
1033
    "model by performing hyperparameter tuning using cross-validation for the\n",
1034
    "prediction task of each $C_{ij}$. For this purpose, we implement the\n",
1035
    "function `fit_predict_data`, which takes input as the correlation\n",
1036
    "function index `cij`, kernel matrix `kernel`, and internal kernel\n",
1037
    "mapping `opt` required by the kernel-based regression models from the\n",
1038
    "`sklearn` library.\n"
1039
   ]
1040
  },
1041
  {
1042
   "cell_type": "code",
1043
   "execution_count": 62,
1044
   "metadata": {
1045
    "id": "7qbJKRGglMUK"
1046
   },
1047
   "outputs": [],
1048
   "source": [
1049
    "from sklearn.metrics import mean_squared_error\n",
1050
    "\n",
1051
    "def fit_predict_data(cij, kernel, opt=\"linear\"):\n",
1052
    "\n",
1053
    "    # training data (estimated from measurement data)\n",
1054
    "    y = np.array([y_estim[i][cij] for i in range(len(X_data))])\n",
1055
    "    X_train, X_test, y_train, y_test = train_test_split(\n",
1056
    "        kernel, y, test_size=0.3, random_state=24\n",
1057
    "    )\n",
1058
    "\n",
1059
    "    # testing data (exact expectation values)\n",
1060
    "    y_clean = np.array([y_exact[i][cij] for i in range(len(X_data))])\n",
1061
    "    _, _, _, y_test_clean = train_test_split(kernel, y_clean, test_size=0.3, random_state=24)\n",
1062
    "\n",
1063
    "    # hyperparameter tuning with cross validation\n",
1064
    "    models = [\n",
1065
    "        # Epsilon-Support Vector Regression\n",
1066
    "        (lambda Cx: svm.SVR(kernel=opt, C=Cx, epsilon=0.1)),\n",
1067
    "        # Kernel-Ridge based Regression\n",
1068
    "        (lambda Cx: KernelRidge(kernel=opt, alpha=1 / (2 * Cx))),\n",
1069
    "    ]\n",
1070
    "\n",
1071
    "    # Regularization parameter\n",
1072
    "    hyperparams = [0.0025, 0.0125, 0.025, 0.05, 0.125, 0.25, 0.5, 1.0, 5.0, 10.0]\n",
1073
    "    best_pred, best_cv_score, best_test_score = None, np.inf, np.inf\n",
1074
    "    for model in models:\n",
1075
    "        for hyperparam in hyperparams:\n",
1076
    "            cv_score = -np.mean(\n",
1077
    "                cross_val_score(\n",
1078
    "                    model(hyperparam), X_train, y_train, cv=5,\n",
1079
    "                    scoring=\"neg_root_mean_squared_error\",\n",
1080
    "                )\n",
1081
    "            )\n",
1082
    "            if best_cv_score > cv_score:\n",
1083
    "                best_model = model(hyperparam).fit(X_train, y_train)\n",
1084
    "                best_pred = best_model.predict(X_test)\n",
1085
    "                best_cv_score = cv_score\n",
1086
    "                best_test_score = mean_squared_error(\n",
1087
    "                    best_model.predict(X_test).ravel(), y_test_clean.ravel(), squared=False\n",
1088
    "                )\n",
1089
    "\n",
1090
    "    return (\n",
1091
    "        best_pred, y_test_clean, np.round(best_cv_score, 5), np.round(best_test_score, 5)\n",
1092
    "    )"
1093
   ]
1094
  },
1095
  {
1096
   "cell_type": "markdown",
1097
   "metadata": {
1098
    "id": "IGPcW5sglMUK"
1099
   },
1100
   "source": [
1101
    "We perform the fitting and prediction for each $C_{ij}$ and print the\n",
1102
    "output in a tabular format.\n"
1103
   ]
1104
  },
1105
  {
1106
   "cell_type": "code",
1107
   "execution_count": 63,
1108
   "metadata": {
1109
    "colab": {
1110
     "base_uri": "https://localhost:8080/",
1111
     "height": 0
1112
    },
1113
    "id": "vxZOUxk9lMUK",
1114
    "outputId": "07ed6444-ca91-48c2-fe8c-64b9bba549c8"
1115
   },
1116
   "outputs": [
1117
    {
1118
     "name": "stdout",
1119
     "output_type": "stream",
1120
     "text": [
1121
      "              Correlation                    Gaussian kernel              Neural Tangent kernel\n",
1122
      "               \t C_00 \t|                           [-0.  0.]                          [-0.  0.]\n",
1123
      "               \t C_01 \t|                   [0.08991 0.07814]                  [0.1165  0.08399]\n",
1124
      "               \t C_02 \t|                   [0.10099 0.06564]                  [0.10664 0.08351]\n",
1125
      "               \t C_03 \t|                   [0.09774 0.04564]                  [0.10384 0.06656]\n",
1126
      "               \t C_10 \t|                   [0.08991 0.07814]                  [0.1165  0.08399]\n",
1127
      "               \t C_11 \t|                           [-0.  0.]                          [-0.  0.]\n",
1128
      "               \t C_12 \t|                   [0.11993 0.0337 ]                  [0.1305  0.06696]\n",
1129
      "               \t C_13 \t|                   [0.09644 0.05856]                  [0.0995  0.08167]\n",
1130
      "               \t C_20 \t|                   [0.10099 0.06564]                  [0.10664 0.08351]\n",
1131
      "               \t C_21 \t|                   [0.11993 0.0337 ]                  [0.1305  0.06696]\n",
1132
      "               \t C_22 \t|                           [-0.  0.]                          [-0.  0.]\n",
1133
      "               \t C_23 \t|                   [0.101   0.06974]                  [0.1226  0.07248]\n",
1134
      "               \t C_30 \t|                   [0.09774 0.04564]                  [0.10384 0.06656]\n",
1135
      "               \t C_31 \t|                   [0.09644 0.05856]                  [0.0995  0.08167]\n",
1136
      "               \t C_32 \t|                   [0.101   0.06974]                  [0.1226  0.07248]\n",
1137
      "               \t C_33 \t|                           [-0.  0.]                          [-0.  0.]\n"
1138
     ]
1139
    }
1140
   ],
1141
   "source": [
1142
    "kernel_list = [\"Gaussian kernel\", \"Neural Tangent kernel\"]\n",
1143
    "kernel_data = np.zeros((num_qubits ** 2, len(kernel_list), 2))\n",
1144
    "y_predclean, y_predicts1, y_predicts2 = [], [], []\n",
1145
    "\n",
1146
    "for cij in range(num_qubits ** 2):\n",
1147
    "    y_predict, y_clean, cv_score, test_score = fit_predict_data(cij, X_data, opt=\"rbf\")\n",
1148
    "    y_predclean.append(y_clean)\n",
1149
    "    kernel_data[cij][0] = (cv_score, test_score)\n",
1150
    "    y_predicts1.append(y_predict)\n",
1151
    "    y_predict, y_clean, cv_score, test_score = fit_predict_data(cij, kernel_NN)\n",
1152
    "    kernel_data[cij][1] = (cv_score, test_score)\n",
1153
    "    y_predicts2.append(y_predict)\n",
1154
    "\n",
1155
    "# For each C_ij print (best_cv_score, test_score) pair\n",
1156
    "row_format = \"{:>25}{:>35}{:>35}\"\n",
1157
    "print(row_format.format(\"Correlation\", *kernel_list))\n",
1158
    "for idx, data in enumerate(kernel_data):\n",
1159
    "    print(\n",
1160
    "        row_format.format(\n",
1161
    "            f\"\\t C_{idx//num_qubits}{idx%num_qubits} \\t| \",\n",
1162
    "            str(data[0]),\n",
1163
    "            str(data[1]),\n",
1164
    "        )\n",
1165
    "    )"
1166
   ]
1167
  },
1168
  {
1169
   "cell_type": "markdown",
1170
   "metadata": {
1171
    "id": "W8OQJN7blMUK"
1172
   },
1173
   "source": [
1174
    "Overall, we find that the models with the Gaussian kernel performed\n",
1175
    "better than those with NTK for predicting the expectation value of the\n",
1176
    "correlation function $C_{ij}$ for the ground state of the Heisenberg\n",
1177
    "model. However, the best choice of $\\lambda$ differed substantially\n",
1178
    "across the different $C_{ij}$ for both kernels. We present the predicted\n",
1179
    "correlation matrix $C^{\\prime}$ for randomly selected Heisenberg models\n",
1180
    "from the test set below for comparison against the actual correlation\n",
1181
    "matrix $C$, which is obtained from the ground state found using exact\n",
1182
    "diagonalization.\n"
1183
   ]
1184
  },
1185
  {
1186
   "cell_type": "code",
1187
   "execution_count": 64,
1188
   "metadata": {
1189
    "colab": {
1190
     "base_uri": "https://localhost:8080/",
1191
     "height": 1000
1192
    },
1193
    "id": "EpnjzM4WlMUK",
1194
    "outputId": "54130309-f89b-4dcd-97fa-626b40d1a169"
1195
   },
1196
   "outputs": [
1197
    {
1198
     "data": {
1199
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABQgAAAR4CAYAAABKNTsbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAAD64UlEQVR4nOzdd3gU5fr/8c9sKumhSG+C0gUUEAWUplLkqCjoQSl2D18LCKgcFRALitixF5oUQVABUcEAKh0EBBRBhGCoAkI6gSTz+yO/nZOQbNhNNtls5v26rr0IO/M8e+/s7D279z7zjGGapikAAAAAAAAAtuTwdQAAAAAAAAAAfIcCIQAAAAAAAGBjFAgBAAAAAAAAG6NACAAAAAAAANgYBUIAAAAAAADAxigQAgAAAAAAADZGgRAAAAAAAACwMQqEAAAAAAAAgI1RIAQAAAAAAABsjAIh4EOdO3eWYRgaN26cr0MpF1auXCnDMGQYhkfLyjJnzCtXrvR1KACKoF69ejIMQ1OnTvV1KPAicjMAlD9Tp06VYRiqV6+er0MBfMIWBcJx48ZZH+TOd7MTZwJ09xYfH+/rkItl3LhxGjduXLGfR0HbJjg4WFWqVNHFF1+svn376vnnn9eePXu8EzjKpddff13jxo3T1q1bfR0KCsBxwz3ff/+9hg4dqpYtW6pKlSoKCgpSdHS0GjVqpP79++uDDz7QsWPHfB0mimDIkCFufUl69tlnrfdCv379dObMmdIJEOUOebdguT+vOxwObdmypdD1neva5UcJ54/tRbkNGTLE1+H7hPP5FzZA4cSJE7r88sut7zmfffZZ6QUIwGcCfR1AaatataqvQyiTKleurICAgELXOd/ysu6ZZ56RlPNBwhu/CoWHhysiIkKSlJ2draSkJB0/flx//PGHvvjiCz311FPq0aOH3nvvPdWtW7fAPurUqaNGjRqpcuXKxY4HhQsLC1OjRo18HYbl9ddf1/79+1WvXj21atXK5XrOmMPCwkopMpyL40Z+u3fv1sCBA7VhwwbrPofDoejoaJ0+fVq7d+/W7t27NW/ePD3yyCN66KGHNHHiRB9G7DsNGjRQaGiooqOjfR2KV5mmqUcffVSvv/66JOnee+/Ve++9J4fDFr89o4SRdwtmmqaeeOIJfffdd74OpcyoWLFigfvLmTNndPLkSUlSbGysgoOD861T3vKytxw6dEjXXHONfvvtN4WFhWnBggW67rrrfB0WgFJguwLhkSNHfB1CmbRx40aGUnto5MiR+X55O3HihDZs2KDp06dr7ty5+vbbb9WiRQstX75cbdq0ydfH9OnTSylatGvXTr///ruvw/CYP8Zc3nDcyGvdunW67rrrlJSUpPDwcA0dOlS33nqrWrVqZf2QdOrUKa1atUpz587VZ599punTp9u2QBgXF+frELwuKytL99xzjzVC6bHHHtNLL73k26BQrpB3XVu6dKmWL1+url27+jqUMmHBggUF3r9y5Up16dLFWqdz586lGJX/2rNnj6655hrFx8crJiZGX3/9ta688kpfhwWglPAzL+BFlSpVUs+ePTV79mzFxcUpOjpaycnJuv76661fMQHAX/3999/q27evkpKSVLt2bW3cuFETJ07UZZddlmeUeUxMjK6//npNnz5df/zxh3r37u3DqOFNGRkZ6tevn1UcfOmllygOAqXk+uuvlyQ98cQTMk3Tx9GgvNm2bZs6deqk+Ph4VatWTT/++CPFQcBmKBAWID4+Ps+8e3/++afuu+8+1a9fXyEhIflG2iUmJmr8+PG69NJLFRUVpQoVKuiiiy7Sf/7zH+3du9fl4+Se4PrEiRN69NFH1aBBA1WoUEF169bVgw8+mGfupv379+s///mP6tevr9DQUNWpU0cjRoxQcnJySW0Kl1566SVrTorcp5jltmTJEjkcDhmGoZkzZ+ZZtm/fPr300kvq0aOHLr74Yut03aZNm2rYsGH666+/zhtDQkKCHnvsMbVq1UrR0dGqUKGCGjRooBtuuEHTp0/X6dOnJf1vHiWnLl265Jl/pKRGTnbu3FkfffSRJOno0aN69dVXC1zH1RwgR44c0VtvvaUbbrhBTZo0sZ5jw4YNdc899+jXX389bwxfffWVunbtqpiYGEVERKhly5aaOHGizp49a831U9gvqitXrlS/fv1Us2ZNhYSEqHLlyurWrZumTJmirKysAtuc229cXJx69+6tKlWqKDQ0VE2aNNEzzzxjvT7nSktL0+zZszVo0CC1atVKVapUUUhIiGrUqKEbb7xR33zzzXmft6vnUtDcRbnf7+e7nfs67dixQ+PGjVPXrl2t925UVJRat26tp556SsePH3e5ffbv3y9JuvPOOwudW+l8E+GfPn1ar7/+uq688krFxsYq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e/fmWVZYgfDZZ581X375ZXP79u3WB8CsrCxzx44d5u233259QD148GC+trNnz7Yec8CAAeaBAwdM08zZbz744AMzNDTU+iBU0Bfat956y2p/3333mYcPHzZN0zRTUlLM1157zfrAe+utt+Zr63y/xcTEmA6Hwxw9erR57Ngx0zRNMzEx0RwzZozVd0HFpy+//NIcOXKkuWrVKjM1NdW6/9ChQ+YzzzxjfQn86quv8rUtSoHwfEaPHm19YFu1alWeZYMGDTKnTp1q7t+/37ovIyPD/P77760v0pdeemmB/RZWNMjN1X6bmZlpFfaio6PNTz/91MzIyDBN0zT//PNP8/rrr7e+4C5ZssTl48fGxpo1a9Y0v/zyS/PMmTOmaZrm77//buWviIgI89SpU+fbTOUOx438Vq9ebT3+O++841HbgiQkJJi33367uXDhQvPEiRPW/cnJyeaUKVOsL0/Dhw/P17a4BcJu3bpZ78+1a9ea2dnZpmnmvH93795tTpo0yZw4cWKeNnfffbcpyaxXr575/fffW1/0MzMzzfj4ePPdd981H3/88XwxFPZeL86x0Hn8iI2NNaOjo82pU6da6yUkJJh9+vSxvnzt3r270O1UkNwFwoMHD5rNmjWzjjvLli0rtO22bdvMChUqmJLMe++91/ztt9+s7bV//35z6NCh1he+3O8T08z72kZERJi9evUyd+7caS13PhfnZ5iwsDAzJCTEvOeee8y//vrLNE3TTE1NNSdPnmwdL55++ul8MR46dMj6DNO3b19z06ZNVg48evSo+fTTT1vHui+++CJf+5L88m5X5N2CnVsg3L9/vxkSEmJKMt99912X8RaUcz766CNrez3//PPW57vMzExz06ZNZteuXU1JZq1atfJ9fvdWgTAiIsIMDAw0J02aZCYmJpqmmZP3CytKFcX5CoR9+vQxP/vsM2sbmKZppqWlmQsWLDAbNWpkSjJvuummAvt29hsbG2s2bdrUXL58uZmVlWVmZ2ebGzZssNrXrVvX2teczpw5Y7Zo0cKUZFauXNlcsGCBlR937txpdu3aNU+xsqQLhHPnzrUKZ+3btzf/+eefQts+9dRTpiTzggsuMN9++23r+H3mzBlzxYoVZuvWra3j67nP3d19oLjHt+Ls5xQIYXe2KxAWNlLIeTDP/YGjbt26Ln95fvHFF00p51fx7du3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q6++Ksn1r+z+uK0yMzP173//W6dOnVKrVq20ZMkSJSUlKTk5WUePHtWRI0e0bt06a31PRxicT0ZGhm688Ubt3btXtWvX1sKFC1WhQoUC1/344481e/ZsBQQEaMyYMfrjjz/y7cfOL9DejhNlW3k9buQeDeaNU36HDx+u7du3q1KlSvrkk090+PBhpaen69ixY9Z7yPkFytvvoZiYGC1fvlw//fSTHnvsMXXo0EGBgYH6+eefNX78eF100UV5iv9Szqjszz77TFu3btWYMWPUtWtXhYWFaceOHZo0aZKaNWt23i/ouRXnWFjaqlevrpUrV6pJkyZWnp47d26B6zqLMVWrVpWZM9f1eW+uzmAoqfdS7hHp6enpbsVYWiN6UDTlNe8WJjw83JrW5+2339Zff/1V6PrO/f7WW291a5+Pj48vkbjLwmv1/PPPa8WKFapQoYJee+017d+/X6dPn9aJEyes/OscvVZS+besfE7v37+/Zs+ercDAQP3+++/q3Lmzy6k0nPvQ448/7tY+tHLlygL7Kcl9oKzs54C/okBYRBUrVrSSW2FDz3MvKwu/mJWExYsX66233pIkXXLJJTJNU4MHD3b5q/ycOXMk5czH8vbbb6t58+b5DhTOkYLncv6i5U/DwZcsWSIpZ9Sju6dxf/7558rKylKTJk00Z86cAofiu9pGVapUkZQzr2RBp+o5HTx4sMD7nfvp+U7pcy735n69du1a7d+/XwEBAVq8eLF69uyZ79dDV8/bG+68806tWbNGERERWrRoUaGnJjj343vuuUfPPPOMGjZsKIcjb0otyVjdeZ2cH3Zzrw/f8ffjRtu2ba3348KFC4vV19mzZ7VgwQJJOaOl77zzznzvt9yjhc+Ve8SOqxECruYRy61jx4566aWXtGrVKp06dUpfffWVWrRoofT0dN11110FHsdatmypZ555RnFxcTp16pS+//57XXXVVcrKyrJGGbqjOMdCX6hWrZpWrFihpk2bKjMzUwMGDChwXknn63j8+PESGT3tDbn3NX/6PAHP+XvePZ97771XF110kTIyMqx5h10p7mdoZ94tbFSWO3m3LHDm3zFjxmjYsGGqU6dOvoJdSeVf5+f03COZz+XqM3pJueWWW/TZZ58pKChIu3btUufOnQuMzx++h/lDjEBZRoGwiIKDg3XJJZdIkuLi4lyu9/3330uSHA6HLr300lKJrTQdPnxYd955p6Sc4sqPP/6oevXq6e+//9bgwYML/NUtISFBktS6desC+zRNU8uXLy9wmXNOvSNHjric+84V54G/NEdifP7559qxY4ckeXSRC+c2atmyZb6ik5Nz3zqXcz87e/asy4mVTdPUjz/+WOAy59yOBw4c0O7duwtcJysryzotw9V8O0XhfN5VqlRxeXqFq+ddXGPGjNHs2bPlcDg0a9Ysl5MvO51vP05JSdH69etdtne+rkXdH52vU2H5Z+XKldbpTN58nVA0/n7cCAoK0n333ScpZ1Lv3KN5PZV7ridX76FVq1a5/CIaGxtr/e18L56rsPdfQUJDQ/Wvf/3LKlyePn36vBcYCgwMVLdu3fT1118rJCREpmm6naOKcyz0lapVq2rFihVq1qyZsrKydPvtt+cbaemcCy4rK0vffPONL8I8r9w/ui1atMjH0aAk+XvePZ/AwEA999xzkqTp06fr119/dbmu8735888/F+liS8686yrnSp7nXV85X/6Nj4+3Lvjnbc79y9XouvMtKyl9+/bV3LlzFRQUpN27d6tz5875CpXOfej777936/RdXyjufg7YHQXCYrjtttsk5S0C5ZaSkmKdPtSrVy9FR0eXanwlLTs7WwMHDtTx48d10UUX6a233lJ0dLRmzZqlwMBAfffdd9ZpsLk5t4OrURbvvfee9u7dW+CyLl266MILL5SUc3paYSPkzuWcSD733HYl6YcfftA999wjKefXrGHDhrnd1rmNtm/fXmAB6ZtvvnH54aFVq1bWhO0vvvhige0//fRTl7+sXXPNNdZcY66uYvz+++9bvyw6rwLmDc7n7bxS4bkOHDigN99802uP5zRjxgw9++yzkqRJkyapT58+521zvv342WefVXJyssv2xd0fnfln7dq1Wrp0ab7lmZmZGj9+vCSpefPmBV65EaXP348bjz32mKpXry7TNNW/f3/t3LmzSP1ERUVZP9oU9B7KzMzUk08+6bL9xRdfbJ3+P3/+/HzLs7OzNWHChALbZmZmWnO7FiT3tAK5f6DJyMhw2SYkJMQapeTqR51zFedY6EsXXHCBVqxYoRYtWigrK0sDBw7UzJkzreUXXXSRdTruk08+ed4RRb64CFJ4eLgGDBggSXrppZfOe2qm3S/U5O/8Pe+eT79+/dSmTRtlZ2dr9OjRha4XExOjs2fP6tFHHy30B8rs7Ox8n0+cP5xu3LixwCLhzp07rR9Yyrrz5d8nnniixB7bOf3Mjz/+aF1QI7eMjAxNmjSpxB6/MDfeeKM+//xzBQcH648//lDnzp3zjK696667FBgYqOPHj593xOqZM2esi5WUpuLu54DdUSAshv/85z+qX7++zp49q549e+qbb76xvnRs375d1113nfbt26eQkBDr173yZOLEiYqLi1NQUJBmz56t8PBwSdIVV1xhHTT++9//WlfrcurRo4eknCLXs88+a52CdOrUKb3wwgt66KGHXF7MIyAgQJMnT5ZhGFq1apW6deumVatWWdv9zJkzWrlype644w799ttvedo6CyQzZ84ssQlp//nnH33zzTcaMGCAunXrpsTEREVFRenrr79WTEyM2/04t9Gvv/6q//u//7O+nKSmpur999/XLbfc4nIbGYahZ555RlLOKJ/BgwfnmbD3448/1v33359nBE5uFSpUsAqDs2fP1gMPPGAV69LS0vTmm29axc5bb71Vl112mdvP63w6duyo8PBwq/jgHMGYlZWl7777Tp07d/b6nC2rV6+2Crn333+/NefX+Thfow8//FAffPCBVax2zhs2ceLEQi9K49wfP//88yJd1fDmm2+25sfp37+/Zs2aZU3UvG/fPt18881au3atJOW5CAJ8y9+PGxdccIEWLFigqKgoJSQkqG3btho1apR+/vnnPPO6paWl6YcffnA5cjoiIsL6lf/RRx/V8uXLre2wY8cO9erVS5s2bbKOK+cKCgrSzTffLEl64YUXNHfuXOs9uGvXLt10003WlUvPdeDAAV100UV67rnntGXLljwXDdi2bZvuuOMOSTlFpNxXmaxbt65Gjx6tdevW5SkW7tmzR7fffrvS0tLkcDh03XXXFboNnYpzLPS1KlWqaPny5brkkkuUlZWlQYMG6dNPP7WWv/XWW4qIiNDu3bvVvn17ffXVV3lGmxw8eFAzZsxQt27d9Pjjj/viKeiFF15QjRo1dPz4cV1xxRWaMWNGnh91jh07pvnz5+umm27y6g9hKH3+nnfPxzAMvfjii5IKHxEbExOj119/XVLOKba9e/fW+vXrrW2RnZ2tnTt36pVXXlGzZs20ePHiPO379OmjiIgInT17Vv3799euXbsk5Zyx8tVXX6l79+4uc7Y74uPjZRiGDMNw+QO1tzjz73PPPacFCxZYx4F9+/ZpwIABmjt3rsvPycV16623qlmzZjJNU3379tVXX31lHT937dql66+//rynN9erV0+GYZTI3Kj/+te/NH/+fAUHB2vPnj3q3LmzVRBu0KCBnn76aUk5ny0HDRqUp+iemZmprVu3avz48WrYsKFX5iv2VHH3c8D2TBsYO3asKcl09+nu27fPWn/fvn2Frrt9+3azZs2a1vqhoaFmVFSU9f+QkBBz3rx5BbZ1rrNixYoix7FixQqPnltuU6ZMsdpWrlzZrFq1aqG3OXPmWG3Xr19vBgUFmZLMl19+OV/fWVlZZufOnU1J5sUXX2ympKRYy86cOWN26tTJemzDMMzY2FjT4XCYkszevXubTz31lCnJvPrqqwuMfdq0aWZISEie7VypUiUzMDDQum/Lli152syYMcNaFhQUZNasWdOsW7eu2aFDB4+2m7OP8PBwa9tccMEFZmhoqLXM+bx69epl7t+/32VfV199tSnJHDt2bL5lt912W57+YmJizICAAFOSedlll5lvvfWWKcmsW7dugX0PGzYs3zZ2vmZdu3Y1R48ebUoyr7vuugLbDx8+PF/73Nu3S5cuZlJSUr52zvebq9fONAvfb9999908zzsiIsLatpUrVzYXLlzo8n1RWL+uluXOD+d7H+Te10+ePGk2btzYautwOMyYmBjTMAxTknn//febgwcPNiWZgwcPzhfPDz/8YK0bEBBgVq9e3axbt26+17OwPHHgwAGzWbNm1jrBwcFmTExMnpjeeOONAl+DunXrmpLMKVOmFLjcNM1C4y/vOG4U7vfffzfbtWuX573qcDjMihUrmtHR0da+7Xw+w4cPN0+ePJmnj02bNpnh4eF51ouMjDQlmYGBgeb06dML3U8TEhLMGjVq5Mnrzu0YGRlprly5ssDtlXsbOd9/FStWNIODg/O8l859Dc59rrGxsXnyvmEY5muvvZYvTlfPobjHwsKOH07u5GNXnO9/V8cY0zTN48ePmy1btrS2ybRp06xlq1atMqtVq5ZnO1eqVMmsUKFCnm15zz335OnT3f3T+RmmsPjO93747bffzIsvvjjfPpx7v5Rkdu/ePV/b870X4TnybsFyf14vzDXXXJNnv3V1fH/33Xfz5DvnZ2jnZ0Tn7dNPP83X9qOPPsqT3yMjI62+2rdvb06ePNnl+/J8nylyb8fC8pq7cm/zc1+7+Ph4s2rVqtbywMBAMzo62vr/Cy+8UGiOdef9X1j7nTt35smPISEh1uOHhISYixYtspatXbs2X3vncaUouT13/IVt58WLF1vftS688ELr+0x2drb59NNP59kPKlSoYFaqVMn6nuK8rVq1Kk+f7n6u9Mbxraj7uTvHFqA8YwRhMTVv3ly//vqrxo0bp1atWikwMFAZGRlq0KCBHnjgAf3666/WUPKy7Pjx49Zpna5u6enpkqTk5GT9+9//1tmzZ3XNNddoxIgR+fpzOByaMWOGKlasqN27d+vBBx+0lgUFBWnp0qUaO3asLr74YgUFBck0TbVr107vvvuuFi5ceN6rWw0aNEi///67hg0bpqZNmyowMFDp6emqW7eubrzxRs2YMUNNmjTJ0+aOO+7QjBkz1LFjR4WFhenw4cPav3//eS/G4Upqaqq1bU6ePKnw8HBddNFFuummm/T888/rjz/+0Ndff606deoUqf+ZM2fq9ddf1yWXXKKQkBBlZWWpRYsWmjBhglavXq2IiIhC27/22mtasGCBOnfurMjISGVkZKhJkyZ6+eWX9d1331mjVVyNbHz11Ve1fPly3XzzzapatapSUlIUGRmpLl266JNPPtGyZcvyXUDEGx544AF9/fXX6ty5syIiIpSZmamaNWvqoYce0i+//KIWLVp4/TGdzvc+yH2qRExMjNasWaNhw4apXr16CggIUGBgoDp37qzZs2frvffeK/SxrrrqKn399dfq3r27YmJidPToUe3fv9+jSZVr1qypTZs26dVXX1X79u1VoUIFpaWlqXbt2ho4cKB+/vlnPfzww0XeHigZ5eG40ahRI61fv15Lly7VAw88oBYtWig2NlZJSUkyTVMNGjTQLbfconfeeUeHDh3Sq6++mi/XXHbZZdqwYYP69++vypUrKzs7W5GRkerfv7/WrFmjgQMHFhpDrVq1tH79et1zzz3WnKUREREaNGiQNm/enGf0X241a9bUwoULNXz4cLVv317Vq1dXSkqKAgMD1bRpU/3f//2fduzYke81WLp0qUaPHq1OnTqpdu3a1jGxYcOGuvPOO7Vx40aPppLwxrHQ1ypVqqTly5erdevWys7O1p133qmpU6dKypkHavfu3Zo0aZKuuuoqxcTE6NSpUwoICFCTJk10xx13WMc5X2nSpIm2bdum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DkpS5cqV9c4770iSJk+erMTExPP2FRgYqE2bNqlfv355ioOS1KJFC02cOFGSNGfOHI9PXS6PKBACAAAAAADApw4ePKiNGzdKkgYMGJBveceOHVW7dm1lZGRoyZIlxX681q1bS5LS09N1/PjxYvfn7zjFGAAAAAAAAD61ZcsWSVLFihVVv379Atdp06aNEhIStGXLFv373/8u1uP98ccfkqTg4GBVrFixwHWOHj2q8ePH6+DBgwoNDVXjxo3Vu3dv1alTp1iPXRZRIAQAAAAAAIDXJSUl5fl/SEhIvtN9nfbt2ydJhRbfateunWfdojJN0zrF+Prrr3cZ0++//66xY8fmuS8wMFAPPfSQJk6cqMDA8lNW4xRjAAAAAAAAm3MYhldvUk5BLzo62rpNmDDB5eMnJydLksLDw12uExERISl/4dFTzzzzjNauXauIiAi9+OKL+ZZHR0dr2LBh+uGHH3T48GGlpqZq27ZtGj58uAzD0GuvvaahQ4cWK4aypvyUOgEAAAAAAFBmJCQkKCoqyvq/q5F6pWn69OkaP368HA6HPvnkE1100UX51mndurU1R6FTixYt9Oqrr6pjx466+eab9eGHH2ro0KFq1apVKUVeshhBCAAAAAAAAK+LiorKcyusQBgZGSlJSk1NdblOSkqK1W9RzJs3T3fddZck6cMPP1S/fv087qNv375WUXDRokVFiqMsokAIAAAAAAAAn6pXr56knFGHrjiXOdf1xIIFCzRgwABlZ2fr/ffftwqFRdGkSRNJ0oEDB4rcR1lDgRAAAAAAAMDmAhzevXnKeUrviRMnXF6EZNOmTZKkSy+91KO+v/zyS912223KysrSu+++q3vvvdfzAHM5ceKEpP+NeiwPKBACAAAAAADAp2rVqqW2bdtKkmbNmpVv+apVq5SQkKCQkBD16tXL7X4XLVqk/v37KzMzU++++67uv//+YsV58OBB/fTTT5Kkdu3aFauvsoQCIQAAAAAAAHzuv//9ryTpxRdf1ObNm637T5w4YV01+MEHH1R0dLS17IsvvlDjxo3VrVu3fP0tWbJEt9xyizIzM/Xee++5XRx84403dPz48Xz3b9u2TX369FF6eroaNGigG264waPnV5ZxFWMAAAAAAAD43I033qiHH35Yb775ptq3b69u3bopPDxccXFxOnXqlDp06KBnn302T5vExETt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AFKfPn1UqVIlpaamav369Ve9v2DBAklS+/btVadOHc/+evXq6fbbby90zJW+/vprpaWlKSwsTH369Cml6r1X7hqE7dq106uvvqqNGzfq3Llzys3NVUZGhjIzM/Xee++pRo0aSk9P14ABA3ThwgW7ywUARyKrASDwkdUAACfp3r27mjVrpiVLlhTaX7VqVT355JOSpNGjR+vMmTOe97Zt26a//vWvkqTf//73V435/PPPS5Jefvllbdu2zbP/zJkzGj16tCTpqaeeUpUqVaz9ZUqg3N1iPHz48CL3R0VFafjw4YqNjVXPnj11+vRprVixQg899FAZVwgAIKsBIPCR1QCAYPTSSy/p3//+91X7+/Xrp0qVKkm6fEvvm2++Wej9Q4cO6bvvvivyj15/+ctftGXLFm3cuFE333yz7r77bmVnZysxMVGXLl3S7373O/385z+/6rwBAwboN7/5jf7+97+rffv26t69uyIjI5WYmKjz58+rY8eOeumllyz6zf1T7hqE19O+fXvP64JFJAEAgYWsBoDAR1YDAALRoUOHtHnz5qv2b9++3fPa1yc2R0REKCkpSX/72980f/58rVy5UpUqVVKHDh301FNPafDgwcWeO336dHXs2FFvvPGGNmzYoEuXLummm27ShAkTNHbsWE/T0m6OaxCuW7fO8/qmm26ysRIAQHHIagAIfGQ1ACAQzZkzR3PmzPH5vJSUlGu+X6lSJU2YMEETJkzweewHHnhADzzwgM/nlSVHNAjz8vJ04sQJrVixQpMmTZIkNW7cWH379i32+Ly8PM/PGRkZZVInADgZWQ0Agc/XrC44h7wGACCwlesGYXh4eKEvIwU6duyoBQsWKCwsrMjzEhIS9OKLL5Z2eQAAkdUAEAxKmtUSeQ0AQDAod08xvlJsbKxq1aqlyMhIz75u3brp9ddfV/369Ys9b+LEibpw4YJnS0tLK4tyAcCRyGoACHwlzWqJvAYAIBiU6wZhSkqKTp48qaysLJ06dUpTp07Vjh071K5dO88tEUUJCwtTTExMoQ0AUDrIagAIfCXNaom8BgAgGJTrBuGVatasqXHjxmn16tUyDEMvvfSSVqxYYXdZAIArkNUAEPjIagAAyh/HNAgLtGvXTp06dZIkzZw50+ZqAABFIasBIPCR1QAAlB+OaxBKUt26dSVJBw8etLkSAEBxyGoACHxk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\n",
1200
      "text/plain": [
1201
       "<Figure size 1400x1400 with 10 Axes>"
1202
      ]
1203
     },
1204
     "metadata": {},
1205
     "output_type": "display_data"
1206
    }
1207
   ],
1208
   "source": [
1209
    "fig, axes = plt.subplots(3, 3, figsize=(14, 14))\n",
1210
    "corr_vals = [y_predclean, y_predicts1, y_predicts2]\n",
1211
    "plt_plots = [1, 14, 25]\n",
1212
    "\n",
1213
    "cols = [\n",
1214
    "    \"From {}\".format(col)\n",
1215
    "    for col in [\"Exact Diagonalization\", \"Gaussian Kernel\", \"Neur. Tang. Kernel\"]\n",
1216
    "]\n",
1217
    "rows = [\"Model {}\".format(row) for row in plt_plots]\n",
1218
    "\n",
1219
    "for ax, col in zip(axes[0], cols):\n",
1220
    "    ax.set_title(col, fontsize=18)\n",
1221
    "\n",
1222
    "for ax, row in zip(axes[:, 0], rows):\n",
1223
    "    ax.set_ylabel(row, rotation=90, fontsize=24)\n",
1224
    "\n",
1225
    "for itr in range(3):\n",
1226
    "    for idx, corr_val in enumerate(corr_vals):\n",
1227
    "        shw = axes[itr][idx].imshow(\n",
1228
    "            np.array(corr_vals[idx]).T[plt_plots[itr]].reshape(Nr * Nc, Nr * Nc),\n",
1229
    "            cmap=plt.get_cmap(\"RdBu\"), vmin=-1, vmax=1,\n",
1230
    "        )\n",
1231
    "        axes[itr][idx].xaxis.set_ticks(range(Nr * Nc))\n",
1232
    "        axes[itr][idx].yaxis.set_ticks(range(Nr * Nc))\n",
1233
    "        axes[itr][idx].xaxis.set_tick_params(labelsize=18)\n",
1234
    "        axes[itr][idx].yaxis.set_tick_params(labelsize=18)\n",
1235
    "\n",
1236
    "fig.subplots_adjust(right=0.86)\n",
1237
    "cbar_ax = fig.add_axes([0.90, 0.15, 0.015, 0.71])\n",
1238
    "bar = fig.colorbar(shw, cax=cbar_ax)\n",
1239
    "\n",
1240
    "bar.set_label(r\"$C_{ij}$\", fontsize=18, rotation=0)\n",
1241
    "bar.ax.tick_params(labelsize=16)\n",
1242
    "plt.show()"
1243
   ]
1244
  },
1245
  {
1246
   "cell_type": "markdown",
1247
   "metadata": {
1248
    "id": "EY4jZ8bPlMUK"
1249
   },
1250
   "source": [
1251
    "Finally, we also attempt to showcase the effect of the size of training\n",
1252
    "data $N$ and the number of Pauli measurements $T$. For this, we look at\n",
1253
    "the average root-mean-square error (RMSE) in prediction for each kernel\n",
1254
    "over all two-point correlation functions $C_{ij}$. Here, the first plot\n",
1255
    "looks at the different training sizes $N$ with a fixed number of\n",
1256
    "randomized Pauli measurements $T=100$. In contrast, the second plot\n",
1257
    "looks at the different shadow sizes $T$ with a fixed training data size\n",
1258
    "$N=70$. The performance improvement seems to be saturating after a\n",
1259
    "sufficient increase in $N$ and $T$ values for all two kernels in both\n",
1260
    "the cases.\n"
1261
   ]
1262
  },
1263
  {
1264
   "cell_type": "markdown",
1265
   "metadata": {
1266
    "id": "E2XL6tE-lMUK"
1267
   },
1268
   "source": [
1269
    "![image](/demonstrations/ml_classical_shadows/rmse_training.png){width=\"47.0%\"}\n",
1270
    "\n",
1271
    "![image](/demonstrations/ml_classical_shadows/rmse_shadow.png){width=\"47.0%\"}\n"
1272
   ]
1273
  },
1274
  {
1275
   "cell_type": "markdown",
1276
   "metadata": {
1277
    "id": "NGuMg3dVlMUK"
1278
   },
1279
   "source": [
1280
    "Conclusion\n",
1281
    "==========\n",
1282
    "\n",
1283
    "This demo illustrates how classical machine learning models can benefit\n",
1284
    "from the classical shadow formalism for learning characteristics and\n",
1285
    "predicting the behavior of quantum systems. As argued in Ref., this\n",
1286
    "raises the possibility that models trained on experimental or quantum\n",
1287
    "data data can effectively address quantum many-body problems that cannot\n",
1288
    "be solved using classical methods alone.\n"
1289
   ]
1290
  },
1291
  {
1292
   "cell_type": "code",
1293
   "execution_count": 65,
1294
   "metadata": {},
1295
   "outputs": [
1296
    {
1297
     "name": "stdout",
1298
     "output_type": "stream",
1299
     "text": [
1300
      "Time in seconds since end of run: 1693283266.7257466\n",
1301
      "Tue Aug 29 04:27:46 2023\n"
1302
     ]
1303
    }
1304
   ],
1305
   "source": [
1306
    "seconds = time.time()\n",
1307
    "print(\"Time in seconds since end of run:\", seconds)\n",
1308
    "local_time = time.ctime(seconds)\n",
1309
    "print(local_time)"
1310
   ]
1311
  },
1312
  {
1313
   "cell_type": "markdown",
1314
   "metadata": {
1315
    "id": "hkYS-zIJlMUL"
1316
   },
1317
   "source": [
1318
    "References {#ml_classical_shadow_references}\n",
1319
    "==========\n",
1320
    "\n",
1321
    "About the author\n",
1322
    "================\n"
1323
   ]
1324
  }
1325
 ],
1326
 "metadata": {
1327
  "colab": {
1328
   "provenance": []
1329
  },
1330
  "kernelspec": {
1331
   "display_name": "Python 3 (ipykernel)",
1332
   "language": "python",
1333
   "name": "python3"
1334
  },
1335
  "language_info": {
1336
   "codemirror_mode": {
1337
    "name": "ipython",
1338
    "version": 3
1339
   },
1340
   "file_extension": ".py",
1341
   "mimetype": "text/x-python",
1342
   "name": "python",
1343
   "nbconvert_exporter": "python",
1344
   "pygments_lexer": "ipython3",
1345
   "version": "3.10.8"
1346
  },
1347
  "widgets": {
1348
   "application/vnd.jupyter.widget-state+json": {
1349
    "state": {},
1350
    "version_major": 2,
1351
    "version_minor": 0
1352
   }
1353
  }
1354
 },
1355
 "nbformat": 4,
1356
 "nbformat_minor": 4
1357
}