diff --git a/doc/source/api-reference/qibo.rst b/doc/source/api-reference/qibo.rst index 8a3fe4f245..a4c0491877 100644 --- a/doc/source/api-reference/qibo.rst +++ b/doc/source/api-reference/qibo.rst @@ -194,23 +194,6 @@ Iterative Quantum Amplitude Estimation (IQAE) :member-order: bysource -Double Bracket Iteration algorithm for Diagonalization -"""""""""""""""""""""""""""""""""""""""""""""""""""""" - -The Double Bracket Flow (DBF) has been presented `here `_ -as a novel strategy for preparing eigenstates of a quantum system. We implement in -Qibo a discretized version of the algorithm, which executes sequential Double -Bracket Iterations. - -.. autoclass:: qibo.models.dbi.double_bracket.DoubleBracketGeneratorType - :members: - :member-order: bysource - -.. autoclass:: qibo.models.dbi.double_bracket.DoubleBracketIteration - :members: - :member-order: bysource - - .. _timeevolution: Time evolution diff --git a/doc/source/code-examples/tutorials/dbi/README.md b/doc/source/code-examples/tutorials/dbi/README.md deleted file mode 120000 index 50b9e9eaec..0000000000 --- a/doc/source/code-examples/tutorials/dbi/README.md +++ /dev/null @@ -1 +0,0 @@ -../../../../../examples/dbi/README.md \ No newline at end of file diff --git a/doc/source/code-examples/tutorials/dbi/dbi_tutorial_basic_intro.ipynb b/doc/source/code-examples/tutorials/dbi/dbi_tutorial_basic_intro.ipynb deleted file mode 120000 index 79ea4d0ea8..0000000000 --- a/doc/source/code-examples/tutorials/dbi/dbi_tutorial_basic_intro.ipynb +++ /dev/null @@ -1 +0,0 @@ -../../../../../examples/dbi/dbi_tutorial_basic_intro.ipynb \ No newline at end of file diff --git a/examples/dbi/README.md b/examples/dbi/README.md deleted file mode 100644 index 76640ff99f..0000000000 --- a/examples/dbi/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Double-bracket quantum algorithms - -Qibo features a model implementing double-bracke quantum algorithms (DBQAs) which are helpful for approximating eigenstates based on the ability to run the evolution under the input Hamiltonian. - -More specifically, given a Hamiltonian $H_0$, how can we find a circuit which after applying to the reference state (usually $|0\rangle^{\otimes L}$ for $L$ qubits) will approximate an eigenstate? - -A standard way is to run variational quantum circuits. For example, Qibo already features the `VQE` model [2] which provides the implementation of the variational quantum eigensolver framework. -DBQAs allow to go beyond VQE in that they take a different approach to compiling the quantum circuit approximating the eigenstate. - -## What is the unitary of DBQA? - -Given $H_0$ we begin by assuming that we were given a diagonal and hermitian operator $D_0$ and a time $s_0$. -The `dbi` module provides numerical strategies for selecting them. -For any such choice we define the bracket -$$ W_0 = [D_0, H_0]$$ -and the double-bracket rotation (DBR) of the input Hamiltonian to time $s$ -$$H_0(s) = e^{sW} H e^{- s W}$$ - -### Why are double-bracket rotations useful? -We can show that the magnitude of the off-diagonal norms will decrease. -For this let us set the notation that $\sigma(A)$ is the restriction to the off-diagonal of the matrix A. -In `numpy` this can be implemented by `\sigma(A) = A-np.diag(A)`. In Qibo we implement this as -https://github.com/qiboteam/qibo/blob/8c9c610f5f2190b243dc9120a518a7612709bdbc/src/qibo/models/dbi/double_bracket.py#L145-L147 -which is part of the basic `DoubleBracketIteration` class in the `dbi` module. - -With this notation we next use the Hilbert-Schmidt scalar product and norm to measure the progress of diagonalization - $$||\sigma(H_0(s))||^2- ||\sigma (H_0 )||^2= -2s \langle W, [H,\sigma(H)\rangle+O(s^2)$$ -This equation tells us that as long as the scalar product $\langle W, [H,\sigma(H)\rangle$ is positive then after the DBR the magnitude of the off-diagonal couplings in $H_0(s)$ is less than in $H_0$. - -For the implementation of the DBR unitary $U_0(s) = e^{-s W_0}$ see -https://github.com/qiboteam/qibo/blob/363a6e5e689e5b907a7602bd1cc8d9811c60ee69/src/qibo/models/dbi/double_bracket.py#L68 - -### How to choose $D$? - -For theoretical considerations the canonical bracket is useful. -For this we need the notation of the dephasing channel $\Delta(H)$ which is equivalent to `np.diag(h)`. - $M = [\Delta(H),\sigma(H)]= [H,\sigma(H)]= [\Delta(H),H]$ - The canonical bracket appears on its own in the monotonicity relation above and gives an unconditional reduction of the magnitude of the off-diagonal terms - $$||\sigma(H_0(s))||^2- ||\sigma (H_0 )||^2= -2s ||M||^2+O(s^2)$$ -- the multi qubit Pauli Z generator with $Z(\mu) = (Z_1)^{\mu_1}\ldots (Z_L)^{\mu_L}$ where we optimize over all binary strings $\mu\in \{0,1\}^L$ -- the magnetic field $D = \sum_i B_i Z_i$ -- the two qubit Ising model $D = \sum_i B_i Z_i + \sum_{i,j} J_{i,j} Z_i Z_j$, please follow the tutorial by Matteo and use the QIBO ising model for that with $h=0$ - - -### How to choose s? - -The theory above shows that in generic cases the DBR will have a linear diagonalization effect (as quantified by $||\sigma(H_0(s))||$). -This can be further expanded with Taylor expansion and the Qibo implementation comes with methods for fitting the first local minimum. -Additionally a grid search for the optimal step is provided for an exhaustive evaluation and hyperopt can be used for a more efficient 'unstructured' optimization; additionally simulated annealing is provided which sometimes outperforms hyperopt (and grid search), see example notebooks. -The latter methods may output DBR durations $s_k$ which correspond to secondary local minima. - - - - - -[1] https://arxiv.org/abs/2206.11772 - -[2] https://github.com/qiboteam/vqe-sun diff --git a/examples/dbi/dbi_tutorial_basic_intro.ipynb b/examples/dbi/dbi_tutorial_basic_intro.ipynb deleted file mode 100644 index 5a722341ea..0000000000 --- a/examples/dbi/dbi_tutorial_basic_intro.ipynb +++ /dev/null @@ -1,782 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "2a33581d", - "metadata": {}, - "source": [ - "## Double-Bracket Iteration diagonalization algorithm\n", - "\n", - "In this example we present the `Qibo`'s implementation of the Double-Bracket Iteration (DBI) algorithm, which can be used to prepare the eigenstates of a quantum system. \n", - "\n", - "#### The initial setup\n", - "\n", - "At first we import some useful packages." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "62d9723f", - "metadata": {}, - "outputs": [], - "source": [ - "# uncomment this line if seaborn is not installed\n", - "# !python -m pip install seaborn" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "b80b4738", - "metadata": {}, - "outputs": [], - "source": [ - "from copy import deepcopy\n", - "\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "\n", - "import optuna\n", - "\n", - "from qibo import hamiltonians, set_backend\n", - "from qibo.models.dbi.double_bracket import DoubleBracketGeneratorType, DoubleBracketIteration, DoubleBracketScheduling" - ] - }, - { - "cell_type": "markdown", - "id": "a5e25f51", - "metadata": {}, - "source": [ - "Here we define a simple plotting function useful to keep track of the diagonalization process." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "933d9a00", - "metadata": {}, - "outputs": [], - "source": [ - "def visualize_matrix(matrix, title=\"\"):\n", - " \"\"\"Visualize hamiltonian in a heatmap form.\"\"\"\n", - " fig, ax = plt.subplots(figsize=(5,5))\n", - " ax.set_title(title)\n", - " try:\n", - " im = ax.imshow(np.absolute(matrix), cmap=\"inferno\")\n", - " except TypeError:\n", - " im = ax.imshow(np.absolute(matrix.get()), cmap=\"inferno\")\n", - " fig.colorbar(im, ax=ax)\n", - "\n", - "def visualize_drift(h0, h):\n", - " \"\"\"Visualize drift of the evolved hamiltonian w.r.t. h0.\"\"\"\n", - " fig, ax = plt.subplots(figsize=(5,5))\n", - " ax.set_title(r\"Drift: $|\\hat{H}_0 - \\hat{H}_{\\ell}|$\")\n", - " try:\n", - " im = ax.imshow(np.absolute(h0 - h), cmap=\"inferno\")\n", - " except TypeError:\n", - " im = ax.imshow(np.absolute((h0 - h).get()), cmap=\"inferno\")\n", - "\n", - " fig.colorbar(im, ax=ax)\n", - "\n", - "def plot_histories(histories, labels):\n", - " \"\"\"Plot off-diagonal norm histories over a sequential evolution.\"\"\"\n", - " colors = sns.color_palette(\"inferno\", n_colors=len(histories)).as_hex()\n", - " plt.figure(figsize=(5,5*6/8))\n", - " for i, (h, l) in enumerate(zip(histories, labels)):\n", - " plt.plot(h, lw=2, color=colors[i], label=l, marker='.')\n", - " plt.legend()\n", - " plt.xlabel(\"Iterations\")\n", - " plt.ylabel(r\"$\\| \\sigma(\\hat{H}) \\|^2$\")\n", - " plt.title(\"Loss function histories\")\n", - " plt.grid(True)\n", - " plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "4efd4a97", - "metadata": {}, - "source": [ - "We need to define a target hamiltonian which we aim to diagonalize. As an example, we consider the Transverse Field Ising Model (TFIM):\n", - "$$ H_{\\rm TFIM} = - \\sum_{q=0}^{N}\\bigl( Z_i Z_{i+1} + h X_i \\bigr),$$\n", - "which is already implemented in `Qibo`. For this tutorial we set $N=6$ and $h=3$." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7125940f", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[Qibo 0.2.12|INFO|2024-09-06 12:03:17]: Using numpy backend on /CPU:0\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# set the qibo backend (we suggest qibojit if N >= 20)\n", - "set_backend(\"numpy\")\n", - "\n", - "# hamiltonian parameters\n", - "nqubits = 5\n", - "h = 3\n", - "\n", - "# define the hamiltonian\n", - "h = hamiltonians.TFIM(nqubits=nqubits, h=h)\n", - "\n", - "# vosualize the matrix\n", - "visualize_matrix(h.matrix, title=\"Target hamiltonian\")" - ] - }, - { - "cell_type": "markdown", - "id": "c2ca8392", - "metadata": {}, - "source": [ - "#### The generator of the evolution\n", - "\n", - "The model is implemented following the procedure presented in [1], and the first practical step is to define the generator of the iteration $\\hat{\\mathcal{U}}_{\\ell}$, which executes one diagonalization step $$\\hat{H}_{\\ell} = \\hat{\\mathcal{U}}_{\\ell}^{\\dagger} \\hat{H} \\hat{\\mathcal{U}}_{\\ell}.$$\n", - "In `Qibo`, we define the iteration type through a `DoubleBracketGeneratorType` object, which can be chosen between one of the following:\n", - "- `canonical`: the generator of the iteration at step $k+1$ is defined using the commutator between the off diagonal part $\\sigma(\\hat{H_k})$ and the diagonal part $\\Delta(\\hat{H}_k)$ of the target evolved hamiltonian:\n", - " $$\\hat{\\mathcal{U}}_{k+1}=\\exp\\bigl\\{s[\\Delta(\\hat{H}_k), \\sigma(\\hat{H}_k)]\\bigr\\}.$$ \n", - "- `single_commutator`: the evolution follows a similar procedure of the previous point in this list, but any additional matrix $D_k$ can be used to control the evolution at each step:\n", - " $$ \\hat{\\mathcal{U}}_{k+1}=\\exp\\bigl\\{s[D_k, \\hat{H}_k]\\bigr\\}. $$\n", - "- `group_commutator`: the following group commutator is used to compute the evolution:\n", - " $$ \\hat{\\mathcal{U}}_{k+1}= e^{is\\hat{H_k}} e^{isD_k} e^{-is\\hat{H_k}} e^{-isD_k}, $$\n", - "which approximates the canonical commutator for small $s$.\n", - "\n", - "In order to set one of this evolution generators one can do as follow:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "1adafc19", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "DoubleBracketGeneratorType.canonical\n", - "DoubleBracketGeneratorType.single_commutator\n", - "DoubleBracketGeneratorType.group_commutator\n", - "DoubleBracketGeneratorType.group_commutator_third_order\n" - ] - } - ], - "source": [ - "# we have a look inside the DoubleBracketGeneratorType class\n", - "for generator in DoubleBracketGeneratorType:\n", - " print(generator)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "8a4d0e9d", - "metadata": {}, - "outputs": [], - "source": [ - "# here we set the canonical generator\n", - "iterationtype = DoubleBracketGeneratorType.canonical" - ] - }, - { - "cell_type": "markdown", - "id": "a5527622", - "metadata": {}, - "source": [ - "#### The `DoubleBracketIteration` class\n", - "\n", - "A `DoubleBracketIteration` object can be initialize by calling the `qibo.models.double_braket.DoubleBracketIteration` model and passing the target hamiltonian and the generator type we want to use to perform the evolutionary steps." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "9521c464", - "metadata": {}, - "outputs": [], - "source": [ - "dbf = DoubleBracketIteration(hamiltonian=deepcopy(h), mode=iterationtype)" - ] - }, - { - "cell_type": "markdown", - "id": "a262c69f", - "metadata": {}, - "source": [ - "#### `DoubleBracketIteration` features" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "290e5828", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Backend: numpy\n" - ] - } - ], - "source": [ - "# on which qibo backend am I running the algorithm?\n", - "print(f\"Backend: {dbf.backend}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "3e2b9950", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initial form of the target hamiltonian:\n", - "[[-5.-0.j -3.-0.j -3.-0.j ... -0.-0.j -0.-0.j -0.-0.j]\n", - " [-3.-0.j -1.-0.j -0.-0.j ... -0.-0.j -0.-0.j -0.-0.j]\n", - " [-3.-0.j -0.-0.j -1.-0.j ... -0.-0.j -0.-0.j -0.-0.j]\n", - " ...\n", - " [-0.-0.j -0.-0.j -0.-0.j ... -1.-0.j -0.-0.j -3.-0.j]\n", - " [-0.-0.j -0.-0.j -0.-0.j ... -0.-0.j -1.-0.j -3.-0.j]\n", - " [-0.-0.j -0.-0.j -0.-0.j ... -3.-0.j -3.-0.j -5.-0.j]]\n" - ] - } - ], - "source": [ - "# the initial target hamiltonian is a qibo hamiltonian\n", - "# thus the matrix can be accessed typing h.matrix\n", - "print(f\"Initial form of the target hamiltonian:\\n{dbf.h0.matrix}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "638ba4b5", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# let's visualize it in a more graphical way\n", - "visualize_matrix(dbf.h0.matrix, r\"$H_0$\")" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "08f0c466", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# since we didn't perform yet any evolutionary step they are the same\n", - "visualize_drift(dbf.h0.matrix, dbf.h.matrix)" - ] - }, - { - "cell_type": "markdown", - "id": "bb5f10da", - "metadata": {}, - "source": [ - "which shows $\\hat{H}$ is now identical to $\\hat{H}_0$ since no evolution step has been performed yet." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "90e6fdff", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# diagonal part of the H target\n", - "visualize_matrix(dbf.diagonal_h_matrix)" - ] - }, - { - "cell_type": "markdown", - "id": "a0101ae0", - "metadata": {}, - "source": [ - "The Hilbert-Schmidt norm of a Hamiltonian is defined as:\n", - "\n", - "$\\langle A\\rangle_{HS}=\\sqrt{A^\\dagger A}$" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "0d90c8b5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "HS norm of the off diagonal part of H: 37.94733192202055\n" - ] - } - ], - "source": [ - "# Hilbert-Schmidt norm of the off-diagonal part\n", - "# which we want to bring to be close to zero\n", - "print(f\"HS norm of the off diagonal part of H: {dbf.off_diagonal_norm}\")" - ] - }, - { - "cell_type": "markdown", - "id": "a1d1eb77", - "metadata": {}, - "source": [ - "Finally, the energy fluctuation of the system at step $k$ over a given state $\\mu$\n", - "\n", - "$$ \\Xi(\\mu) = \\sqrt{\\langle \\mu | \\hat{H}_k^2 | \\mu \\rangle - \\langle \\mu | \\hat{H}_k | \\mu \\rangle^2} $$\n", - "\n", - "can be computed:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "13710cc2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6.708203932499369" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# define a quantum state\n", - "# for example the ground state of a multi-qubit Z hamiltonian\n", - "Z = hamiltonians.Z(nqubits=nqubits)\n", - "state = Z.ground_state()\n", - "\n", - "# compute energy fluctuations using current H and given state\n", - "dbf.energy_fluctuation(state)" - ] - }, - { - "cell_type": "markdown", - "id": "4d34e1e3", - "metadata": {}, - "source": [ - "#### Call the `DoubleBracketIteration` to perform a DBF iteration\n", - "\n", - "If the DBF object is called, a Double Bracket Iteration iteration is performed. This can be done customizing the iteration by setting the iteration step and the desired `DoubleBracketGeneratorType`. If no generator is provided, the one passed at the initialization time is used (default is `DoubleBracketGeneratorType.canonical`)." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "a7749a96", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initial value of the off-diagonal norm: 37.94733192202055\n", - "One step later off-diagonal norm: 34.179717587686405\n" - ] - } - ], - "source": [ - "# perform one evolution step\n", - "\n", - "# initial value of the off-diagonal norm\n", - "print(f\"Initial value of the off-diagonal norm: {dbf.off_diagonal_norm}\")\n", - "\n", - "dbf(step=0.01, mode=iterationtype)\n", - "\n", - "# after one step\n", - "print(f\"One step later off-diagonal norm: {dbf.off_diagonal_norm}\")" - ] - }, - { - "cell_type": "markdown", - "id": "dab441bb", - "metadata": {}, - "source": [ - "We can check now if something happened by plotting the drift:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "fc01baa4", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_drift(dbf.h0.matrix, dbf.h.matrix)" - ] - }, - { - "cell_type": "markdown", - "id": "9223433b", - "metadata": {}, - "source": [ - "The set step can be good, but maybe not the best one. In order to do this choice in a wiser way, we can call the DBF hyperoptimization routine to search for a better initial step. The `dbf.hyperopt_step` method is built on top of the [`hyperopt`](https://hyperopt.github.io/hyperopt/) package. Any algorithm or sampling space provided by the official package can be used. We are going to use the default options (we sample new steps from a uniform space following a _Tree of Parzen estimators algorithm_)." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "0d7b86d3", - "metadata": {}, - "outputs": [], - "source": [ - "# restart\n", - "dbf.h = dbf.h0\n", - "\n", - "# optimization of the step, we allow to search in [1e-5, 1]\n", - "step = dbf.choose_step(\n", - " scheduling=DoubleBracketScheduling.hyperopt,\n", - " step_min = 1e-5,\n", - " step_max = 1,\n", - " optimizer = optuna.samplers.TPESampler(),\n", - " max_evals = 1000,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "1b9b1431", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZ4AAAGiCAYAAADXxKDZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAqe0lEQVR4nO3df3CV5Z3//9cByQlKcjD8yI+SIIhCFYNtKmlGy4KkhGyHwcofaJ1pdCkObmCKWbeanVbQbSesnVFsm8aOdaGdKWJxCo52hNVIwrhLrEQYpN3NAJ+0xEJC5TskEOUAua/vH5FjD4TkPrnv3OdcyfPhXDOcO/e57vc5d+Dtdd3Xj5AxxggAgICMSnYAAICRhcQDAAgUiQcAECgSDwAgUCQeAECgSDwAgECReAAAgSLxAAACReIBAASKxAMACBSJBwDg2vr16xUKheLKrFmzEqrjmiGKDQAwTN166616++23Y6+vuSaxVELiAQAk5JprrlFOTs7g3+9jLACAgJw7d07nz5/3pS5jjEKhUNyxcDiscDjc5/mHDx9WXl6e0tPTVVJSopqaGhUUFLi+XohtEQDALufOndO0aTlqb+/0pb5x48bp7NmzccfWrVun9evXX3Hum2++qbNnz2rmzJk6ceKEnnrqKf31r3/VoUOHlJGR4ep6JB4AsExXV5cikYj+31+eU2bmWI91farpUx9VW1ubMjMzY8f7a/H8vdOnT2vq1Kl69tlntWLFClfXpKsNACyVmTnWc+L5vK7MuMTj1vjx43XzzTfryJEjrt/DcGoAsJQxF30pXpw9e1ZHjx5Vbm6u6/eQeADAUsb0+FIS8dhjj6mxsVF//vOf9T//8z/65je/qdGjR+v+++93XQddbQAA1z766CPdf//9OnXqlCZNmqS77rpLTU1NmjRpkus6SDwAYCnHXJTjsass0fdv3brV0/UkEg8AWMuPZzRe3z8YPOMBAASKFg8AWKp3cIDXFk9igwv8QOIBAEsZ56KM4zHxeHz/YNDVBgAIFC0eALCVudhbvNYRMBIPAFiKUW0AALhAiwcAbOVclJwL3usIGIkHACzV29U22nMdQaOrDQAQKFo8AGAr56LkeGvx0NUGAHDP0sRDVxsAIFC0eADAWj0+TABlrTYAgEsh56JCjreOqxBdbQCA4Y4WDwDYyrkoeWzxMKoNAOCepYmHrjYAQKBo8QCApULmokLG4+ACtkUAALjmOJLjcTi04/gTSwLoagMABIoWDwBYqnceT8hzHUEj8QCArZweH0a1Bb9yAV1tAIBA0eIBAFs5FyWPXW1MIAUAuBZyenxYq42uNgDAMJdyLR7HcXT8+HFlZGQoFPLYhASAFGCM0ZkzZ5SXl6dRo3z8/33jw+ACw7YIOn78uPLz85MdBgD4rq2tTVOmTPGtvpDjeO4qCyVhAumQJZ7a2lr9+Mc/Vnt7u+bMmaOf/vSnmjt37oDvy8jIkCT9+djzyswc2++5f3ngRV9ilaQv/b7Z1Xn7v1Hka31+chNbMuJKZal8PzGcGEkm9u/bSDckieeVV15RVVWVXnjhBRUXF2vjxo0qKytTS0uLJk+e3O97L3WvZWaOVWbmtf2emzHGz/Dddeu5v2bw3YTuYqP78u+l8v3EcGP8f3zg9Pgwqm2YDC549tlntXLlSj300EO65ZZb9MILL+jaa6/Vf/7nfw7F5QBgROod1ea9BM33xHP+/Hk1NzertLT084uMGqXS0lLt3bv3ivOj0ai6urriCgBg+PI98Xz88cfq6elRdnZ23PHs7Gy1t7dfcX5NTY0ikUisMLAAAFxyevwpAUv6PJ7q6mp1dnbGSltbW7JDAgAr2NrV5vvggokTJ2r06NHq6OiIO97R0aGcnJwrzg+HwwqHw36HAQBIUb63eNLS0lRUVKT6+vrYMcdxVF9fr5KSEr8vBwAjl6VdbUMynLqqqkoVFRX6yle+orlz52rjxo3q7u7WQw89NBSXA4ARKeQYzxNAQ47xKRr3hiTxLF++XH/729/05JNPqr29Xbfffrt27tx5xYCD/vzlgRcHnGOxclfhgPXs/vSXrq535J6BJ7dK0owdf/CtPrd1ueWmPr8/p+38vJ+J1AeMZEO2csHq1au1evXqoaoeAOD0SF5XvBkuXW0AgAAYHxJPEhYJTfpwagDAyEKLBwAsFTKOQsbbWm0hM4xWpwYADDFLn/HQ1QYACBQtHgCwleP4sC0CXW0AALdIPMFzMzl0wdjvuKztoLdgLpOqkzmZMDk4fG+Af6xOPAAwkoUcRyGPDRavS+4MBokHAGzlOD6Mags+8TCqDQAQKFo8AGArS1s8JB4AsJWliYeuNgBAoGjxAICtTI/kdSM31moDALhl63BqutoAAIFK2RbPl37fLKn/pSDczRJ3tyKBm220e42MVQRSObZUlspbo2MYsnRwQcomHgDAACxNPHS1AQACRYsHAGzlGO8tFq+j4gaBxAMAtnKMD11twSceutoAAIGixQMAtvJlIzhaPAAAtxzHnzJIGzZsUCgU0tq1axN6H4kHAJCw999/X7/4xS9UWOh2DuTnSDwAYCvH+FMSdPbsWT3wwAN68cUXdf311yf8/pR9xrP/G0XKGNN/eP7O7HZX14Kx33F13otl7lZMcCOVZ7AzU39w3HxWVoXAgIwjGY/PeExv4unq6oo7HA6HFQ6H+3xLZWWlvvGNb6i0tFQ//OEPE74kLR4AgPLz8xWJRGKlpqamz/O2bt2qDz744Ko/dyNlWzwAgAEYH+bxfNbiaWtrU2ZmZuxwX62dtrY2ffe739Vbb72l9PT0QV+SxAMAtvJxAmlmZmZc4ulLc3OzTp48qS9/+cuxYz09PdqzZ49+9rOfKRqNavTo0QNeksQDAHBl4cKF+vDDD+OOPfTQQ5o1a5Yef/xxV0lHIvEAgL0CXjInIyNDs2fPjjt23XXXacKECVcc7w+JBwAsZRzvO1cnYedrEg8AYPAaGhoSfg+JBwBsZenq1CmbePza+trvyXXJmBg6HCYSMmEycSPp9wOD5MiHxONHIIlhAikAIFC+J57169crFArFlVmzZvl9GQCA41MJ2JB0td166616++23P7/INSnbowcA9jKfFa91BGxIMsI111yjnJwcV+dGo1FFo9HY68sXqgMADC9D8ozn8OHDysvL0/Tp0/XAAw/o2LFjVz23pqYmbmG6/Pz8oQgJAIYd44R8KUHzPfEUFxdr8+bN2rlzp+rq6tTa2qqvfe1rOnPmTJ/nV1dXq7OzM1ba2tr8DgkAhiee8fQqLy+P/bmwsFDFxcWaOnWqfvvb32rFihVXnN/fng8AgOFnyJ/6jx8/XjfffLOOHDky1JcCgJHFhCSvXWVJGFww5PN4zp49q6NHjyo3N3eoLwUAI4qtz3h8b/E89thjWrJkiaZOnarjx49r3bp1Gj16tO6//36/L5XSs+Hd1Od2G23Jv9USUhkz9QeH7w228T3xfPTRR7r//vt16tQpTZo0SXfddZeampo0adIkvy8FACOb40NX23AYXLB161a/qwQA9MWEeounOvwJJRGs1QYACBRr2QCApfwYHMBGcAAA95xRPjzjCb6vja42AECgaPEAgK0Y1QYACJIxIRmPo9oMo9oAAMPdsG/xJGtWt7v63K1IsHJXoavzpJEx49zPezCSZunzvQ1Dlg4uGPaJBwCGK+PIh+HUjGoDAAxztHgAwFa+bIswDFanBgAEw59RbcNg62sAAPpDiwcAbOWM6i2e6vAnlESQeADAUv4sEkpXGwBgmAsZk4wFE66uq6tLkUhE+79xhzLG9N8gYxJbPDdbab9Y5u822kxKHJnYRjtRRpKjzs5OZWZmeq7t0r+Tf300W5lhb+2HrqijLzzX4VtsbtDVBgC2svQZD11tAIBA0eIBAEvZOriAxAMAlmICKQAALtDiAQBbWTq4gMQDAJay9RkPXW0AgEDR4gEAS9k6uCBlE8+Xft8sqf8vhNnw8fxclSAZW4YzG94eydpSHpcxPjzjScLaNXS1AQAClbItHgBA/2wdXEDiAQBLGeP9GU0ylommqw0AEChaPABgKx+62kRXGwDALWNGyRhvHVfJ2JKNrjYAQKBo8QCArZyQ964yutoAAG6xckESMBs+cX7POPcTs+GHHz/vKfdz+Ej4Gc+ePXu0ZMkS5eXlKRQKaceOHXE/N8boySefVG5ursaOHavS0lIdPnzYr3gBAJ+5NIHUawlawomnu7tbc+bMUW1tbZ8/f+aZZ/STn/xEL7zwgt577z1dd911Kisr07lz5zwHCwD43KVRbV5L0BLuaisvL1d5eXmfPzPGaOPGjfr+97+vpUuXSpJ+/etfKzs7Wzt27NB9993nLVoAgPV8TXWtra1qb29XaWlp7FgkElFxcbH27t3b53ui0ai6urriCgBgYCOmq60/7e3tkqTs7Oy449nZ2bGfXa6mpkaRSCRW8vPz/QwJAIatS6PavJagJX0CaXV1tTo7O2Olra0t2SEBAIaQr8Opc3JyJEkdHR3Kzc2NHe/o6NDtt9/e53vC4bDC4bCfYQDAiGDrPB5fWzzTpk1TTk6O6uvrY8e6urr03nvvqaSkxM9LAcCIZ4wPz3hsmEB69uxZHTlyJPa6tbVVBw4cUFZWlgoKCrR27Vr98Ic/1E033aRp06bpBz/4gfLy8nTPPff4GTcAwFIJJ559+/ZpwYIFsddVVVWSpIqKCm3evFnf+9731N3drYcfflinT5/WXXfdpZ07dyo9Pd2/qBMwkmbD+7mSQypjNvzwwyokg2Pr6tQJJ5758+f3G2goFNLTTz+tp59+2lNgAID+2br1ddJHtQEARharFwkFgJHM1lFtJB4AsJStiYeuNgBAoEg8AGAp4/ixXlti16yrq1NhYaEyMzOVmZmpkpISvfnmmwnVQVcbAFgqGV1tU6ZM0YYNG3TTTTfJGKNf/epXWrp0qfbv369bb73VVR0kHgCAa0uWLIl7/aMf/Uh1dXVqamoi8SRqOEw0TeUJkwvGfmfAc14sO+jrNUfSRMKRYDj8HfWbPxNIe99/+ZY0btbR7Onp0bZt29Td3Z3Qsmg84wEASzkm5EuRpPz8/Lgtampqaq563Q8//FDjxo1TOBzWqlWrtH37dt1yyy2u46bFAwBQW1ubMjMzY6/7a+3MnDlTBw4cUGdnp1599VVVVFSosbHRdfIh8QCArfzYQfSz918apeZGWlqaZsyYIUkqKirS+++/r+eff16/+MUvXL2fxAMAlkqVCaSO4ygajbo+n8QDAHCturpa5eXlKigo0JkzZ7RlyxY1NDRo165drusg8QCApZLR4jl58qS+/e1v68SJE4pEIiosLNSuXbv09a9/3XUdJB4AsFQyEs9LL73k6XoSw6kBAAGjxQMAlnLMKDkeJ5B6ff9gkHgSlMrbLqfy9sF+rkqQyvcAyTeSVjgwxocdSNkWAQAw3NHiAQBLpco8nkSReADAUrYmHrraAACBosUDAJb6+9WlvdQRNBIPAFiKrjYAAFygxQMAlrK1xUPiAQBL8YwHcVJ1FYFUntXttq4FY7/jskb/VkvA8MMKGMlD4gEASxnjvavMGJ+CSQCJBwAsZeszHka1AQACRYsHACxlfBhcwKg2AIBrdLUBAOACLR4AsJStLR4SDwBYigmkSNhwmMzpZ2xu63I7MXTlrkIXZzHxD/3z43f3zIWL+tLv3/crJOuReADAUrZ2tSU8uGDPnj1asmSJ8vLyFAqFtGPHjrifP/jggwqFQnFl8eLFfsULAPjMpa42ryVoCSee7u5uzZkzR7W1tVc9Z/HixTpx4kSsvPzyy56CBAAMHwl3tZWXl6u8vLzfc8LhsHJyclzVF41GFY1GY6+7uroSDQkARiSjkIw8drV5fP9gDMk8noaGBk2ePFkzZ87UI488olOnTl313JqaGkUikVjJz88fipAAYNi59IzHawma74ln8eLF+vWvf636+nr9x3/8hxobG1VeXq6enp4+z6+urlZnZ2estLW1+R0SACCF+D6q7b777ov9+bbbblNhYaFuvPFGNTQ0aOHChVecHw6HFQ6H/Q4DAIY9W+fxDPmSOdOnT9fEiRN15MiRob4UAIwodLVdxUcffaRTp04pNzd3qC8FALBAwl1tZ8+ejWu9tLa26sCBA8rKylJWVpaeeuopLVu2TDk5OTp69Ki+973vacaMGSorK0voOvu/UaSMMf2HN1K2m03lz5mM1RLcG7g+t9tov1jm7zbaqbo1ulupHFsyDPw5h2abT0c+dLUlYVRbwoln3759WrBgQex1VVWVJKmiokJ1dXU6ePCgfvWrX+n06dPKy8vTokWL9O///u88xwEASBpE4pk/f75MP5t079q1y1NAAAB3bF0yh7XaAMBSjkKeu8qS0dXGRnAAgEDR4gEAW/kxHJquNgCAW0wgBQDABVo8AGApRrUBAALlfFa81hG0lE08X/p9szTAMD83s6dHysxpDI7bFQlW7ip0dd7uT3/p6jw/f3eTsYpAKseG1JeyiQcA0D+62gAAgXKM91FpztAsI9cvRrUBAAJFiwcALGUUkvG45I3X9w8GiQcALMUEUgAAXKDFAwCW6h1c4L2OoJF4AMBSPONJAtu3D4Y9/JwY6rdUnszpZ2z8HR0+rE48ADCS2Tq4gMQDAJYyprd4rSNojGoDAASKFg8AWMooJIfBBQCAoNi6SChdbQCAQNHiAQBLMaoNABAo81nxWkfQ6GoDAARq2Ld4UnlWN5LP798Pt9xtpe3v71oqryLAKiSDQ1cbACBQzmfFax1Bo6sNABAoWjwAYClb5/GQeADAUrY+46GrDQAQKBIPAFjK+FQSUVNTozvuuEMZGRmaPHmy7rnnHrW0tCRUB4kHACx1qavNa0lEY2OjKisr1dTUpLfeeksXLlzQokWL1N3d7boOnvEAAFzbuXNn3OvNmzdr8uTJam5u1rx581zVQeIBAEv5OY+nq6sr7ng4HFY4HB7w/Z2dnZKkrKws19ck8XyGFQ5GpuTdT/9m6vstVX93+Tt6JT+HU+fn58cdX7dundavX9/vex3H0dq1a3XnnXdq9uzZrq+Z0DMeNw+Vzp07p8rKSk2YMEHjxo3TsmXL1NHRkchlAAABa2trU2dnZ6xUV1cP+J7KykodOnRIW7duTehaCSUeNw+VHn30Ub3++uvatm2bGhsbdfz4cd17770JBQUAGJjR591tgy2XRrVlZmbGlYG62VavXq033nhDu3fv1pQpUxKKO6GutoEeKnV2duqll17Sli1bdPfdd0uSNm3apC9+8YtqamrSV7/61YSCAwBcnZEPXW0Jbn1tjNGaNWu0fft2NTQ0aNq0aQlf09MznssfKjU3N+vChQsqLS2NnTNr1iwVFBRo7969fSaeaDSqaDQae335Ay4AQOqorKzUli1b9NprrykjI0Pt7e2SpEgkorFjx7qqY9DzePp6qNTe3q60tDSNHz8+7tzs7OxYcJerqalRJBKJlcsfcAEA+uYYf0oi6urq1NnZqfnz5ys3NzdWXnnlFdd1DLrFc+mh0rvvvjvYKiRJ1dXVqqqqir3u6uoi+QCAC8nYgdQY73uWDirxXHqotGfPnriHSjk5OTp//rxOnz4d1+rp6OhQTk5On3W5HSsOABgeEupqM8Zo9erV2r59u955550rHioVFRVpzJgxqq+vjx1raWnRsWPHVFJS4k/EAABJyVkyxw8JtXgGeqgUiUS0YsUKVVVVKSsrS5mZmVqzZo1KSkqGzYi2VN4+GIkbSZMSR8rv7ki6p7buQJpQ4qmrq5MkzZ8/P+74pk2b9OCDD0qSnnvuOY0aNUrLli1TNBpVWVmZfv7zn/sSLADAfgklHjcPldLT01VbW6va2tpBBwUAGBg7kAIAAmVrVxv78QAAAkWLBwAsZUxv8VpH0Eg8AGApRyE5Ca611lcdQaOrDQAQKFo8AGCpway11lcdQSPxAICtfHjG43mxt0Eg8QwRN7Odh8PM6ZEilWfD+x3bSDFSVnJIRSQeALCUrYMLSDwAYClbh1Mzqg0AEChaPABgKVuXzCHxAIClbB1OTVcbACBQtHgAwFJG3qfhJKHBQ+IBAFv1drV5HE5NVxsAYLijxZNEqTwbHoOTjNnwfq9IsHJXoYuzRs7vmh+rkJy5cFFf+v37foUUY+s8HhIPAFjK1uHUdLUBAAJFiwcALEVXGwAgUHS1AQDgAi0eALCU8WHJHLraAACu2bpyAV1tAIBA0eKxAFv0Dp1kTc5NxtbX7g1c34Kx33FV04tlB70GE5PKE64Hrmto2hW2rk5N4gEAS9k6nJquNgBAoGjxAIClbJ3HQ+IBAEvZ+oyHrjYAQKBo8QCApWydx0PiAQBL0dUGAIALtHgAwFK2zuMh8QwjfmzRm0hdw0Eqz4ZPZW5XJHC3jba0+9NfDniO3/dgONxTW4dT09UGAAhUQomnpqZGd9xxhzIyMjR58mTdc889amlpiTtn/vz5CoVCcWXVqlW+Bg0A+KzFYzyWJMSdUOJpbGxUZWWlmpqa9NZbb+nChQtatGiRuru7485buXKlTpw4ESvPPPOMr0EDAD4fTu21BC2hZzw7d+6Me71582ZNnjxZzc3NmjdvXuz4tddeq5ycHFd1RqNRRaPR2Ouurq5EQgIAWMbTM57Ozk5JUlZWVtzx3/zmN5o4caJmz56t6upqffLJJ1eto6amRpFIJFby8/O9hAQAI4YZbPfa3xWrRrU5jqO1a9fqzjvv1OzZs2PHv/Wtb2nq1KnKy8vTwYMH9fjjj6ulpUW/+93v+qynurpaVVVVsdddXV0kHwBwwRgfVi6wKfFUVlbq0KFDevfdd+OOP/zww7E/33bbbcrNzdXChQt19OhR3XjjjVfUEw6HFQ6HBxsGAMAyg+pqW716td544w3t3r1bU6ZM6ffc4uJiSdKRI0cGcykAwFU4PpWgJdTiMcZozZo12r59uxoaGjRt2rQB33PgwAFJUm5u7qACBAD0rXc4tLe+spTf+rqyslJbtmzRa6+9poyMDLW3t0uSIpGIxo4dq6NHj2rLli36x3/8R02YMEEHDx7Uo48+qnnz5qmw0N0MZgytkTSr2098b4PjZkUCyf335ic/7+lIuZ9+SSjx1NXVSeqdJPr3Nm3apAcffFBpaWl6++23tXHjRnV3dys/P1/Lli3T97//fd8CBgD0GhHbIpgBhj/k5+ersbHRU0AAAHf8WHmAbREAAMMeq1MDgKXMZ/95rSNoJB4AsBRdbQAAuECLBwAsZetGcCQeALCUMT4840nCYm10tQEAAkWLB31ipv7gjJTZ8H7/frixcpfb1U/8/d7cfNaBPueZCxf1pd+/71dIMXS1AQACRVcbAAAu0OIBAEsZee8qS/m12gAAqcMxxodtEehqAwCksD179mjJkiXKy8tTKBTSjh07Eq6DxAMAljI+/ZeI7u5uzZkzR7W1tYOOm642ALBUMoZTl5eXq7y83NM1STwAAHV1dcW9DofDCofDQ3ItEg88GSkTJv3mx6TEROryW3Jic1fXgrHfcXXei2UHvQQTZ+DPOTQP8B35MLjgs/fn5+fHHV+3bp3Wr1/vqe6rIfEAgKX8HNXW1tamzMzM2PGhau1IJB4AgKTMzMy4xDOUSDwAYCl2IAUABMrPZzxunT17VkeOHIm9bm1t1YEDB5SVlaWCggJXdZB4AACu7du3TwsWLIi9rqqqkiRVVFRo8+bNruog8QCApZLR4pk/f77nFa1JPABgKVuf8bBkDgAgULR4AMBSxoeuNka1YdiyfaZ+MqTy9uOpHJvbFQncbqW9+9NfDnhO0ra+DjkKhbyt1uYkYfNrutoAAIGixQMAlnJkFAp4VJsfSDwAYCnz2YBqr3UEja42AECgaPEAgKUcyYeutuCReADAUoxqAwDABVo8AGApR45CHlssyWjxkHgAwFIkHsCjVJ4Nn8pS+XvzMza/76ebFQkkacHY77g4y91qCeiV0DOeuro6FRYWxrZILSkp0Ztvvhn7+blz51RZWakJEyZo3LhxWrZsmTo6OnwPGgDw+TweryVoCSWeKVOmaMOGDWpubta+fft09913a+nSpfrjH/8oSXr00Uf1+uuva9u2bWpsbNTx48d17733DkngADDSOSHHlxK0hLralixZEvf6Rz/6kerq6tTU1KQpU6bopZde0pYtW3T33XdLkjZt2qQvfvGLampq0le/+tU+64xGo4pGo7HXXV1diX4GAIBFBj2cuqenR1u3blV3d7dKSkrU3NysCxcuqLS0NHbOrFmzVFBQoL179161npqaGkUikVjJz88fbEgAMKIYOZ7/S/muNkn68MMPNW7cOIXDYa1atUrbt2/XLbfcovb2dqWlpWn8+PFx52dnZ6u9vf2q9VVXV6uzszNW2traEv4QADASGfX4UoKW8Ki2mTNn6sCBA+rs7NSrr76qiooKNTY2DjqAcDiscDg86PcDAOyScOJJS0vTjBkzJElFRUV6//339fzzz2v58uU6f/68Tp8+Hdfq6ejoUE5Ojm8BAwB69c7BsW8ej+clcxzHUTQaVVFRkcaMGaP6+vrYz1paWnTs2DGVlJR4vQwA4DKOT095gpZQi6e6ulrl5eUqKCjQmTNntGXLFjU0NGjXrl2KRCJasWKFqqqqlJWVpczMTK1Zs0YlJSVXHdEGDEYqT0pMZan8vSVja3S39bmZHHrD7yr7/XlX1yfSeP+3vrZVQonn5MmT+va3v60TJ04oEomosLBQu3bt0te//nVJ0nPPPadRo0Zp2bJlikajKisr089//vMhCRwARrrewQEhz3UELaHE89JLL/X78/T0dNXW1qq2ttZTUACAgY3YZzwAACSCRUIBwFJ+rLWWjAmkJB4AsJSjHsnjMx4nCc946GoDAASKFg8AWIquNgBAoBzjQ1ebSfHh1EEw5tIs2uBn02J4OXPhoouz+D27XKp+b+7iktzG5r6+gXV1fTLAzz+V9Pf/vo1sIZNi38RHH33E1ggAhqW2tjZNmTLFcz1dXV2KRCKacG2RRoW8tR8cc1GnPmlWZ2enMjMzPcfmRsq1ePLy8tTW1qaMjAyFQr1NyK6uLuXn56utrS2wL8Zvtn8G2+OX7P8MxJ98g/0MxhidOXNGeXl5vsbT+4zHW1cZz3gkjRo16qr/R5CZmWntL+wltn8G2+OX7P8MxJ98g/kMkUhkiKKxT8olHgCAO8Y4cryu1WZo8QAAXOrtJvO6SChrtfUpHA5r3bp1Vu9UavtnsD1+yf7PQPzJNxw+QypIuVFtAID+XRrVFkm/RaHQaE91GdOjznN/Gtmj2gAA7vQ+4aGrDQCAftHiAQBL9Y5IY1QbACAgfmxbnYytr+lqAwAEyorEU1tbqxtuuEHp6ekqLi7WH/7wh2SH5Mr69esVCoXiyqxZs5IdVr/27NmjJUuWKC8vT6FQSDt27Ij7uTFGTz75pHJzczV27FiVlpbq8OHDyQm2DwPF/+CDD15xTxYvXpycYPtQU1OjO+64QxkZGZo8ebLuuecetbS0xJ1z7tw5VVZWasKECRo3bpyWLVumjo6OJEV8JTefYf78+Vfch1WrViUp4nh1dXUqLCyMrU5QUlKiN998M/bzVPr+jTEyxvFYgh/YnPKJ55VXXlFVVZXWrVunDz74QHPmzFFZWZlOnjyZ7NBcufXWW3XixIlYeffdd5MdUr+6u7s1Z84c1dbW9vnzZ555Rj/5yU/0wgsv6L333tN1112nsrIynTt3LuBI+zZQ/JK0ePHiuHvy8ssvBxhh/xobG1VZWammpia99dZbunDhghYtWqTu7u7YOY8++qhef/11bdu2TY2NjTp+/LjuvffeJEYdz81nkKSVK1fG3YdnnnkmSRHHmzJlijZs2KDm5mbt27dPd999t5YuXao//vGPklLr+7+0H4/XEnzgKW7u3LmmsrIy9rqnp8fk5eWZmpqaJEblzrp168ycOXOSHcagSTLbt2+PvXYcx+Tk5Jgf//jHsWOnT5824XDYvPzyy0mIsH+Xx2+MMRUVFWbp0qVJiWcwTp48aSSZxsZGY0zv9z1mzBizbdu22Dn/+7//aySZvXv3JivMfl3+GYwx5h/+4R/Md7/73eQFlaDrr7/e/PKXv0yZ77+zs9NIMmPTbjDXhqd7KmPTbjCSTGdnZ2Dxp3SL5/z582publZpaWns2KhRo1RaWqq9e/cmMTL3Dh8+rLy8PE2fPl0PPPCAjh07luyQBq21tVXt7e1x9yMSiai4uNia+yFJDQ0Nmjx5smbOnKlHHnlEp06dSnZIV9XZ2SlJysrKkiQ1NzfrwoULcfdg1qxZKigoSNl7cPlnuOQ3v/mNJk6cqNmzZ6u6ulqffNL/njbJ0NPTo61bt6q7u1slJSUp9/0b0+NLCVpKj2r7+OOP1dPTo+zs7Ljj2dnZ+r//+78kReVecXGxNm/erJkzZ+rEiRN66qmn9LWvfU2HDh1SRkZGssNLWHt7uyT1eT8u/SzVLV68WPfee6+mTZumo0eP6t/+7d9UXl6uvXv3avRobzPA/eY4jtauXas777xTs2fPltR7D9LS0jR+/Pi4c1P1HvT1GSTpW9/6lqZOnaq8vDwdPHhQjz/+uFpaWvS73/0uidF+7sMPP1RJSYnOnTuncePGafv27brlllt04MCBlPr+/RgKzXDqYaa8vDz258LCQhUXF2vq1Kn67W9/qxUrViQxspHrvvvui/35tttuU2FhoW688UY1NDRo4cKFSYzsSpWVlTp06FDKPxfsz9U+w8MPPxz782233abc3FwtXLhQR48e1Y033hh0mFeYOXOmDhw4oM7OTr366quqqKhQY2NjssMaNlK6q23ixIkaPXr0FSNGOjo6lJOTk6SoBm/8+PG6+eabdeTIkWSHMiiXvvPhcj8kafr06Zo4cWLK3ZPVq1frjTfe0O7du+P2p8rJydH58+d1+vTpuPNT8R5c7TP0pbi4WJJS5j6kpaVpxowZKioqUk1NjebMmaPnn38+5b5/WwcXpHTiSUtLU1FRkerr62PHHMdRfX29SkpKkhjZ4Jw9e1ZHjx5Vbm5uskMZlGnTpiknJyfufnR1dem9996z8n5IvVutnzp1KmXuiTFGq1ev1vbt2/XOO+9o2rRpcT8vKirSmDFj4u5BS0uLjh07ljL3YKDP0JcDBw5IUsrch8s5jqNoNJpy37/3odROUrraUn5U29atW004HDabN282f/rTn8zDDz9sxo8fb9rb25Md2oD+5V/+xTQ0NJjW1lbz3//936a0tNRMnDjRnDx5MtmhXdWZM2fM/v37zf79+40k8+yzz5r9+/ebv/zlL8YYYzZs2GDGjx9vXnvtNXPw4EGzdOlSM23aNPPpp58mOfJe/cV/5swZ89hjj5m9e/ea1tZW8/bbb5svf/nL5qabbjLnzp1LdujGGGMeeeQRE4lETENDgzlx4kSsfPLJJ7FzVq1aZQoKCsw777xj9u3bZ0pKSkxJSUkSo4430Gc4cuSIefrpp82+fftMa2uree2118z06dPNvHnzkhx5ryeeeMI0Njaa1tZWc/DgQfPEE0+YUChk/uu//ssYkxrf/6VRbWNGZ5u0a3I9lTGjswMf1ZbyiccYY37605+agoICk5aWZubOnWuampqSHZIry5cvN7m5uSYtLc184QtfMMuXLzdHjhxJdlj92r17t5F0RamoqDDG9A6p/sEPfmCys7NNOBw2CxcuNC0tLckN+u/0F/8nn3xiFi1aZCZNmmTGjBljpk6dalauXJlS/xPTV+ySzKZNm2LnfPrpp+af//mfzfXXX2+uvfZa881vftOcOHEieUFfZqDPcOzYMTNv3jyTlZVlwuGwmTFjhvnXf/3XQP/h688//dM/malTp5q0tDQzadIks3DhwljSMSY1vv9Lieea0ZPMmGuyPZVrRk8KPPGwHw8AWObSfjyjR2UpFPL2xMQYRz3O/xfofjwp/YwHADD8MJwaAKxlJM+j0oLv9CLxAICl/NmPh0VCAQDDHC0eALBU7+RPjy0eutoAAO55TzzJeMZDVxsAIFC0eADAVj4MLlASBheQeADAUrY+46GrDQAQKFo8AGAtBhcAAAJlep/ReCmDTDy1tbW64YYblJ6eruLiYv3hD39w/V4SDwAgIa+88oqqqqq0bt06ffDBB5ozZ47Kysp08uRJV+9ndWoAsMyl1aml0fKnq60nodWpi4uLdccdd+hnP/uZpN6N8vLz87VmzRo98cQTA76fFg8AWO2qWyC5LL26urriSjQa7fNq58+fV3Nzs0pLS2PHRo0apdLSUu3du9dVxCQeALBMWlqacnJyJPX4UsaNG6f8/HxFIpFYqamp6fPaH3/8sXp6epSdnR13PDs7W+3t7a7iZ1QbAFgmPT1dra2tOn/+vC/1GWMUCsV32YXDYV/q7guJBwAslJ6ervT09MCvO3HiRI0ePVodHR1xxzs6Oj5rhQ2MrjYAgGtpaWkqKipSfX197JjjOKqvr1dJSYmrOmjxAAASUlVVpYqKCn3lK1/R3LlztXHjRnV3d+uhhx5y9X4SDwAgIcuXL9ff/vY3Pfnkk2pvb9ftt9+unTt3XjHg4GqYxwMACBTPeAAAgSLxAAACReIBAASKxAMACBSJBwAQKBIPACBQJB4AQKBIPACAQJF4AACBIvEAAAJF4gEABOr/B3tglwUGPsrTAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_matrix(dbf.h.matrix)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "52fa3599", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_drift(dbf.h0.matrix, dbf.h.matrix)" - ] - }, - { - "cell_type": "markdown", - "id": "084c3bcb", - "metadata": {}, - "source": [ - "#### Let's evolve the model for `NSTEPS`\n", - "\n", - "We know recover the initial hamiltonian, and we perform a sequence of DBF iteration steps, in order to show how this mechanism can lead to a proper diagonalization of the target hamiltonian.\n", - "\n", - "#### Method 1: fixed step" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "d1f197b1", - "metadata": {}, - "outputs": [], - "source": [ - "# restart\n", - "dbf_1 = DoubleBracketIteration(hamiltonian=deepcopy(h), mode=iterationtype)\n", - "off_diagonal_norm_history = [dbf_1.off_diagonal_norm]\n", - "histories, labels = [], [\"Fixed step\"]\n", - "\n", - "# set the number of evolution steps\n", - "NSTEPS = 20\n", - "step = 0.005\n", - "\n", - "for s in range(NSTEPS):\n", - " dbf_1(step=step)\n", - " off_diagonal_norm_history.append(dbf_1.off_diagonal_norm)\n", - "\n", - "histories.append(off_diagonal_norm_history)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "c115c222", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plot_histories(histories, labels)" - ] - }, - { - "cell_type": "markdown", - "id": "233ba431", - "metadata": {}, - "source": [ - "#### Method 2: optimizing the step" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "4e0fc1c2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "New optimized step at iteration 1/20: 0.00934294935664311\n", - "New optimized step at iteration 2/20: 0.009364588177233102\n", - "New optimized step at iteration 3/20: 0.005985356940597437\n", - "New optimized step at iteration 4/20: 0.011472840984366184\n", - "New optimized step at iteration 5/20: 0.006802887431910996\n", - "New optimized step at iteration 6/20: 0.010837702507351613\n", - "New optimized step at iteration 7/20: 0.006624471861894687\n", - "New optimized step at iteration 8/20: 0.00870720701470905\n", - "New optimized step at iteration 9/20: 0.005748706054245771\n", - "New optimized step at iteration 10/20: 0.009512049459920756\n", - "New optimized step at iteration 11/20: 0.004887478565382978\n", - "New optimized step at iteration 12/20: 0.011309993175156744\n", - "New optimized step at iteration 13/20: 0.0017896288977535153\n", - "New optimized step at iteration 14/20: 0.0003944795659594491\n", - "New optimized step at iteration 15/20: 0.0006390700306615794\n", - "New optimized step at iteration 16/20: 0.0008772593599309826\n", - "New optimized step at iteration 17/20: 0.012559015937191706\n", - "New optimized step at iteration 18/20: 0.003294180889937215\n", - "New optimized step at iteration 19/20: 0.002707744316510693\n" - ] - } - ], - "source": [ - "# restart\n", - "dbf_2 = DoubleBracketIteration(hamiltonian=deepcopy(h), mode=iterationtype, scheduling=DoubleBracketScheduling.hyperopt)\n", - "off_diagonal_norm_history = [dbf_2.off_diagonal_norm]\n", - "\n", - "# set the number of evolution steps\n", - "NSTEPS = 20\n", - "\n", - "# optimize first step\n", - "step = dbf_2.choose_step(\n", - " step_min = 1e-5,\n", - " step_max = 1,\n", - " optimizer = optuna.samplers.TPESampler(),\n", - " max_evals = 1000,\n", - ")\n", - "\n", - "for s in range(NSTEPS):\n", - " if s != 0:\n", - " step = dbf_2.choose_step(\n", - " step_min = 1e-5,\n", - " step_max = 1,\n", - " optimizer = optuna.samplers.TPESampler(),\n", - " max_evals = 1000,\n", - " )\n", - " print(f\"New optimized step at iteration {s}/{NSTEPS}: {step}\")\n", - " dbf_2(step=step)\n", - " off_diagonal_norm_history.append(dbf_2.off_diagonal_norm)\n", - "\n", - "histories.append(off_diagonal_norm_history)\n", - "labels.append(\"Optimizing step\")" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "40e31e97", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plot_histories(histories, labels)" - ] - }, - { - "cell_type": "markdown", - "id": "0de78acd", - "metadata": {}, - "source": [ - "The hyperoptimization can lead to a faster convergence of the algorithm." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "baab0ab5", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_matrix(dbf_1.h.matrix)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "2bc9ac69", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "visualize_matrix(dbf_2.h.matrix)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "310c0bad-4eeb-4940-8c18-5921dfb4d157", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "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.10.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/qibo/models/dbi/__init__.py b/src/qibo/models/dbi/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/qibo/models/dbi/double_bracket.py b/src/qibo/models/dbi/double_bracket.py deleted file mode 100644 index ccaacca39d..0000000000 --- a/src/qibo/models/dbi/double_bracket.py +++ /dev/null @@ -1,377 +0,0 @@ -from copy import copy -from enum import Enum, auto -from typing import Optional - -import numpy as np -import optuna - -from qibo.config import raise_error -from qibo.hamiltonians import Hamiltonian -from qibo.models.dbi.utils import * -from qibo.models.dbi.utils_scheduling import ( - grid_search_step, - hyperopt_step, - polynomial_step, - simulated_annealing_step, -) -from qibo.quantum_info.linalg_operations import commutator, matrix_exponentiation - - -class DoubleBracketGeneratorType(Enum): - """Define DBF evolution.""" - - canonical = auto() - """Use canonical commutator.""" - single_commutator = auto() - """Use single commutator.""" - group_commutator = auto() - """Use group commutator approximation""" - group_commutator_third_order = auto() - """Implements Eq. (8) of Ref. [1], i.e. - - .. math:: - e^{\\frac{\\sqrt{5}-1}{2}isH} \\, - e^{\\frac{\\sqrt{5}-1}{2}isD} \\, - e^{-isH} \\, - e^{isD} \\, - e^{\\frac{3-\\sqrt{5}}{2}isH} \\, - e^{isD} \\approx e^{-s^2[H,D]} + O(s^4) \\, . - - :math:`s` must be taken as :math:`\\sqrt{s}` to approximate the flow using the commutator. - """ - - -class DoubleBracketCostFunction(str, Enum): - """Define the DBI cost function.""" - - off_diagonal_norm = "off_diagonal_norm" - """Use off-diagonal norm as cost function.""" - least_squares = "least_squares" - """Use least squares as cost function.""" - energy_fluctuation = "energy_fluctuation" - """Use energy fluctuation as cost function.""" - - -class DoubleBracketScheduling(Enum): - """Define the DBI scheduling strategies.""" - - hyperopt = hyperopt_step - """Use optuna package to hyperoptimize the DBI step.""" - grid_search = grid_search_step - """Use greedy grid search.""" - polynomial_approximation = polynomial_step - """Use polynomial expansion (analytical) of the loss function.""" - simulated_annealing = simulated_annealing_step - """Use simulated annealing algorithm""" - - -class DoubleBracketIteration: - """ - Class implementing the Double Bracket iteration algorithm. For more details, see Ref. [1]. - - Args: - hamiltonian (:class:`qibo.hamiltonians.Hamiltonian`): starting Hamiltonian. - mode (:class:`qibo.models.dbi.double_bracket.DoubleBracketGeneratorType`): - type of generator of the evolution. - scheduling (:class:`qibo.models.dbi.double_bracket.DoubleBracketScheduling`): - type of scheduling strategy. - cost (:class:`qibo.models.dbi.double_bracket.DoubleBracketCostFunction`): - type of cost function. - ref_state (ndarray): reference state for computing the energy fluctuation. - - Example: - .. testcode:: - - from qibo.models.dbi.double_bracket import DoubleBracketIteration, DoubleBracketGeneratorType - from qibo.quantum_info import random_hermitian - from qibo.hamiltonians import Hamiltonian - - nqubits = 4 - h0 = random_hermitian(2**nqubits, seed=2) - dbf = DoubleBracketIteration(Hamiltonian(nqubits=nqubits, matrix=h0)) - - # diagonalized matrix - dbf.h - - References: - 1. M. Gluza, *Double-bracket quantum algorithms for diagonalization*. - `arXiv:2206.11772 [quant-ph] `_. - """ - - def __init__( - self, - hamiltonian, - mode=DoubleBracketGeneratorType.canonical, - scheduling=DoubleBracketScheduling.grid_search, - cost=DoubleBracketCostFunction.off_diagonal_norm, - ref_state=None, - ): - self.h = hamiltonian - self.h0 = copy(self.h) - self.mode = mode - self.scheduling = scheduling - self.cost = cost - self.ref_state = ref_state - - def __call__(self, step: float, mode=None, d=None): - """We use the following convention: - - .. math:: - H^{'} = U^{\\dagger} \\, H \\, U \\, , - - where :math:`U=e^{-s\\,W}`, and :math:`W =[D, H]` (or depending on ``mode`` an - approximation, see `eval_dbr_unitary`). If :math:`s > 0`, then, - for :math:`D = \\Delta(H)`, the GWW DBR will give a :math:`\\sigma`-decrease. - - References: - 1. M. Gluza, *Double-bracket quantum algorithms for diagonalization*. - `arXiv:2206.11772 [quant-ph] `_.""" - - operator = self.eval_dbr_unitary(step, mode, d) - operator_dagger = self.backend.cast( - np.array(np.matrix(self.backend.to_numpy(operator)).getH()) - ) - self.h.matrix = operator_dagger @ self.h.matrix @ operator - return operator - - def eval_dbr_unitary( - self, - step: float, - mode=None, - d=None, - ): - """In :meth:`qibo.models.dbi.double_bracket.DoubleBracketIteration.__call__`, - we are working in the following convention: - - .. math:: - H^{'} = U^{\\dagger} \\, H \\, U \\, , - - where :math:`U = e^{-s\\,W}`, and :math:`W = [D, H]` - (or an approximation of that by a group commutator). - That is convenient because if we switch from the DBI in the Heisenberg picture for the - Hamiltonian, we get that the transformation of the state is - :math:`|\\psi'\\rangle = U \\, |\\psi\\rangle`, so that - - .. math:: - \\langle H\\rangle_{\\psi'} = \\langle H' \\rangle_\\psi \\, , - - i.e. when writing the unitary acting on the state dagger notation is avoided). - The group commutator must approximate :math:`U = e^{-s\\, [D,H]}`. - This is achieved by setting :math:`r = \\sqrt{s}` so that - - .. math:: - V = e^{-i\\,r\\,H} \\, e^{i\\,r\\,D} \\, e^{i\\,r\\,H} \\, e^{-i\\,r\\,D} - - because - - .. math:: - e^{-i\\,r\\,H} \\, D \\, e^{i\\,r\\,H} = D + i\\,r\\,[D, H] +O(r^2) - - so - - .. math:: - V \\approx \\exp\\left(i\\,r\\,D + i^2 \\, r^2 \\, [D, H] + O(r^2) -i\\,r\\,D\\right) \\approx U \\, . - - See the Appendix in Ref. [1] for the complete derivation. - - References: - 1. M. Gluza, *Double-bracket quantum algorithms for diagonalization*. - `arXiv:2206.11772 [quant-ph] `_. - """ - if mode is None: - mode = self.mode - - if mode is DoubleBracketGeneratorType.canonical: - operator = matrix_exponentiation( - -1.0j * step, - self.commutator(self.diagonal_h_matrix, self.h.matrix), - backend=self.backend, - ) - elif mode is DoubleBracketGeneratorType.single_commutator: - if d is None: - d = self.diagonal_h_matrix - operator = matrix_exponentiation( - -1.0j * step, - self.commutator(self.backend.cast(d), self.h.matrix), - backend=self.backend, - ) - elif mode is DoubleBracketGeneratorType.group_commutator: - if d is None: - d = self.diagonal_h_matrix - operator = ( - self.h.exp(step) - @ matrix_exponentiation(-step, d, backend=self.backend) - @ self.h.exp(-step) - @ matrix_exponentiation(step, d, backend=self.backend) - ) - elif mode is DoubleBracketGeneratorType.group_commutator_third_order: - if d is None: - d = self.diagonal_h_matrix - operator = ( - self.h.exp(-step * (np.sqrt(5) - 1) / 2) - @ matrix_exponentiation( - -step * (np.sqrt(5) - 1) / 2, d, backend=self.backend - ) - @ self.h.exp(step) - @ matrix_exponentiation( - step * (np.sqrt(5) + 1) / 2, d, backend=self.backend - ) - @ self.h.exp(-step * (3 - np.sqrt(5)) / 2) - @ matrix_exponentiation(-step, d, backend=self.backend) - ) - operator = ( - matrix_exponentiation(step, d, backend=self.backend) - @ self.h.exp(step * (3 - np.sqrt(5)) / 2) - @ matrix_exponentiation( - -step * (np.sqrt(5) + 1) / 2, d, backend=self.backend - ) - @ self.h.exp(-step) - @ matrix_exponentiation( - step * (np.sqrt(5) - 1) / 2, d, backend=self.backend - ) - @ self.h.exp(step * (np.sqrt(5) - 1) / 2) - ) - else: - raise_error( - NotImplementedError, f"The mode {mode} is not supported" - ) # pragma: no cover - - return operator - - @staticmethod - def commutator(a, b): - """Compute commutator between two arrays.""" - return commutator(a, b) - - @property - def diagonal_h_matrix(self): - """Diagonal H matrix.""" - return self.backend.cast(np.diag(np.diag(self.backend.to_numpy(self.h.matrix)))) - - @property - def off_diag_h(self): - """Off-diagonal H matrix.""" - return self.h.matrix - self.diagonal_h_matrix - - @property - def off_diagonal_norm(self): - """Hilbert Schmidt norm of off-diagonal part of H matrix, namely :math:`\\text{Tr}(\\sqrt{A^{\\dagger} A})`.""" - off_diag_h_dag = self.backend.cast( - np.matrix(self.backend.to_numpy(self.off_diag_h)).getH() - ) - return np.sqrt( - np.real(np.trace(self.backend.to_numpy(off_diag_h_dag @ self.off_diag_h))) - ) - - @property - def backend(self): - """Get Hamiltonian's backend.""" - return self.h0.backend - - @property - def nqubits(self): - """Number of qubits.""" - return self.h.nqubits - - def least_squares(self, d: np.array): - """Least squares cost function.""" - d = self.backend.to_numpy(d) - return np.real( - 0.5 * np.linalg.norm(d) ** 2 - - np.trace(self.backend.to_numpy(self.h.matrix) @ d) - ) - - def choose_step( - self, - d: Optional[np.array] = None, - scheduling: Optional[DoubleBracketScheduling] = None, - **kwargs, - ): - """Calculate the optimal step using respective the `scheduling` methods.""" - if scheduling is None: - scheduling = self.scheduling - step = scheduling(self, d=d, **kwargs) - # TODO: write test for this case - if ( - step is None - and scheduling is DoubleBracketScheduling.polynomial_approximation - ): # pragma: no cover - kwargs["n"] = kwargs.get("n", 3) - kwargs["n"] += 1 - # if n==n_max, return None - step = scheduling(self, d=d, **kwargs) - # if for a given polynomial order n, no solution is found, we increase the order of the polynomial by 1 - return step - - def loss(self, step: float, d: np.array = None, look_ahead: int = 1): - """ - Compute loss function distance between `look_ahead` steps. - - Args: - step (float): iteration step. - d (np.array): diagonal operator, use canonical by default. - look_ahead (int): number of iteration steps to compute the loss function; - """ - # copy initial hamiltonian - h_copy = copy(self.h) - - for _ in range(look_ahead): - self.__call__(mode=self.mode, step=step, d=d) - - # loss values depending on the cost function - if self.cost is DoubleBracketCostFunction.off_diagonal_norm: - loss = self.off_diagonal_norm - elif self.cost is DoubleBracketCostFunction.least_squares: - loss = self.least_squares(d) - elif self.cost == DoubleBracketCostFunction.energy_fluctuation: - loss = self.energy_fluctuation(self.ref_state) - - # set back the initial configuration - self.h = h_copy - - return loss - - def energy_fluctuation(self, state): - """ - Evaluate energy fluctuation. - - .. math:: - \\Xi(\\mu) = \\sqrt{\\langle\\mu|\\hat{H}^2|\\mu\\rangle - \\langle\\mu|\\hat{H}|\\mu\\rangle^2} \\, - - for a given state :math:`|\\mu\\rangle`. - - Args: - state (np.ndarray): quantum state to be used to compute the energy fluctuation with H. - """ - return self.h.energy_fluctuation(state) - - def sigma(self, h: np.array): - """Returns the off-diagonal restriction of matrix `h`.""" - return self.backend.cast(h) - self.backend.cast( - np.diag(np.diag(self.backend.to_numpy(h))) - ) - - def generate_gamma_list(self, n: int, d: np.array): - r"""Computes the n-nested Gamma functions, where $\Gamma_k=[W,...,[W,[W,H]]...]$, where we take k nested commutators with $W = [D, H]$""" - W = self.commutator(self.backend.cast(d), self.sigma(self.h.matrix)) - gamma_list = [self.h.matrix] - for _ in range(n - 1): - gamma_list.append(self.commutator(W, gamma_list[-1])) - return gamma_list - - def cost_expansion(self, d, n): - d = self.backend.cast(d) - - if self.cost is DoubleBracketCostFunction.off_diagonal_norm: - coef = off_diagonal_norm_polynomial_expansion_coef(self, d, n) - elif self.cost is DoubleBracketCostFunction.least_squares: - coef = least_squares_polynomial_expansion_coef( - self, d, n, backend=self.backend - ) - elif self.cost is DoubleBracketCostFunction.energy_fluctuation: - coef = energy_fluctuation_polynomial_expansion_coef( - self, d, n, self.ref_state - ) - else: # pragma: no cover - raise ValueError(f"Cost function {self.cost} not recognized.") - return coef diff --git a/src/qibo/models/dbi/utils.py b/src/qibo/models/dbi/utils.py deleted file mode 100644 index 4a04c7a4f8..0000000000 --- a/src/qibo/models/dbi/utils.py +++ /dev/null @@ -1,286 +0,0 @@ -import math -from enum import Enum, auto -from itertools import combinations, product - -import numpy as np - -from qibo import symbols -from qibo.backends import _check_backend -from qibo.hamiltonians import SymbolicHamiltonian - - -def generate_Z_operators(nqubits: int, backend=None): - """Generate a dictionary containing 1) all possible products of Pauli Z operators for L = n_qubits and 2) their respective names. - Return: Dictionary with operator names (str) as keys and operators (np.array) as values - - Example: - .. testcode:: - - from qibo.models.dbi.utils import generate_Z_operators - from qibo.models.dbi.double_bracket import DoubleBracketIteration - from qibo.quantum_info import random_hermitian - from qibo.hamiltonians import Hamiltonian - import numpy as np - - nqubits = 4 - h0 = random_hermitian(2**nqubits) - dbi = DoubleBracketIteration(Hamiltonian(nqubits=nqubits, matrix=h0)) - generate_Z = generate_Z_operators(nqubits) - Z_ops = list(generate_Z.values()) - - delta_h0 = dbi.diagonal_h_matrix - dephasing_channel = (sum([Z_op @ h0 @ Z_op for Z_op in Z_ops])+h0)/2**nqubits - norm_diff = np.linalg.norm(delta_h0 - dephasing_channel) - """ - - backend = _check_backend(backend) - # list of tuples, e.g. ('Z','I','Z') - combination_strings = product("ZI", repeat=nqubits) - output_dict = {} - - for zi_string_combination in combination_strings: - # except for the identity - if "Z" in zi_string_combination: - op_name = "".join(zi_string_combination) - tensor_op = str_to_symbolic(op_name) - # append in output_dict - output_dict[op_name] = SymbolicHamiltonian( - tensor_op, backend=backend - ).dense.matrix - return output_dict - - -def str_to_symbolic(name: str): - """Convert string into symbolic hamiltonian. - Example: - .. testcode:: - - from qibo.models.dbi.utils import str_to_symbolic - op_name = "ZYXZI" - # returns 5-qubit symbolic hamiltonian - ZIXZI_op = str_to_symbolic(op_name) - """ - tensor_op = 1 - for qubit, char in enumerate(name): - tensor_op *= getattr(symbols, char)(qubit) - return tensor_op - - -def cs_angle_sgn(dbi_object, d, backend=None): - """Calculates the sign of Cauchy-Schwarz Angle :math:`\\langle W(Z), W({\\rm canonical}) \\rangle_{\\rm HS}`.""" - backend = _check_backend(backend) - d = backend.cast(d) - norm = backend.np.trace( - backend.np.matmul( - backend.np.conj( - dbi_object.commutator(dbi_object.diagonal_h_matrix, dbi_object.h.matrix) - ).T, - dbi_object.commutator(d, dbi_object.h.matrix), - ) - ) - return backend.np.real(backend.np.sign(norm)) - - -def decompose_into_pauli_basis(h_matrix: np.array, pauli_operators: list, backend=None): - """finds the decomposition of hamiltonian `h_matrix` into Pauli-Z operators""" - nqubits = int(np.log2(h_matrix.shape[0])) - backend = _check_backend(backend) - decomposition = [] - for Z_i in pauli_operators: - expect = backend.np.trace(h_matrix @ Z_i) / 2**nqubits - decomposition.append(expect) - return decomposition - - -def generate_pauli_index(nqubits, order): - """ - Generate all possible combinations of qubits for a given order of Pauli operators. - """ - if order == 1: - return list(range(nqubits)) - else: - indices = list(range(nqubits)) - return indices + [ - comb for i in range(2, order + 1) for comb in combinations(indices, i) - ] - - -def generate_pauli_operator_dict( - nqubits: int, - parameterization_order: int = 1, - symbols_pauli=symbols.Z, - backend=None, -): - """Generates a dictionary containing Pauli `symbols_pauli` operators of locality `parameterization_order` for `nqubits` qubits. - - Args: - nqubits (int): number of qubits in the system. - parameterization_order (int, optional): the locality of the operators generated. Defaults to 1. - symbols_pauli (qibo.symbols, optional): the symbol of the intended Pauli operator. Defaults to symbols.Z. - - Returns: - pauli_operator_dict (dictionary): dictionary with structure {"operator_name": operator} - - Example: - pauli_operator_dict = generate_pauli_operator_dict) - """ - backend = _check_backend(backend) - pauli_index = generate_pauli_index(nqubits, order=parameterization_order) - pauli_operators = [ - generate_pauli_operators(nqubits, symbols_pauli, index, backend=backend) - for index in pauli_index - ] - return {index: operator for index, operator in zip(pauli_index, pauli_operators)} - - -def generate_pauli_operators(nqubits, symbols_pauli, positions, backend=None): - # generate matrix of an nqubit-pauli operator with `symbols_pauli` at `positions` - if isinstance(positions, int): - return SymbolicHamiltonian( - symbols_pauli(positions), - nqubits=nqubits, - backend=backend, - ).dense.matrix - else: - terms = [symbols_pauli(pos) for pos in positions] - return SymbolicHamiltonian( - math.prod(terms), nqubits=nqubits, backend=backend - ).dense.matrix - - -class ParameterizationTypes(Enum): - """Define types of parameterization for diagonal operator.""" - - pauli = auto() - """Uses Pauli-Z operators (magnetic field).""" - computational = auto() - """Uses computational basis.""" - - -def params_to_diagonal_operator( - params: np.array, - nqubits: int, - parameterization: ParameterizationTypes = ParameterizationTypes.pauli, - pauli_parameterization_order: int = 1, - normalize: bool = False, - pauli_operator_dict: dict = None, - backend=None, -): - r"""Creates the $D$ operator for the double-bracket iteration ansatz depending on the parameterization type.""" - backend = _check_backend(backend) - if parameterization is ParameterizationTypes.pauli: - # raise error if dimension mismatch - d = sum( - [ - backend.to_numpy(params[i]) - * backend.to_numpy(list(pauli_operator_dict.values())[i]) - for i in range(nqubits) - ] - ) - elif parameterization is ParameterizationTypes.computational: - d = np.zeros((len(params), len(params))) - for i in range(len(params)): - d[i, i] = backend.to_numpy(params[i]) - - # TODO: write proper tests for normalize=True - if normalize: # pragma: no cover - d = d / np.linalg.norm(d) - return backend.cast(d) - - -def off_diagonal_norm_polynomial_expansion_coef(dbi_object, d, n): - # generate Gamma's where $\Gamma_{k+1}=[W, \Gamma_{k}], $\Gamma_0=H - W = dbi_object.commutator( - dbi_object.backend.cast(d), dbi_object.sigma(dbi_object.h.matrix) - ) - gamma_list = dbi_object.generate_gamma_list(n + 2, d) - sigma_gamma_list = list(map(dbi_object.sigma, gamma_list)) - gamma_list_np = list(map(dbi_object.backend.to_numpy, sigma_gamma_list)) - exp_list = np.array([1 / math.factorial(k) for k in range(n + 1)]) - # coefficients for rotation with [W,H] and H - c1 = exp_list.reshape((-1, 1, 1)) * gamma_list_np[1:] - c2 = exp_list.reshape((-1, 1, 1)) * gamma_list_np[:-1] - # product coefficient - trace_coefficients = [0] * (2 * n + 1) - for k in range(n + 1): - for j in range(n + 1): - power = k + j - product_matrix = c1[k] @ c2[j] - trace_coefficients[power] += 2 * np.trace(product_matrix) - # coefficients from high to low (n:0) - coef = list(reversed(trace_coefficients[: n + 1])) - return coef - - -def least_squares_polynomial_expansion_coef(dbi_object, d, n: int = 3, backend=None): - """Return the Taylor expansion coefficients of least square cost of `dbi_object.h` and diagonal operator `d` with respect to double bracket rotation duration `s`.""" - # generate Gamma's where $\Gamma_{k+1}=[W, \Gamma_{k}], $\Gamma_0=H - backend = _check_backend(backend) - Gamma_list = dbi_object.generate_gamma_list(n + 1, d) - exp_list = np.array([1 / math.factorial(k) for k in range(n + 1)]) - # coefficients - coef = np.empty(n) - for i in range(n): - coef[i] = backend.np.real( - exp_list[i] - * backend.np.trace(dbi_object.backend.cast(d) @ Gamma_list[i + 1]) - ) - coef = list(reversed(coef)) - return coef - - -def energy_fluctuation_polynomial_expansion_coef( - dbi_object, d: np.array, n: int = 3, state=0 -): - """Return the Taylor expansion coefficients of energy fluctuation of `dbi_object` with respect to double bracket rotation duration `s`.""" - # generate Gamma's where $\Gamma_{k+1}=[W, \Gamma_{k}], $\Gamma_0=H - Gamma_list = dbi_object.generate_gamma_list(n + 1, d) - # coefficients - coef = np.empty(3) - state_cast = dbi_object.backend.cast(state) - state_dag = dbi_object.backend.cast(state.conj().T) - - def variance(a): - """Calculates the variance of a matrix A with respect to a state: - Var($A$) = $\\langle\\mu|A^2|\\mu\rangle-\\langle\\mu|A|\\mu\rangle^2$""" - b = a @ a - return state_dag @ b @ state_cast - (state_dag @ a @ state_cast) ** 2 - - def covariance(a, b): - """This is a generalization of the notion of covariance, needed for the polynomial expansion of the energy fluctuation, - applied to two operators A and B with respect to a state: - Cov($A,B$) = $\\langle\\mu|AB|\\mu\rangle-\\langle\\mu|A|\\mu\rangle\\langle\\mu|B|\\mu\rangle$ - """ - - c = a @ b + b @ a - return ( - state_dag @ c @ state_cast - - 2 * state_dag @ a @ state_cast * state_dag @ b @ state_cast - ) - - coef[0] = np.real(2 * covariance(Gamma_list[0], Gamma_list[1])) - coef[1] = np.real(2 * variance(Gamma_list[1])) - coef[2] = np.real( - covariance(Gamma_list[0], Gamma_list[3]) - + 3 * covariance(Gamma_list[1], Gamma_list[2]) - ) - coef = list(reversed(coef)) - return coef - - -def copy_dbi_object(dbi_object): - """ - Return a copy of the DoubleBracketIteration object. - This is necessary for the `select_best_dbr_generator` function as pytorch do not support deepcopy for leaf tensors. - """ - from copy import copy, deepcopy # pylint: disable=import-outside-toplevel - - dbi_class = dbi_object.__class__ - new = dbi_class.__new__(dbi_class) - - # Manually copy h and h0 as they may be torch tensors - new.h, new.h0 = copy(dbi_object.h), copy(dbi_object.h0) - # Deepcopy the rest of the attributes - for attr in ("mode", "scheduling", "cost", "ref_state"): - setattr(new, attr, deepcopy(getattr(dbi_object, attr, None))) - return new diff --git a/src/qibo/models/dbi/utils_dbr_strategies.py b/src/qibo/models/dbi/utils_dbr_strategies.py deleted file mode 100644 index 3f7ff06221..0000000000 --- a/src/qibo/models/dbi/utils_dbr_strategies.py +++ /dev/null @@ -1,262 +0,0 @@ -import optuna - -from qibo.backends import _check_backend -from qibo.models.dbi.double_bracket import * -from qibo.models.dbi.utils import * - - -def select_best_dbr_generator( - dbi_object: DoubleBracketIteration, - d_list: list, - step: Optional[float] = None, - compare_canonical: bool = True, - scheduling: DoubleBracketScheduling = None, - **kwargs, -): - """Selects the best double bracket rotation generator from a list and execute the rotation. - - Args: - dbi_object (`DoubleBracketIteration`): the target DoubleBracketIteration object. - d_list (list): list of diagonal operators (np.array) to select from. - step (float): fixed iteration duration. - Defaults to ``None``, optimize with `scheduling` method and `choose_step` function. - compare_canonical (boolean): if `True`, the diagonalization effect with operators from `d_list` is compared with the canonical bracket. - scheduling (`DoubleBracketScheduling`): scheduling method for finding the optimal step. - - Returns: - The updated dbi_object (`DoubleBracketIteration`), index of the optimal diagonal operator (int), respective step duration (float), and sign (int). - - Example: - from qibo.hamiltonians import Hamiltonian - from qibo.models.dbi.double_bracket import * - from qibo.models.dbi.utils_dbr_strategies import select_best_dbr_generator - from qibo.quantum_info import random_hermitian - - nqubits = 3 - NSTEPS = 3 - h0 = random_hermitian(2**nqubits) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0), - mode=DoubleBracketGeneratorType.single_commutator, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - generate_local_Z = generate_Z_operators(nqubits) - Z_ops = list(generate_local_Z.values()) - for _ in range(NSTEPS): - dbi, idx, step, flip_sign = select_best_dbr_generator( - dbi, Z_ops, compare_canonical=True - ) - """ - if scheduling is None: - scheduling = dbi_object.scheduling - - if compare_canonical: - norms_off_diagonal_restriction = [dbi_object.off_diagonal_norm] * ( - len(d_list) + 1 - ) - optimal_steps = np.zeros(len(d_list) + 1) - flip_list = np.ones(len(d_list) + 1) - else: - norms_off_diagonal_restriction = [dbi_object.off_diagonal_norm] * (len(d_list)) - optimal_steps = np.zeros(len(d_list)) - flip_list = np.ones(len(d_list)) - - for i, d in enumerate(d_list): - # prescribed step durations - dbi_eval = copy_dbi_object(dbi_object) - d = dbi_eval.backend.cast(d) - flip_list[i] = cs_angle_sgn(dbi_eval, d, backend=dbi_object.backend) - if flip_list[i] != 0: - if step is None: - step_best = dbi_eval.choose_step( - d=flip_list[i] * d, scheduling=scheduling, **kwargs - ) - else: - step_best = step - dbi_eval(step=step_best, d=flip_list[i] * d) - optimal_steps[i] = step_best - norms_off_diagonal_restriction[i] = dbi_eval.off_diagonal_norm - # canonical - if compare_canonical is True: - dbi_eval = copy_dbi_object(dbi_object) - dbi_eval.mode = DoubleBracketGeneratorType.canonical - if step is None: - step_best = dbi_eval.choose_step(scheduling=scheduling, **kwargs) - else: - step_best = step - dbi_eval(step=step_best) - optimal_steps[-1] = step_best - norms_off_diagonal_restriction[-1] = dbi_eval.off_diagonal_norm - # find best d - idx_max_loss = np.argmin(norms_off_diagonal_restriction) - flip = flip_list[idx_max_loss] - step_optimal = optimal_steps[idx_max_loss] - dbi_eval = copy_dbi_object(dbi_object) - if idx_max_loss == len(d_list) and compare_canonical is True: - # canonical - dbi_eval(step=step_optimal, mode=DoubleBracketGeneratorType.canonical) - - else: - d_optimal = flip * d_list[idx_max_loss] - dbi_eval(step=step_optimal, d=d_optimal) - return dbi_eval, idx_max_loss, step_optimal, flip - - -def gradient_numerical( - dbi_object: DoubleBracketIteration, - d_params: list, - parameterization: ParameterizationTypes, - s: float = 1e-2, - delta: float = 1e-3, - backend=None, - **kwargs, -): - r""" - Gradient of the DBI with respect to the parametrization of D. A simple finite difference is used to calculate the gradient. - - Args: - dbi_object (DoubleBracketIteration): DoubleBracketIteration object. - d_params (np.array): Parameters for the ansatz (note that the dimension must be 2**nqubits for full ansazt and nqubits for Pauli ansatz). - s (float): A short flow duration for finding the numerical gradient. - delta (float): Step size for numerical gradient. - Returns: - grad (np.array): Gradient of the D operator. - """ - backend = _check_backend(backend) - nqubits = dbi_object.nqubits - grad = np.zeros(len(d_params)) - d = params_to_diagonal_operator( - d_params, nqubits, parameterization=parameterization, **kwargs, backend=backend - ) - for i in range(len(d_params)): - params_new = backend.to_numpy(d_params).copy() - params_new[i] = params_new[i] + delta - d_new = params_to_diagonal_operator( - params_new, - nqubits, - parameterization=parameterization, - **kwargs, - backend=backend, - ) - # find the increment of a very small step - grad[i] = (dbi_object.loss(s, d_new) - dbi_object.loss(s, d)) / delta - return grad - - -def gradient_descent( - dbi_object: DoubleBracketIteration, - iterations: int, - d_params: list, - parameterization: ParameterizationTypes, - pauli_operator_dict: dict = None, - pauli_parameterization_order: int = 1, - normalize: bool = False, - lr_min: float = 1e-5, - lr_max: float = 1, - max_evals: int = 100, - space: callable = None, - optimizer: optuna.samplers.BaseSampler = optuna.samplers.TPESampler(), - verbose: bool = False, - backend=None, -): - r"""Numerical gradient descent method for variating diagonal operator in each double bracket rotation. - - Args: - dbi_object (DoubleBracketIteration): the target double bracket object. - iterations (int): number of double bracket rotations. - d_params (list): the parameters for the initial diagonal operator. - parameterization (ParameterizationTypes): the parameterization method for diagonal operator. - Options include pauli and computational. - pauli_operator_dict (dictionary, optional): dictionary of "name": Pauli-operator for Pauli-based parameterization type. - Defaults to None. - pauli_parameterization_order (int, optional): the order of parameterization or locality in Pauli basis. Defaults to 1. - normalize (bool, optional): option to normalize the diagonal operator. Defaults to False. - lr_min (float, optional): the minimal gradient step. Defaults to 1e-5. - lr_max (float, optional): the maximal gradient step. Defaults to 1. - max_evals (int, optional): maximum number of evaluations for `lr` using `optuna`. Defaults to 100. - space (callable, optional): evalutation space for `optuna`. Defaults to None. - optimizer (optuna.samplers.BaseSampler, optional): optimizer option for `optuna`. Defaults to `TPESampler()`. - verbose (bool, optional): option for printing `optuna` process. Defaults to False. - - Returns: - loss_hist (list): list of history losses of `dbi_object` throughout the double bracket rotations. - d_params_hist (list): list of history of `d` parameters after gradient descent. - s_hist (list): list of history of optimal `s` found. - """ - backend = _check_backend(backend) - - nqubits = dbi_object.nqubits - if ( - parameterization is ParameterizationTypes.pauli and pauli_operator_dict is None - ): # pragma: no cover - pauli_operator_dict = generate_pauli_operator_dict( - nqubits=nqubits, parameterization_order=pauli_parameterization_order - ) - - d = params_to_diagonal_operator( - d_params, - nqubits, - parameterization=parameterization, - pauli_operator_dict=pauli_operator_dict, - normalize=normalize, - backend=backend, - ) - - loss_hist = [dbi_object.loss(0.0, d=d)] - d_params_hist = [d_params] - s_hist = [0] - - s = dbi_object.choose_step(d=d) - dbi_object(step=s, d=d) - - for _ in range(iterations): - grad = gradient_numerical( - dbi_object, - d_params, - parameterization, - pauli_operator_dict=pauli_operator_dict, - pauli_parameterization_order=pauli_parameterization_order, - normalize=normalize, - backend=backend, - ) - - def func_loss_to_lr(trial): - lr = trial.suggest_loguniform("lr", lr_min, lr_max) - d_params_eval = [d_params[j] - grad[j] * lr for j in range(len(grad))] - d_eval = params_to_diagonal_operator( - d_params_eval, - nqubits, - parameterization=parameterization, - pauli_operator_dict=pauli_operator_dict, - normalize=normalize, - backend=backend, - ) - return dbi_object.loss(step=s, d=d_eval) - - # create a study using the specified optimizer (sampler) - study = optuna.create_study(sampler=optimizer, direction="minimize") - - # optimize the function - study.optimize(func_loss_to_lr, n_trials=max_evals) - - # get the best learning rate - lr = study.best_params["lr"] - - d_params = [d_params[j] - grad[j] * lr for j in range(len(grad))] - d = params_to_diagonal_operator( - d_params, - nqubits, - parameterization=parameterization, - pauli_operator_dict=pauli_operator_dict, - normalize=normalize, - backend=backend, - ) - s = dbi_object.choose_step(d=d) - dbi_object(step=s, d=d) - - # record history - loss_hist.append(dbi_object.loss(0.0, d=d)) - d_params_hist.append(d_params) - s_hist.append(s) - - return loss_hist, d_params_hist, s_hist diff --git a/src/qibo/models/dbi/utils_scheduling.py b/src/qibo/models/dbi/utils_scheduling.py deleted file mode 100644 index 1f08ca2e04..0000000000 --- a/src/qibo/models/dbi/utils_scheduling.py +++ /dev/null @@ -1,209 +0,0 @@ -import math -from typing import Optional - -import numpy as np -import optuna - -error = 1e-3 - - -def grid_search_step( - dbi_object, - step_min: float = 1e-5, - step_max: float = 1, - num_evals: int = 100, - space: Optional[np.array] = None, - d: Optional[np.array] = None, -): - """ - Greedy optimization of the iteration step. - - Args: - step_min: lower bound of the search grid; - step_max: upper bound of the search grid; - mnum_evals: number of iterations between step_min and step_max; - d: diagonal operator for generating double-bracket iterations. - - Returns: - (float): optimized best iteration step (minimizing off-diagonal norm). - """ - if space is None: - space = np.linspace(step_min, step_max, num_evals) - - if d is None: - d = dbi_object.diagonal_h_matrix - - loss_list = [dbi_object.loss(step, d=d) for step in space] - - idx_max_loss = np.argmin(loss_list) - return space[idx_max_loss] - - -def hyperopt_step( - self, - step_min: float = 1e-5, - step_max: float = 1, - max_evals: int = 1000, - look_ahead: int = 1, - verbose: bool = False, - d: np.array = None, - optimizer: optuna.samplers.BaseSampler = None, -): - """ - Optimize iteration step using Optuna. - - Args: - step_min: lower bound of the search grid; - step_max: upper bound of the search grid; - max_evals: maximum number of trials done by the optimizer; - look_ahead: number of iteration steps to compute the loss function; - verbose: level of verbosity; - d: diagonal operator for generating double-bracket iterations; - optimizer: Optuna sampler for the search algorithm (e.g., - optuna.samplers.TPESampler()). - See: https://optuna.readthedocs.io/en/stable/reference/samplers/index.html - - Returns: - (float): optimized best iteration step. - """ - optuna.logging.set_verbosity(optuna.logging.WARNING) - - def objective(trial): - step = trial.suggest_float("step", step_min, step_max) - return self.loss(step, d=d, look_ahead=look_ahead) - - if optimizer is None: - optimizer = optuna.samplers.TPESampler() - - study = optuna.create_study(direction="minimize", sampler=optimizer) - study.optimize(objective, n_trials=max_evals, show_progress_bar=verbose) - - return study.best_params["step"] - - -def polynomial_step( - dbi_object, - n: int = 2, - n_max: int = 5, - d: np.array = None, - coef: Optional[list] = None, - cost: Optional[str] = None, -): - r""" - Optimizes iteration step by solving the n_th order polynomial expansion of the loss function. - e.g. $n=2$: $2\Trace(\sigma(\Gamma_1 + s\Gamma_2 + s^2/2\Gamma_3)\sigma(\Gamma_0 + s\Gamma_1 + s^2/2\Gamma_2)) - Args: - n (int, optional): the order to which the loss function is expanded. Defaults to 4. - n_max (int, optional): maximum order allowed for recurring calls of `polynomial_step`. Defaults to 5. - d (np.array, optional): diagonal operator, default as $\delta(H)$. - backup_scheduling (`DoubleBracketScheduling`): the scheduling method to use in case no real positive roots are found. - """ - if cost is None: - cost = dbi_object.cost - - if d is None: - d = dbi_object.diagonal_h_matrix - - if n > n_max: - raise ValueError( - "No solution can be found with polynomial approximation. Increase `n_max` or use other scheduling methods." - ) - if coef is None: - coef = dbi_object.cost_expansion(d=d, n=n) - roots = np.roots(coef) - real_positive_roots = [ - np.real(root) for root in roots if np.imag(root) < 1e-3 and np.real(root) > 0 - ] - # solution exists, return minimum s - if len(real_positive_roots) > 0: - losses = [dbi_object.loss(step=root, d=d) for root in real_positive_roots] - return real_positive_roots[losses.index(min(losses))] - # solution does not exist, return None - else: - return None - - -def simulated_annealing_step( - dbi_object, - d: Optional[np.array] = None, - initial_s=None, - step_min=1e-5, - step_max=1, - s_jump_range=None, - s_jump_range_divident=5, - initial_temp=1, - cooling_rate=0.85, - min_temp=1e-5, - max_iter=200, -): - """ - Perform a single step of simulated annealing optimization. - - Parameters: - dbi_object: DBI object - The object representing the problem to be optimized. - d: Optional[np.array], optional - The diagonal matrix 'd' used in optimization. If None, it uses the diagonal - matrix 'diagonal_h_matrix' from dbi_object. - initial_s: float or None, optional - Initial value for 's', the step size. If None, it is initialized using - polynomial_step function with 'n=4'. If 'polynomial_step' returns None, - 'initial_s' is set to 'step_min'. - step_min: float, optional - Minimum value for the step size 's'. - step_max: float, optional - Maximum value for the step size 's'. - s_jump_range: float or None, optional - Range for the random jump in step size. If None, it's calculated based on - 'step_min', 'step_max', and 's_jump_range_divident'. - s_jump_range_divident: int, optional - Dividend to determine the range for random jump in step size. - initial_temp: float, optional - Initial temperature for simulated annealing. - cooling_rate: float, optional - Rate at which temperature decreases in simulated annealing. - min_temp: float, optional - Minimum temperature threshold for termination of simulated annealing. - max_iter: int, optional - Maximum number of iterations for simulated annealing. - - Returns: - float: - The optimized step size 's'. - """ - - if d is None: - d = dbi_object.diagonal_h_matrix - if initial_s is None: - initial_s = polynomial_step(dbi_object=dbi_object, d=d, n=4) - # TODO: implement test to catch this if statement - if initial_s is None: # pragma: no cover - initial_s = step_min - if s_jump_range is None: - s_jump_range = (step_max - step_min) / s_jump_range_divident - current_s = initial_s - current_loss = dbi_object.loss(d=d, step=current_s) - temp = initial_temp - - for _ in range(max_iter): - candidate_s = max( - step_min, - min( - current_s + np.random.uniform(-1 * s_jump_range, s_jump_range), step_max - ), - ) - candidate_loss = dbi_object.loss(d=d, step=candidate_s) - - # Calculate change in loss - delta_loss = candidate_loss - current_loss - - # Determine if the candidate solution is an improvement - if delta_loss < 0 or np.random.rand() < math.exp(-delta_loss / temp): - current_s = candidate_s - current_loss = candidate_loss - # Cool down - temp *= cooling_rate - if temp < min_temp or current_s > step_max or current_s < step_min: - break - - return current_s diff --git a/tests/test_models_dbi.py b/tests/test_models_dbi.py deleted file mode 100644 index d19168caa9..0000000000 --- a/tests/test_models_dbi.py +++ /dev/null @@ -1,293 +0,0 @@ -"""Testing DoubleBracketIteration model""" - -import numpy as np -import pytest - -from qibo import hamiltonians -from qibo.hamiltonians import Hamiltonian -from qibo.models.dbi.double_bracket import ( - DoubleBracketCostFunction, - DoubleBracketGeneratorType, - DoubleBracketIteration, - DoubleBracketScheduling, -) -from qibo.models.dbi.utils import * -from qibo.models.dbi.utils_dbr_strategies import ( - gradient_descent, - select_best_dbr_generator, -) -from qibo.models.dbi.utils_scheduling import polynomial_step -from qibo.quantum_info import random_hermitian - -NSTEPS = 3 -seed = 10 -"""Number of steps for evolution.""" - - -@pytest.mark.parametrize("nqubits", [1, 2]) -def test_double_bracket_iteration_canonical(backend, nqubits): - """Check default (canonical) mode.""" - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.canonical, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - for _ in range(NSTEPS): - dbi(step=np.sqrt(0.001)) - - assert initial_off_diagonal_norm > dbi.off_diagonal_norm - - -@pytest.mark.parametrize("nqubits", [1, 2]) -def test_double_bracket_iteration_group_commutator(backend, nqubits): - """Check group commutator mode.""" - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - d = backend.cast(np.diag(np.diag(backend.to_numpy(h0)))) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.group_commutator, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - - # test first iteration with default d - dbi(mode=DoubleBracketGeneratorType.group_commutator, step=0.01) - for _ in range(NSTEPS): - dbi(step=0.01, d=d) - - assert initial_off_diagonal_norm > dbi.off_diagonal_norm - - -@pytest.mark.parametrize("nqubits", [1, 2]) -def test_double_bracket_iteration_group_commutator_3rd_order(backend, nqubits): - """Check 3rd order group commutator mode.""" - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - d = backend.cast(np.diag(np.diag(backend.to_numpy(h0)))) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.group_commutator_third_order, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - - # test first iteration with default d - dbi(mode=DoubleBracketGeneratorType.group_commutator_third_order, step=0.01) - for _ in range(NSTEPS): - dbi(step=0.01, d=d) - - assert initial_off_diagonal_norm > dbi.off_diagonal_norm - - -@pytest.mark.parametrize("nqubits", [1, 2]) -def test_double_bracket_iteration_single_commutator(backend, nqubits): - """Check single commutator mode.""" - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - d = backend.cast(np.diag(np.diag(backend.to_numpy(h0)))) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.single_commutator, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - - # test first iteration with default d - dbi(mode=DoubleBracketGeneratorType.single_commutator, step=0.01) - - for _ in range(NSTEPS): - dbi(step=0.01, d=d) - - assert initial_off_diagonal_norm > dbi.off_diagonal_norm - - -@pytest.mark.parametrize("nqubits", [2, 3]) -@pytest.mark.parametrize( - "scheduling", - [ - DoubleBracketScheduling.grid_search, - DoubleBracketScheduling.hyperopt, - DoubleBracketScheduling.simulated_annealing, - ], -) -def test_variational_scheduling(backend, nqubits, scheduling): - """Check schduling options.""" - h = 2 - - # define the hamiltonian - h0 = hamiltonians.TFIM(nqubits=nqubits, h=h) - dbi = DoubleBracketIteration(h0, scheduling=scheduling) - # find initial best step with look_ahead = 1 - initial_off_diagonal_norm = dbi.off_diagonal_norm - for _ in range(NSTEPS): - step = dbi.choose_step() - dbi(step=step) - assert initial_off_diagonal_norm > dbi.off_diagonal_norm - - -@pytest.mark.parametrize( - "cost", - [ - DoubleBracketCostFunction.off_diagonal_norm, - DoubleBracketCostFunction.least_squares, - ], -) -def test_polynomial_cost_function(backend, cost): - nqubits = 2 - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.single_commutator, - cost=cost, - scheduling=DoubleBracketScheduling.polynomial_approximation, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - for i in range(NSTEPS): - s = dbi.choose_step(d=dbi.diagonal_h_matrix, n=5) - dbi(step=s, d=dbi.off_diag_h) - assert initial_off_diagonal_norm > dbi.off_diagonal_norm - - -def test_polynomial_energy_fluctuation(backend): - nqubits = 4 - h0 = random_hermitian(2**nqubits, seed=seed, backend=backend) - state = np.zeros(2**nqubits) - state[0] = 1 - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.single_commutator, - cost=DoubleBracketCostFunction.energy_fluctuation, - scheduling=DoubleBracketScheduling.polynomial_approximation, - ref_state=state, - ) - for i in range(NSTEPS): - s = dbi.choose_step(d=dbi.diagonal_h_matrix, n=5) - dbi(step=s, d=dbi.diagonal_h_matrix) - assert dbi.energy_fluctuation(state=state) < dbi.h0.energy_fluctuation(state=state) - - -@pytest.mark.parametrize("nqubits", [5, 6]) -def test_polynomial_fail_cases(backend, nqubits): - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.single_commutator, - scheduling=DoubleBracketScheduling.polynomial_approximation, - ) - with pytest.raises(ValueError): - polynomial_step(dbi, n=2, n_max=1) - assert polynomial_step(dbi, n=1) is None - - -def test_least_squares(backend): - """Check least squares cost function.""" - nqubits = 4 - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - cost=DoubleBracketCostFunction.least_squares, - ) - d = np.diag(np.linspace(1, 2**nqubits, 2**nqubits)) / 2**nqubits - initial_potential = dbi.least_squares(d=d) - step = dbi.choose_step(d=d) - dbi(d=d, step=step) - assert dbi.least_squares(d=d) < initial_potential - - -@pytest.mark.parametrize("compare_canonical", [True, False]) -@pytest.mark.parametrize("step", [None, 1e-3]) -@pytest.mark.parametrize("nqubits", [2, 3]) -def test_select_best_dbr_generator(backend, nqubits, step, compare_canonical): - h0 = random_hermitian(2**nqubits, backend=backend, seed=seed) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.single_commutator, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - generate_local_Z = generate_Z_operators(nqubits, backend=backend) - Z_ops = list(generate_local_Z.values()) - for _ in range(NSTEPS): - dbi, idx, step, flip_sign = select_best_dbr_generator( - dbi, - Z_ops, - compare_canonical=compare_canonical, - step=step, - ) - assert dbi.off_diagonal_norm < initial_off_diagonal_norm - - -@pytest.mark.parametrize("step", [None, 1e-3]) -def test_params_to_diagonal_operator(backend, step): - nqubits = 2 - pauli_operator_dict = generate_pauli_operator_dict( - nqubits, parameterization_order=1, backend=backend - ) - params = [1, 2, 3] - operator_pauli = sum( - [params[i] * list(pauli_operator_dict.values())[i] for i in range(nqubits)] - ) - backend.assert_allclose( - operator_pauli, - params_to_diagonal_operator( - params, - nqubits=nqubits, - parameterization=ParameterizationTypes.pauli, - pauli_operator_dict=pauli_operator_dict, - backend=backend, - ), - ) - operator_element = params_to_diagonal_operator( - params, - nqubits=nqubits, - parameterization=ParameterizationTypes.computational, - backend=backend, - ) - for i in range(len(params)): - backend.assert_allclose( - backend.cast(backend.to_numpy(operator_element).diagonal())[i], params[i] - ) - - -@pytest.mark.parametrize("order", [1, 2]) -def test_gradient_descent(backend, order): - nqubits = 2 - h0 = random_hermitian(2**nqubits, seed=seed, backend=backend) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.single_commutator, - scheduling=DoubleBracketScheduling.hyperopt, - cost=DoubleBracketCostFunction.off_diagonal_norm, - ) - initial_off_diagonal_norm = dbi.off_diagonal_norm - pauli_operator_dict = generate_pauli_operator_dict( - nqubits, - parameterization_order=order, - backend=backend, - ) - pauli_operators = list(pauli_operator_dict.values()) - # let initial d be approximation of $\Delta(H) - d_coef_pauli = decompose_into_pauli_basis( - dbi.diagonal_h_matrix, pauli_operators=pauli_operators, backend=backend - ) - d_pauli = sum([d_coef_pauli[i] * pauli_operators[i] for i in range(nqubits)]) - loss_hist_pauli, d_params_hist_pauli, s_hist_pauli = gradient_descent( - dbi, - NSTEPS, - d_coef_pauli, - ParameterizationTypes.pauli, - pauli_operator_dict=pauli_operator_dict, - pauli_parameterization_order=order, - backend=backend, - ) - assert loss_hist_pauli[-1] < initial_off_diagonal_norm - - # computational basis - d_coef_computational_partial = backend.cast(backend.to_numpy(d_pauli).diagonal()) - ( - loss_hist_computational_partial, - _, - _, - ) = gradient_descent( - dbi, - NSTEPS, - d_coef_computational_partial, - ParameterizationTypes.computational, - backend=backend, - ) - assert loss_hist_computational_partial[-1] < initial_off_diagonal_norm diff --git a/tests/test_models_dbi_utils.py b/tests/test_models_dbi_utils.py deleted file mode 100644 index 29d1b1058b..0000000000 --- a/tests/test_models_dbi_utils.py +++ /dev/null @@ -1,61 +0,0 @@ -""""Testing utils for DoubleBracketIteration model""" - -import numpy as np -import pytest - -from qibo.hamiltonians import Hamiltonian -from qibo.models.dbi.double_bracket import ( - DoubleBracketGeneratorType, - DoubleBracketIteration, -) -from qibo.models.dbi.utils import * -from qibo.models.dbi.utils_dbr_strategies import select_best_dbr_generator -from qibo.quantum_info import random_hermitian - -NSTEPS = 5 -"""Number of steps for evolution.""" - - -@pytest.mark.parametrize("nqubits", [1, 2]) -def test_generate_Z_operators(backend, nqubits): - h0 = random_hermitian(2**nqubits, backend=backend) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits=nqubits, matrix=h0, backend=backend) - ) - generate_Z = generate_Z_operators(nqubits, backend=backend) - Z_ops = list(generate_Z.values()) - - delta_h0 = dbi.diagonal_h_matrix - dephasing_channel = (sum([Z_op @ h0 @ Z_op for Z_op in Z_ops]) + h0) / 2**nqubits - norm_diff = np.linalg.norm(backend.to_numpy(delta_h0 - dephasing_channel)) - - assert norm_diff < 1e-3 - - -@pytest.mark.parametrize("nqubits", [1, 2]) -@pytest.mark.parametrize("step", [0.1, 0.2]) -def test_select_best_dbr_generator(backend, nqubits, step): - h0 = random_hermitian(2**nqubits, seed=1, backend=backend) - dbi = DoubleBracketIteration( - Hamiltonian(nqubits, h0, backend=backend), - mode=DoubleBracketGeneratorType.single_commutator, - ) - generate_Z = generate_Z_operators(nqubits, backend=backend) - Z_ops = list(generate_Z.values()) - initial_off_diagonal_norm = dbi.off_diagonal_norm - - for _ in range(NSTEPS): - dbi, idx, step_optimize, flip = select_best_dbr_generator( - dbi, Z_ops, step=step, compare_canonical=True, max_evals=5 - ) - - assert initial_off_diagonal_norm > dbi.off_diagonal_norm - - -def test_copy_dbi(backend): - h0 = random_hermitian(4, seed=1, backend=backend) - dbi = DoubleBracketIteration(Hamiltonian(2, h0, backend=backend)) - dbi_copy = copy_dbi_object(dbi) - - assert dbi is not dbi_copy - assert dbi.h.nqubits == dbi_copy.h.nqubits