From 1948c012166fec7c92e3bc6307c79b8ece389646 Mon Sep 17 00:00:00 2001 From: Sam-XiaoyueLi Date: Tue, 30 Jan 2024 14:34:55 +0800 Subject: [PATCH] Notebook section shows difference of scheduling techniques in Pauli-Z strategies --- examples/dbi/dbi_scheduling.ipynb | 110 ++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/examples/dbi/dbi_scheduling.ipynb b/examples/dbi/dbi_scheduling.ipynb index 15f4de2339..275d2dea73 100644 --- a/examples/dbi/dbi_scheduling.ipynb +++ b/examples/dbi/dbi_scheduling.ipynb @@ -170,13 +170,16 @@ "source": [ "# grid_search\n", "step_grid = dbi.choose_step(scheduling=DoubleBracketScheduling.use_grid_search, step_max=0.6, d=d)\n", - "print('grid_search step:', step_grid)\n", + "grid_min = dbi.loss(step=step_grid, d=d)-dbi.off_diagonal_norm\n", + "print('grid_search step:', step_grid, 'loss', grid_min)\n", "# hyperopt\n", "step_hyperopt = dbi.choose_step(scheduling=DoubleBracketScheduling.use_hyperopt, d=d, max_evals=100, step_max=0.6)\n", - "print('hyperopt_search step:', step_hyperopt)\n", + "hyperopt_min = dbi.loss(step=step_hyperopt, d=d)-dbi.off_diagonal_norm\n", + "print('hyperopt_search step:', step_hyperopt, 'loss', hyperopt_min)\n", "# polynomial expansion\n", "step_poly = dbi.choose_step(scheduling=DoubleBracketScheduling.use_polynomial_approximation, d=d, n=5)\n", - "print('polynomial_approximation step:', step_poly)" + "poly_min = dbi.loss(step=step_poly, d=d)-dbi.off_diagonal_norm\n", + "print('polynomial_approximation step:', step_poly, 'loss', poly_min)" ] }, { @@ -188,6 +191,8 @@ "# Plot the results\n", "plt.plot(s_space, off_diagonal_norm_diff)\n", "plt.axvline(x=step_grid, color='r', linestyle='-',label='grid_search')\n", + "plt.text(x=step_grid, y=grid_min, s=f'grid min \\n{round(grid_min,3)}')\n", + "plt.text(x=step_poly, y=poly_min, s=f'grid min \\n{round(poly_min,3)}')\n", "plt.axvline(x=step_hyperopt, color='g', linestyle='--',label='hyperopt')\n", "plt.axvline(x=step_poly, color='m', linestyle='-.',label='polynomial')\n", "plt.ylabel(r'$||\\sigma(H_0)||-\\sigma(H_k)||$')\n", @@ -208,7 +213,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Use polynomial expansion as an restriction of hyperopt/grid range" + "## Use polynomial expansion as an restriction for hyperopt/grid range" ] }, { @@ -256,6 +261,103 @@ "source": [ "Hence, we see that the strategy is indeed effective for finding the first minimum of the loss funciton for both the Z operator and the ZI operator." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compare in Pauli-Z strategy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from qibo.quantum_info import random_hermitian\n", + "from qibo.hamiltonians import Hamiltonian" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Hamiltonian\n", + "set_backend(\"qibojit\", \"numba\")\n", + "nqubits = 4\n", + "h0 = random_hermitian(2**nqubits)\n", + "\n", + "# initialize class\n", + "dbi = DoubleBracketIteration(deepcopy(Hamiltonian(nqubits=nqubits, matrix=h0)),mode=DoubleBracketGeneratorType.single_commutator)\n", + "print(\"Initial off diagonal norm\", dbi.off_diagonal_norm)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "generate_local_Z = generate_Z_operators(nqubits)\n", + "Z_ops = list(generate_local_Z.values())\n", + "Z_names = list(generate_local_Z.keys())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "NSTEPS = 8\n", + "scheduling_list = [DoubleBracketScheduling.use_grid_search,\n", + " DoubleBracketScheduling.use_hyperopt,\n", + " DoubleBracketScheduling.use_polynomial_approximation,]\n", + "scheduling_labels = ['grid search',\n", + " 'hyperopt',\n", + " 'polynomial',]\n", + "Z_optimal_scheduling = []\n", + "s_scheduling = []\n", + "off_norm_scheduling =[]\n", + "for i,scheduling in enumerate(scheduling_list):\n", + " # reinitialize\n", + " dbi = DoubleBracketIteration(Hamiltonian(nqubits=nqubits, matrix=deepcopy(h0)), mode=DoubleBracketGeneratorType.single_commutator)\n", + " Z_optimal = []\n", + " # add in initial values for plotting\n", + " off_diagonal_norm_history = [dbi.off_diagonal_norm]\n", + " steps = [0]\n", + " print(f'----------Scheduling {scheduling_labels[i]}----------')\n", + " for _ in range(NSTEPS):\n", + " dbi, idx, step, flip_sign = select_best_dbr_generator(dbi, Z_ops, scheduling=scheduling, compare_canonical=False)\n", + " off_diagonal_norm_history.append(dbi.off_diagonal_norm)\n", + " steps.append(steps[-1]+step)\n", + " if flip_sign < 0:\n", + " Z_optimal.append('-' + Z_names[idx])\n", + " else:\n", + " Z_optimal.append(Z_names[idx])\n", + " print(f\"New optimized step at iteration {_+1}/{NSTEPS}: {step} with operator {Z_optimal[-1]}, loss {dbi.off_diagonal_norm}\")\n", + " Z_optimal_scheduling.append(Z_optimal)\n", + " s_scheduling.append(steps)\n", + " off_norm_scheduling.append(off_diagonal_norm_history)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure()\n", + "for i, scheduling in enumerate(scheduling_labels):\n", + " plt.plot(s_scheduling[i], off_norm_scheduling[i], '-o', label=scheduling)\n", + "plt.xlabel(\"Iterations\")\n", + "plt.ylabel(\"Norm off-diagonal restriction\")\n", + "plt.title(\"Compare Variational Pauli-Z using different scheduling strategies\")\n", + "plt.legend()" + ] } ], "metadata": {