{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Quantum circuit Born machine (QCBM)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial you will implement your first QCBM and train it to generate a Gaussian distribution over integers." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Overview\n", "We first sample a trainingset from the Gaussian distribution. \n", "Then, we implement an ansatz of alternating parametrized rotation layers and entangling layers. \n", "Finally, we optimize the parameters with respect to the and we test how well the distribution of the QCBM matches the Gaussian distribution." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from scipy.optimize import minimize\n", "from time import time\n", "from functools import partial\n", "import cirq, sympy\n", "import matplotlib.pyplot as plt\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The hyperparameters" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "## Ansatz hyperparameters\n", "n_qubits = 3\n", "depth = 2\n", "n_params = 2 * depth * n_qubits\n", "\n", "# Begin with statevector simulator\n", "shots = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sampling the trainingdata" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def gaussian_pdf(num_bit, mu, sigma):\n", " '''get gaussian distribution function'''\n", " x = np.arange(2**num_bit)\n", " pl = 1. / np.sqrt(2 * np.pi * sigma**2) * \\\n", " np.exp(-(x - mu)**2 / (2. * sigma**2))\n", " return pl/pl.sum()\n", "\n", "pg = gaussian_pdf(n_qubits, mu=2**(n_qubits-1)-0.5, sigma=2**(n_qubits-2))\n", "plt.plot(pg, 'ro')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Implementing the ansatz" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Layer of single qubit z rotations\n", "def rot_z_layer(n_qubits, parameters):\n", " if n_qubits != len(parameters):\n", " raise ValueError(\"Too many or few parameters, must equal n_qubits\")\n", " for i in range(n_qubits):\n", " yield cirq.Rz(2 * parameters[i])(cirq.GridQubit(i, 0))\n", "\n", "# Layer of single qubit y rotations\n", "def rot_y_layer(n_qubits, parameters):\n", " if n_qubits != len(parameters):\n", " raise ValueError(\"Too many of few parameters, must equal n_qubits\")\n", " for i in range(n_qubits):\n", " yield cirq.Ry(parameters[i])(cirq.GridQubit(i, 0))\n", "\n", "# Layer of entangling CZ(i,i+1 % n_qubits) gates.\n", "def entangling_layer(n_qubits):\n", " if n_qubits == 2:\n", " yield cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(1, 0))\n", " return\n", " for i in range(n_qubits):\n", " yield cirq.CZ(cirq.GridQubit(i, 0), cirq.GridQubit((i+1) % n_qubits, 0))\n", "\n", "# Variational circuit, i.e., the ansatz.\n", "def variational_circuit(n_qubits, depth, theta):\n", " if len(theta) != (2 * depth * n_qubits):\n", " raise ValueError(\"Theta of incorrect dimension, must equal 2*depth*n_qubits\")\n", " \n", " # Initializing qubits and circuit\n", " qubits = [cirq.GridQubit(i, 0) for i in range(n_qubits)]\n", " circuit = cirq.Circuit()\n", " \n", " # Adding layers of rotation gates and entangling gates.\n", " for d in range(depth):\n", " # Adding single qubit rotations\n", " circuit.append(rot_z_layer(n_qubits, theta[d * 2 * n_qubits : (d+1) * 2 * n_qubits : 2]))\n", " circuit.append(rot_y_layer(n_qubits, theta[d * 2 * n_qubits + 1 : (d+1) * 2 * n_qubits + 1 : 2]))\n", " # Adding entangling layer\n", " circuit.append(entangling_layer(n_qubits))\n", " \n", " return circuit" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " (0, 0) (1, 0) (2, 0)\n", " │ │ │\n", " Rz(2*theta_0) Rz(2*theta_2) Rz(2*theta_4)\n", " │ │ │\n", " Ry(theta_1) Ry(theta_3) Ry(theta_5)\n", " │ │ │\n", " @─────────────@ │\n", " │ │ │\n", " │ @─────────────@\n", " │ │ │\n", "┌╴│ │ │ ╶┐\n", "│ @─────────────┼─────────────@ │\n", "│ │ Rz(2*theta_8) │ │\n", "└╴│ │ │ ╶┘\n", " │ │ │\n", " Rz(2*theta_6) Ry(theta_9) Rz(2*theta_10)\n", " │ │ │\n", " Ry(theta_7) │ Ry(theta_11)\n", " │ │ │\n", " @─────────────@ │\n", " │ │ │\n", " │ @─────────────@\n", " │ │ │\n", " @─────────────┼─────────────@\n", " │ │ │\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/casper/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6: DeprecationWarning: Rz was used but is deprecated.\n", "It will be removed in cirq v0.8.0.\n", "Use cirq.rz, instead.\n", "\n", " \n", "/home/casper/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:13: DeprecationWarning: Ry was used but is deprecated.\n", "It will be removed in cirq v0.8.0.\n", "Use cirq.ry, instead.\n", "\n", " del sys.path[0]\n" ] } ], "source": [ "theta_entry_symbols = [sympy.Symbol('theta_' + str(i)) for i in range(2 * n_qubits * depth)]\n", "theta_symbol = sympy.Matrix(theta_entry_symbols)\n", "ansatz = variational_circuit(n_qubits, depth, theta_symbol)\n", "print(ansatz.to_text_diagram(transpose=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Implementing the Loss Function" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# Estimate all probabilities of the PQCs distribution.\n", "def estimate_probs(circuit, theta, n_shots=shots):\n", " # Creating parameter resolve dict by adding state and theta.\n", " try:\n", " theta_mapping = [('theta_' + str(i), theta[i]) for i in range(len(theta))]\n", " except IndexError as error:\n", " print(\"Could not resolve theta symbol, array of wrong size.\")\n", " resolve_dict = dict(theta_mapping)\n", " resolver = cirq.ParamResolver(resolve_dict)\n", " resolved_circuit = cirq.resolve_parameters(circuit, resolver)\n", " \n", " # Use statevector simulator\n", " if n_shots == 0:\n", " final_state = cirq.final_wavefunction(resolved_circuit)\n", " probs = np.array([abs(final_state[i])**2 for i in range(len(final_state))])\n", " \n", " # Run the circuit.\n", " else:\n", " # Adding measurement at the end.\n", " resolved_circuit.append(cirq.measure(*resolved_circuit.all_qubits(), key='m'))\n", " results = cirq.sample(resolved_circuit, repetitions=n_shots)\n", " frequencies = results.histogram(key='m')\n", " probs = np.zeros(2**n_qubits)\n", " for key, value in frequencies.items():\n", " probs[key] = value / n_shots\n", " \n", " return probs\n", "\n", "# Function that computes the kernel for the MMD loss\n", "def multi_rbf_kernel(x, y, sigma_list):\n", " '''\n", " multi-RBF kernel.\n", " \n", " Args:\n", " x (1darray|2darray): the collection of samples A.\n", " x (1darray|2darray): the collection of samples B.\n", " sigma_list (list): a list of bandwidths.\n", " \n", " Returns:\n", " 2darray: kernel matrix.\n", " '''\n", " ndim = x.ndim\n", " if ndim == 1:\n", " exponent = np.abs(x[:, None] - y[None, :])**2\n", " elif ndim == 2:\n", " exponent = ((x[:, None, :] - y[None, :, :])**2).sum(axis=2)\n", " else:\n", " raise\n", " K = 0.0\n", " for sigma in sigma_list:\n", " gamma = 1.0 / (2 * sigma)\n", " K = K + np.exp(-gamma * exponent)\n", " return K\n", "\n", "# Function that computes expectation of kernel in MMD loss\n", "def kernel_expectation(px, py, kernel_matrix):\n", " return px.dot(kernel_matrix).dot(py)\n", "\n", "# Function that computes the squared MMD loss related to the given kernel_matrix.\n", "def squared_MMD_loss(probs, target, kernel_matrix):\n", " dif_probs = probs - target\n", " return kernel_expectation(dif_probs,dif_probs,kernel_matrix)\n", "\n", "# The loss function that we aim to minimize.\n", "def loss(theta, circuit, target, kernel_matrix, n_shots=shots):\n", " probs = estimate_probs(circuit, theta, n_shots=n_shots)\n", " return squared_MMD_loss(probs, target, kernel_matrix)\n", "\n", "# Cheat and get gradient.\n", "def gradient(theta, target, kernel_matrix, n_shots=shots):\n", " prob = estimate_probs(ansatz, theta, n_shots=shots)\n", " grad = []\n", " for i in range(len(theta)):\n", " # pi/2 phase\n", " theta[i] += np.pi/2.\n", " prob_pos = estimate_probs(ansatz, theta, n_shots=shots)\n", " # -pi/2 phase\n", " theta[i] -= np.pi\n", " prob_neg = estimate_probs(ansatz, theta, n_shots=shots)\n", " # recover\n", " theta[i] += np.pi/2.\n", " grad_pos = kernel_expectation(prob, prob_pos, kernel_matrix) - kernel_expectation(prob, prob_neg, kernel_matrix)\n", " grad_neg = kernel_expectation(target, prob_pos, kernel_matrix) - kernel_expectation(target, prob_neg, kernel_matrix)\n", " grad.append(grad_pos - grad_neg)\n", " return np.array(grad)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "step = 1, loss = 0.14316100196289158\n", "step = 2, loss = 0.08440857762274066\n", "step = 3, loss = 0.06814258963291457\n", "step = 4, loss = 0.046192077974273195\n", "step = 5, loss = 0.018501963381051322\n", "step = 6, loss = 0.004226420705095475\n", "step = 7, loss = 0.002011254589633399\n", "step = 8, loss = 0.0016714309945646824\n", "step = 9, loss = 0.001393748695381338\n", "step = 10, loss = 0.0009725148906202676\n", "step = 11, loss = 0.0006228965941684052\n", "step = 12, loss = 0.00044505640080219736\n", "step = 13, loss = 0.0002456842381173457\n", "step = 14, loss = 0.00023773055833462763\n", "step = 15, loss = 0.00017031406477115813\n", "step = 16, loss = 0.00014949208735561874\n", "step = 17, loss = 0.00010857848321752927\n", "step = 18, loss = 9.046478293152856e-05\n", "step = 19, loss = 6.399932474980324e-05\n", "step = 20, loss = 4.897463290484894e-05\n", "step = 21, loss = 4.1633627323200655e-05\n", "step = 22, loss = 3.5902733254633684e-05\n", "step = 23, loss = 3.0399670151340435e-05\n", "step = 24, loss = 2.6420557442611562e-05\n", "step = 25, loss = 2.2346237766263288e-05\n", "step = 26, loss = 1.9531611374807113e-05\n", "step = 27, loss = 1.838399859009292e-05\n", "step = 28, loss = 1.686424326143705e-05\n", "step = 29, loss = 1.6024562077525377e-05\n", "step = 30, loss = 1.5385974644829547e-05\n", "step = 31, loss = 1.4990051359948933e-05\n", "step = 32, loss = 1.4783677077664796e-05\n", "step = 33, loss = 1.471020061799454e-05\n", "step = 34, loss = 1.4698505505502302e-05\n", "step = 35, loss = 1.4697687964518195e-05\n", "step = 36, loss = 1.4697595304146004e-05\n", "step = 37, loss = 1.4697482747546985e-05\n", "step = 38, loss = 1.4697482387878364e-05\n", "step = 39, loss = 1.4697311812174217e-05\n", "step = 40, loss = 1.4697311812174217e-05\n", "34.69187378883362\n" ] } ], "source": [ "# MMD kernel\n", "basis = np.arange(2**n_qubits)\n", "sigma_list = [0.25,4]\n", "kernel_matrix = multi_rbf_kernel(basis, basis, sigma_list)\n", "\n", "# Initial theta\n", "theta0 = np.random.random(n_params)*2*np.pi\n", "\n", "# Initializing loss function with our ansatz, target and kernel matrix\n", "loss_ansatz = partial(loss, circuit=ansatz, target=pg, kernel_matrix=kernel_matrix)\n", "\n", "# Callback function to track status \n", "step = [0]\n", "tracking_cost = []\n", "def callback(x, *args, **kwargs):\n", " step[0] += 1\n", " tracking_cost.append(loss_ansatz(x))\n", " print('step = %d, loss = %s'%(step[0], loss_ansatz(x)))\n", "\n", "# Training the QCBM.\n", "start_time = time()\n", "final_params = minimize(loss_ansatz,\n", " theta0, \n", " method=\"L-BFGS-B\", \n", " jac=partial(gradient, target=pg, kernel_matrix=kernel_matrix),\n", " tol=10**-5, \n", " options={'maxiter':50, 'disp': 0, 'gtol':1e-10, 'ftol':0}, \n", " callback=callback)\n", "end_time = time()\n", "print(end_time-start_time)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Looking at final parameters, its cost function and the generated distribution." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " fun: 1.4697311812174217e-05\n", " hess_inv: <12x12 LbfgsInvHessProduct with dtype=float64>\n", " jac: array([ 0.00000000e+00, -1.79241186e-07, 0.00000000e+00, -7.89987431e-09,\n", " 0.00000000e+00, 4.43426241e-08, 0.00000000e+00, 1.09666788e-07,\n", " 0.00000000e+00, -3.56061365e-08, 0.00000000e+00, 5.79055581e-09])\n", " message: b'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH'\n", " nfev: 61\n", " nit: 40\n", " status: 0\n", " success: True\n", " x: array([1.43085857, 4.71294603, 3.86389339, 5.81117531, 0.49743146,\n", " 0.2151291 , 4.28464128, 6.28417168, 6.19759606, 4.71266256,\n", " 0.02028919, 1.57070521])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "final_params" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(list(range(len(tracking_cost))), tracking_cost)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8li6FKAAAVEklEQVR4nO3df4zcd33n8efLdgzdcJA0WVXUv9ZtTNWlRUAn5jhKqEhJ7bvKbiXnzmZ7l1RI21Mvp1YUtelVajgj/wHcATrVqrIiQYFuatK0nHzXUBMdSLQn4Dw2kNzGuF18/rE+2iwkQF2LS41f98d8g8aT3Z3ven/MzGdfD2k18/18Pt/vvmc185rvfr4z369sExER5VrX6wIiImJlJegjIgqXoI+IKFyCPiKicAn6iIjCbeh1AZ1uvfVWj4yM9LqMiIiBcuLEiW/aHp6rr++CfmRkhGaz2esyIiIGiqRz8/Vl6iYionAJ+oiIwiXoIyIKl6CPiChcgj4ionAJ+ijL5CSMjMC6da3bycleV7SwQas3BlLffbwy4rpNTsL4OFy+3Fo+d661DDA21ru65jNo9cbAUr+dprjRaDifo4/rMjLSCstO27bB2bOrXU13g1Zv9DVJJ2w35urL1E2U4/z5xbX32qDVGwOrVtBL2iXptKRpSffP0f9uSc9IekrS/5C0ra3vHkl/U/3cs5zFR1xj69bFtffaoNUbA6tr0EtaDxwGdgOjwAFJox3Dvgw0bL8OeBz4QLXuDwMPAG8CdgIPSLp5+cqPaHPoEAwNXds2NNRq70eDVm8MrDp79DuBadtnbL8AHAH2tg+w/Tnb1RElvghsru7/AvCk7edsPw88CexantIjOoyNwcREa45bat1OTPTvgc1BqzcGVp1P3WwCLrQtz9DaQ5/Pu4BPL7Dups4VJI0D4wBb829rLMXY2GAF5aDVGwNpWQ/GSvoVoAF8cDHr2Z6w3bDdGB6e8yybERFxneoE/UVgS9vy5qrtGpJ+Hvg9YI/t/7eYdSMiYuXUCfrjwA5J2yVtBPYDR9sHSHoD8CCtkH+2resYcJekm6uDsHdVbRERsUq6ztHbviLpPloBvR542PaUpINA0/ZRWlM1rwD+RBLAedt7bD8n6X203iwADtp+bkUeSUREzCnfjI2IKEC+GRsRsYYl6CMiCpegj4goXII+IqJwCfqIiMIl6CMiCpegj4goXII+IqJwCfqIiMIl6CMiCpegj4goXII+IqJwCfqIiMIl6CMiCpegj4goXII+IqJwCfqIiMLVCnpJuySdljQt6f45+u+QdFLSFUn7Ovo+IGlK0ilJ/0XVtQYjImJ1dA16SeuBw8BuYBQ4IGm0Y9h54F7g0Y51/xnwFuB1wE8BtwNvW3LVERFRW9eLgwM7gWnbZwAkHQH2As+8OMD22arvase6Bl4ObAQE3AD83ZKrjoiI2upM3WwCLrQtz1RtXdn+AvA54BvVzzHbpzrHSRqX1JTUnJ2drbPpiIioaUUPxkq6DfhJYDOtN4e3S3pr5zjbE7YbthvDw8MrWVJExJpTJ+gvAlvaljdXbXX8MvBF25dsXwI+Dbx5cSVGRMRS1An648AOSdslbQT2A0drbv888DZJGyTdQOtA7EumbiIiYuV0DXrbV4D7gGO0Qvox21OSDkraAyDpdkkzwN3Ag5KmqtUfB74OPA18Ffiq7f+2Ao8jIiLmIdu9ruEajUbDzWaz12VERAwUSSdsN+bqyzdjIyIKl6CPiChcgj4ionAJ+oiIwiXoIyIKl6CPiChcgj4ionAJ+oiIwiXoIyIKl6CPiChcgj4ionAJ+oiIwiXoIyIKl6CPiChcgj4ionAJ+oiIwtUKekm7JJ2WNC3p/jn675B0UtIVSfs6+rZK+oykU5KekTSyPKVHREQdXYNe0nrgMLAbGAUOSBrtGHYeuBd4dI5NfBz4oO2fBHYCzy6l4IiIWJwNNcbsBKZtnwGQdATYCzzz4gDbZ6u+q+0rVm8IG2w/WY27tDxlR0REXXWmbjYBF9qWZ6q2Ol4DfFvSn0n6sqQPVv8hXEPSuKSmpObs7GzNTUdERB0rfTB2A/BW4D3A7cCP0ZriuYbtCdsN243h4eEVLikiYm2pE/QXgS1ty5urtjpmgK/YPmP7CvBfgTcursTouclJGBmBdetat5OTva4oeiHPg4FVZ47+OLBD0nZaAb8feGfN7R8HbpI0bHsWeDvQvK5KozcmJ2F8HC5fbi2fO9daBhgb611dsbryPBhost19kPTPgY8A64GHbR+SdBBo2j4q6XbgU8DNwPeAv7X92mrddwD/GRBwAhi3/cJ8v6vRaLjZzHtB3xgZab2oO23bBmfPrnY10St5HvQ9SSdsN+bsqxP0qylB32fWrYO5niMSXL360vYoU54HfW+hoM83Y2NhW7curj3KlOfBQEvQx8IOHYKhoWvbhoZa7bF25Hkw0BL0sbCxMZiYaM3FSq3biYkcgFtr8jwYaJmjj4goQOboIyLWsAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYVL0EdEFK5W0EvaJem0pGlJ98/Rf4ekk5KuSNo3R/8rJc1I+oPlKDoiIurrGvSS1gOHgd3AKHBA0mjHsPPAvcCj82zmfcDnr7/MiIi4XnX26HcC07bPVNd6PQLsbR9g+6ztp4CXXFNM0s8APwJ8ZhnqjYiIRaoT9JuAC23LM1VbV5LW0bow+Hu6jBuX1JTUnJ2drbPpiIioaaUPxv468ITtmYUG2Z6w3bDdGB4eXuGSIiLWlg01xlwEtrQtb67a6ngz8FZJvw68Atgo6ZLtlxzQjYiIlVEn6I8DOyRtpxXw+4F31tm47R9cUFLSvUAjIR8Rsbq6Tt3YvgLcBxwDTgGP2Z6SdFDSHgBJt0uaAe4GHpQ0tZJFR0REfbk4eEREAXJx8IiINSxBHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYWrFfSSdkk6LWla0ksuBSjpDkknJV2RtK+t/fWSviBpStJTkv7VchYfERHddQ16SeuBw8BuYBQ4IGm0Y9h54F7g0Y72y8C/sf1aYBfwEUk3LbXoiIior87FwXcC07bPAEg6AuwFnnlxgO2zVd/V9hVt/3Xb/f8r6VlgGPj2kiuPiIha6kzdbAIutC3PVG2LImknsBH4+hx945Kakpqzs7OL3XRERCxgVQ7GSno18AngV21f7ey3PWG7YbsxPDy8GiVFRKwZdYL+IrClbXlz1VaLpFcCfw78nu0vLq68iIhYqjpBfxzYIWm7pI3AfuBonY1X4z8FfNz249dfZkREXK+uQW/7CnAfcAw4BTxme0rSQUl7ACTdLmkGuBt4UNJUtfq/BO4A7pX0lern9SvySCIiYk6y3esartFoNNxsNntdRkTEQJF0wnZjrr58MzYionAJ+oiIwiXoIyIKl6CPiChcgj4ionAJ+oiIwiXoIyIKl6CPiChcgj4ionAJ+oiIwiXoIyIKl6CPiChcgj4ionAJ+oiIwiXoIyIKl6CPiChcraCXtEvSaUnTku6fo/8OSSclXZG0r6PvHkl/U/3cs1yFR0REPV2DXtJ64DCwGxgFDkga7Rh2HrgXeLRj3R8GHgDeBOwEHpB089LLjoiIuurs0e8Epm2fsf0CcATY2z7A9lnbTwFXO9b9BeBJ28/Zfh54Eti1DHVHRERNdYJ+E3ChbXmmaquj1rqSxiU1JTVnZ2drbjoiIuroi4OxtidsN2w3hoeHe11ORERR6gT9RWBL2/Lmqq2OpawbERHLoE7QHwd2SNouaSOwHzhac/vHgLsk3VwdhL2raouIiFXSNehtXwHuoxXQp4DHbE9JOihpD4Ck2yXNAHcDD0qaqtZ9DngfrTeL48DBqi0iIlZJrTl620/Yfo3tH7d9qGr7fdtHq/vHbW+2faPtW2y/tm3dh23fVv18bGUexoCZnISREVi3rnU7OdnriiLKk9fZD2zodQFrzuQkjI/D5cut5XPnWssAY2O9qyuiJHmdXUO2e13DNRqNhpvNZq/LWDkjI60nXadt2+Ds2dWuJqJMa/B1JumE7cZcfX3x8co15fz5xbVHxOLldXaNBP1q27p1ce0RsXh5nV0jQb/aDh2CoaFr24aGWu0RsTzyOrtGgn61jY3BxERrrlBq3U5MrMkDRBErJq+za+RgbEREAXIwNiJiDUvQR0QULkEfEVG4BH1EROES9BERhUvQR0QULkEfEVG4BH1EROES9BERhasV9JJ2STotaVrS/XP0v0zSJ6v+L0kaqdpvkPSIpKclnZL0u8tbfkREdNM16CWtBw4Du4FR4ICk0Y5h7wKet30b8GHg/VX73cDLbP808DPAr734JhAREaujzh79TmDa9hnbLwBHgL0dY/YCj1T3HwfulCTAwI2SNgA/BLwAfHdZKo+IiFrqBP0m4ELb8kzVNueY6mLi3wFuoRX6/wB8AzgP/KdcHDwiYnWt9MHYncD3gR8FtgO/JenHOgdJGpfUlNScnZ1d4ZIiItaWOkF/EdjStry5aptzTDVN8yrgW8A7gb+w/Y+2nwX+J/CS02janrDdsN0YHh5e/KOIiIh51Qn648AOSdslbQT2A0c7xhwF7qnu7wM+69aJ7s8DbweQdCPwT4GvLUfhERFRT9egr+bc7wOOAaeAx2xPSTooaU817CHgFknTwLuBFz+CeRh4haQpWm8YH7P91HI/iIiImF+uMBURUYBcYSoiYg1L0EdEFC5BHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYWrFfSSdkk6LWla0v1z9L9M0ier/i9JGmnre52kL0iakvS0pJcvX/kREdFN16CXtJ7WtV93A6PAAUmjHcPeBTxv+zbgw8D7q3U3AH8E/FvbrwV+DvjHZas+IiK6qrNHvxOYtn3G9gvAEWBvx5i9wCPV/ceBOyUJuAt4yvZXAWx/y/b3l6f0iIioo07QbwIutC3PVG1zjrF9BfgOcAvwGsCSjkk6Kem35/oFksYlNSU1Z2dnF/sYIiJiASt9MHYD8LPAWHX7y5Lu7Bxke8J2w3ZjeHh4hUuKiFhb6gT9RWBL2/Lmqm3OMdW8/KuAb9Ha+/+87W/avgw8AbxxqUVHRER9dYL+OLBD0nZJG4H9wNGOMUeBe6r7+4DP2jZwDPhpSUPVG8DbgGeWp/SIiKhjQ7cBtq9Iuo9WaK8HHrY9Jekg0LR9FHgI+ISkaeA5Wm8G2H5e0odovVkYeML2n6/QY4mIiDmotePdPxqNhpvNZq/LiIgYKJJO2G7M1ZdvxkZEFC5BHxFRuAR9REThEvQREYVL0EdEFC5BHxFRuAR9REThEvQREYUrJ+gnJ2FkBNata91OTva6ooiIelY4v7qeAmEgTE7C+DhcvtxaPneutQwwNta7uiIiulmF/CrjFAgjI60/Tqdt2+Ds2eUoKyJiZSxTfpV/CoTz5xfXHhHRL1Yhv8oI+q1bF9ceEdEvViG/ygj6Q4dgaOjatqGhVntERD9bhfwqI+jHxmBiojWnJbVuJyZyIDYi+t8q5FcZB2MjIta4JR+MlbRL0mlJ05Lun6P/ZZI+WfV/SdJIR/9WSZckved6HkBERFy/rkEvaT1wGNgNjAIHJI12DHsX8Lzt24APA+/v6P8Q8OmllxsREYtVZ49+JzBt+4ztF4AjwN6OMXuBR6r7jwN3ShKApF8C/g8wtTwlR0TEYtQJ+k3AhbblmaptzjG2rwDfAW6R9Argd4D/uNAvkDQuqSmpOTs7W7f2iIioYaU/dfNe4MO2Ly00yPaE7YbtxvDw8AqXFBGxttQ5181FYEvb8uaqba4xM5I2AK8CvgW8Cdgn6QPATcBVSd+z/Qfz/bITJ058U9Ic3weu7Vbgm0tYfzUNUq0wWPUOUq0wWPUOUq0wWPUupdZt83XUCfrjwA5J22kF+n7gnR1jjgL3AF8A9gGfdetzm299cYCk9wKXFgp5ANtL2qWX1JzvI0b9ZpBqhcGqd5BqhcGqd5BqhcGqd6Vq7Rr0tq9Iug84BqwHHrY9Jekg0LR9FHgI+ISkaeA5Wm8GERHRB2qdptj2E8ATHW2/33b/e8DdXbbx3uuoLyIilqiMUyBca6LXBSzCINUKg1XvINUKg1XvINUKg1XvitTad6dAiIiI5VXiHn1ERLRJ0EdEFK6YoO924rV+IulhSc9K+t+9rqUbSVskfU7SM5KmJP1Gr2taiKSXS/pfkr5a1bvgt7L7gaT1kr4s6b/3upZuJJ2V9LSkr0jq69PMSrpJ0uOSvibplKQ397qm+Uj6iepv+uLPdyX95rJtv4Q5+urEa38NvIPWKRqOAwdsP9PTwuYh6Q7gEvBx2z/V63oWIunVwKttn5T0T4ATwC/18d9WwI22L0m6Afgr4Ddsf7HHpc1L0ruBBvBK27/Y63oWIuks0LDd919AkvQI8Je2PyppIzBk+9u9rqubKs8uAm+yvZQvj/5AKXv0dU681jdsf57W9w36nu1v2D5Z3f974BQvPddR33DLi6fcuKH66du9GUmbgX8BfLTXtZRE0quAO2h9xwfbLwxCyFfuBL6+XCEP5QR9nROvxRJV1xl4A/Cl3laysGoq5CvAs8CTtvu53o8Avw1c7XUhNRn4jKQTksZ7XcwCtgOzwMeqabGPSrqx10XVtB/44+XcYClBHyusOhPpnwK/afu7va5nIba/b/v1tM7LtFNSX06PSfpF4FnbJ3pdyyL8rO030ro+xb+rpiH70QbgjcAf2n4D8A9AXx+7A6immPYAf7Kc2y0l6OuceC2uUzXX/afApO0/63U9dVX/qn8O2NXrWubxFmBPNe99BHi7pD/qbUkLs32xun0W+BStadN+NAPMtP039zit4O93u4GTtv9uOTdaStD/4MRr1TviflonWoslqg5uPgScsv2hXtfTjaRhSTdV93+I1gH6r/W2qrnZ/l3bm22P0HrOftb2r/S4rHlJurE6IE81DXIX0JefHLP9t8AFST9RNd0J9OUHCDocYJmnbaDmuW763XwnXutxWfOS9MfAzwG3SpoBHrD9UG+rmtdbgH8NPF3NewP8h+r8R/3o1cAj1ScX1gGP2e77jy0OiB8BPlVdPG4D8Kjtv+htSQv698BktfN3BvjVHtezoOrN8x3Ary37tkv4eGVERMyvlKmbiIiYR4I+IqJwCfqIiMIl6CMiCpegj4goXII+IqJwCfqIiML9f+GtmsTGj0WoAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(estimate_probs(ansatz, final_params.x), 'ro')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }