diff --git a/community/QClass_2024/Submissions/HW3/Otmane_Ainelkitane_HW3_VQE.ipynb b/community/QClass_2024/Submissions/HW3/Otmane_Ainelkitane_HW3_VQE.ipynb new file mode 100644 index 00000000..d9fc502d --- /dev/null +++ b/community/QClass_2024/Submissions/HW3/Otmane_Ainelkitane_HW3_VQE.ipynb @@ -0,0 +1,419 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fc72d98f-8993-4bd4-a545-23d122f3df71", + "metadata": { + "id": "fc72d98f-8993-4bd4-a545-23d122f3df71" + }, + "source": [ + "# H₂ Molecule Homework Assignment\n", + "### Quantum Software Development Journey: From Theory to Application with Classiq - Part 3\n", + "\n", + "- Similarly to what we have done in class, in this exercise we will implement the VQE on H2 molecule.\n", + "- This time instead of using the built-in methods and functions (such as `Molecule` and `MoleculeProblem`) to difne and solve the problem, you will be provided with a two qubits Hamiltonian." + ] + }, + { + "cell_type": "markdown", + "id": "56eda6d8-76c4-4862-b914-0c4598d67274", + "metadata": { + "id": "56eda6d8-76c4-4862-b914-0c4598d67274" + }, + "source": [ + "## Submission\n", + "- Submit the completed Jupyter notebook and report via GitHub. Ensure all files are correctly named and organized.\n", + "- Use the Typeform link provided in the submission folder to confirm your submission.\n", + "\n", + "## Additional Resources\n", + "- [Classiq Documentation](https://docs.classiq.io/latest/)\n", + "- The notebook from live session #3\n", + "\n", + "## Important Dates\n", + "- **Assignment Release:** 22.5.2024\n", + "- **Submission Deadline:** 3.6.2024 (7 A.M GMT+3)\n", + "\n", + "---\n", + "\n", + "Happy coding and good luck!" + ] + }, + { + "cell_type": "markdown", + "id": "d41e969d-f6a7-4ff7-9660-19ce6c97ba6b", + "metadata": { + "id": "d41e969d-f6a7-4ff7-9660-19ce6c97ba6b" + }, + "source": [ + "### Part 1" + ] + }, + { + "cell_type": "markdown", + "id": "f710d6f4-d40b-42d5-b524-c6acb8059fe2", + "metadata": { + "id": "f710d6f4-d40b-42d5-b524-c6acb8059fe2" + }, + "source": [ + "Given the following Hamiltonian:" + ] + }, + { + "cell_type": "markdown", + "id": "6ba8a6f1-3259-4492-a1ca-3abde7530cd4", + "metadata": { + "id": "6ba8a6f1-3259-4492-a1ca-3abde7530cd4" + }, + "source": [ + "$$\n", + "\\hat{H} = -1.0523 \\cdot (I \\otimes I) + 0.3979 \\cdot (I \\otimes Z) - 0.3979 \\cdot (Z \\otimes I) - 0.0112 \\cdot (Z \\otimes Z) + 0.1809 \\cdot (X \\otimes X)\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "736d275c-9a5a-4c08-b891-3078430dc6c1", + "metadata": { + "id": "736d275c-9a5a-4c08-b891-3078430dc6c1" + }, + "source": [ + "Complete the following code" + ] + }, + { + "cell_type": "code", + "source": [ + "!pip install -U -q classiq" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "imjx_MjrLbGs", + "outputId": "41671177-4fd4-4eef-d299-b5edab53a274" + }, + "id": "imjx_MjrLbGs", + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m398.1/398.1 kB\u001b[0m \u001b[31m3.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m10.7/10.7 MB\u001b[0m \u001b[31m25.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m33.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.0/2.0 MB\u001b[0m \u001b[31m26.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m42.6/42.6 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m41.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.4/6.4 MB\u001b[0m \u001b[31m41.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.6/49.6 kB\u001b[0m \u001b[31m5.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "torch 2.3.0+cu121 requires nvidia-cublas-cu12==12.1.3.1; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-cuda-cupti-cu12==12.1.105; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-cuda-nvrtc-cu12==12.1.105; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-cuda-runtime-cu12==12.1.105; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-cudnn-cu12==8.9.2.26; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-cufft-cu12==11.0.2.54; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-curand-cu12==10.3.2.106; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-cusolver-cu12==11.4.5.107; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-cusparse-cu12==12.1.0.106; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-nccl-cu12==2.20.5; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\n", + "torch 2.3.0+cu121 requires nvidia-nvtx-cu12==12.1.105; platform_system == \"Linux\" and platform_machine == \"x86_64\", which is not installed.\u001b[0m\u001b[31m\n", + "\u001b[0m" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "import classiq\n", + "classiq.authenticate()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "UjUn859jLcaS", + "outputId": "1d9eb96e-fefe-42c3-c71d-cd24bfb5d4cb" + }, + "id": "UjUn859jLcaS", + "execution_count": 3, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Your user code: JPTW-QDSJ\n", + "If a browser doesn't automatically open, please visit this URL from any trusted device: https://auth.classiq.io/activate?user_code=JPTW-QDSJ\n" + ] + } + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "19266c11-6acc-4edb-910f-2d0dfe80a6c8", + "metadata": { + "id": "19266c11-6acc-4edb-910f-2d0dfe80a6c8" + }, + "outputs": [], + "source": [ + "from typing import List\n", + "from classiq import *\n", + "\n", + "HAMILTONIAN = QConstant(\"HAMILTONIAN\", List[PauliTerm],\n", + " [PauliTerm([Pauli.I, Pauli.I], -1.0523),\n", + " PauliTerm([Pauli.I,Pauli.Z], 0.3979),\n", + " PauliTerm([Pauli.Z,Pauli.I], -0.3979),\n", + " PauliTerm([Pauli.Z,Pauli.Z], -0.0112),\n", + " PauliTerm([Pauli.X, Pauli.X], 0.1809)])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "0bb68899-2076-45c0-8868-131f38aa3b78", + "metadata": { + "id": "0bb68899-2076-45c0-8868-131f38aa3b78" + }, + "outputs": [], + "source": [ + "@qfunc\n", + "def main(q: Output[QArray[QBit]], angles: CArray[CReal, 3]) -> None:\n", + " # Create an ansatz which allows each qubit to have arbitrary rotation\n", + " allocate(2, q)\n", + " U(angles[0], angles[1], angles[2], 0, q[0])\n", + " U(angles[0], angles[1], angles[2], 0, q[1])\n", + "\n", + "\n", + "@cfunc\n", + "def cmain() -> None:\n", + " res = vqe(\n", + " HAMILTONIAN,\n", + " False,\n", + " [],\n", + " optimizer=Optimizer.COBYLA,\n", + " max_iteration=1000,\n", + " tolerance=0.001,\n", + " step_size=0,\n", + " skip_compute_variance=False,\n", + " alpha_cvar=1.0,\n", + " )\n", + " save({\"result\": res})\n", + "\n", + "qmod = create_model(main, classical_execution_function=cmain)\n", + "qprog = synthesize(qmod)\n", + "# show(qprog)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "0563c1a8-7aec-4da9-9105-6b16c5c24382", + "metadata": { + "id": "0563c1a8-7aec-4da9-9105-6b16c5c24382" + }, + "outputs": [], + "source": [ + "execution = execute(qprog)\n", + "res = execution.result()\n", + "# execution.open_in_ide()\n", + "\n", + "vqe_result = res[0].value" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "de17cfc0-8e64-4493-b4c2-4a97fc9797a0", + "metadata": { + "scrolled": true, + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "de17cfc0-8e64-4493-b4c2-4a97fc9797a0", + "outputId": "695489b1-dcff-431b-8f8a-b90daaa26ff5" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Optimal energy: -1.06546357421875\n", + "Optimal parameters: {'angles_0': 6.139678585190387, 'angles_1': 4.976498216901541, 'angles_2': -4.571133358645985}\n", + "Eigenstate: {'01': (0.06629126073623882+0j), '10': (0.07328774624724109+0j), '00': (0.9951052080056662+0j)}\n" + ] + } + ], + "source": [ + "print(f\"Optimal energy: {vqe_result.energy}\")\n", + "print(f\"Optimal parameters: {vqe_result.optimal_parameters}\")\n", + "print(f\"Eigenstate: {vqe_result.eigenstate}\")" + ] + }, + { + "cell_type": "markdown", + "id": "5df11dfc-3e3a-4191-bd47-d522ca3dcbfa", + "metadata": { + "id": "5df11dfc-3e3a-4191-bd47-d522ca3dcbfa" + }, + "source": [ + "Does it similar to the `optimal energy` we calculated in class? \\\n", + "Does it similar to the `total energy` we calculated in class?" + ] + }, + { + "cell_type": "markdown", + "id": "4f0e0bea-b12f-43ad-94e8-100fedf2b57f", + "metadata": { + "id": "4f0e0bea-b12f-43ad-94e8-100fedf2b57f" + }, + "source": [ + "### Part 2" + ] + }, + { + "cell_type": "markdown", + "id": "66882248-de08-4a6e-b33c-647f015f7d79", + "metadata": { + "id": "66882248-de08-4a6e-b33c-647f015f7d79" + }, + "source": [ + "**Now, we want to have a more interesting ansatz in our `main`.** \n", + "Add **one** line of code to the `main` function you created in Part 1 that creates **entanglement** between the two qubits. \n", + "Which gate should you use?" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "bb39be9e-4994-44e5-84d8-c99bc8b77145", + "metadata": { + "id": "bb39be9e-4994-44e5-84d8-c99bc8b77145" + }, + "outputs": [], + "source": [ + "from typing import List\n", + "from classiq import *\n", + "\n", + "\n", + "@qfunc\n", + "def main(q: Output[QArray[QBit]], angles: CArray[CReal, 3]) -> None:\n", + " # TODO: Create an ansatz which allows each qubit to have arbitrary rotation\n", + " allocate(2, q)\n", + " U(angles[0], angles[1], angles[2], 0, q[0])\n", + " U(angles[0], angles[1], angles[2], 0, q[1])\n", + " CX(q[0], q[1])\n", + "\n", + "\n", + "\n", + "@cfunc\n", + "def cmain() -> None:\n", + " res = vqe(\n", + " HAMILTONIAN, # TODO: complete the missing argument\n", + " False,\n", + " [],\n", + " optimizer=Optimizer.COBYLA,\n", + " max_iteration=1000,\n", + " tolerance=0.001,\n", + " step_size=0,\n", + " skip_compute_variance=False,\n", + " alpha_cvar=1.0,\n", + " )\n", + " save({\"result\": res})\n", + "\n", + "qmod = create_model(main, classical_execution_function=cmain)\n", + "qprog = synthesize(qmod)\n", + "# show(qprog)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "112a1590-283c-4f79-8035-72936561102d", + "metadata": { + "id": "112a1590-283c-4f79-8035-72936561102d" + }, + "outputs": [], + "source": [ + "execution = execute(qprog)\n", + "res = execution.result()\n", + "# execution.open_in_ide()\n", + "vqe_result = res[0].value" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "06500e4c-a04b-4cfa-a84d-41f96a0c68eb", + "metadata": { + "collapsed": true, + "jupyter": { + "outputs_hidden": true + }, + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "06500e4c-a04b-4cfa-a84d-41f96a0c68eb", + "outputId": "32d0ab57-094e-495d-fe1e-6be7c916b9d8" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Optimal energy: -1.8593486328125\n", + "Optimal parameters: {'angles_0': -3.344661707239267, 'angles_1': 2.9341114783374493, 'angles_2': -2.868211044897404}\n", + "Eigenstate: {'11': (0.10126157341262282+0j), '10': (0.11481983169296148+0j), '01': (0.9882117688026185+0j)}\n" + ] + } + ], + "source": [ + "print(f\"Optimal energy: {vqe_result.energy}\")\n", + "print(f\"Optimal parameters: {vqe_result.optimal_parameters}\")\n", + "print(f\"Eigenstate: {vqe_result.eigenstate}\")" + ] + }, + { + "cell_type": "markdown", + "id": "30a635d7-2f15-4c94-a94b-f4270f17aed8", + "metadata": { + "id": "30a635d7-2f15-4c94-a94b-f4270f17aed8" + }, + "source": [ + "Does it similar to the `optimal energy` we calculated in class? \\\n", + "Does it similar to the `total energy` we calculated in class? \\\n", + "What can we learn about the provided form this result Hamiltonian?" + ] + } + ], + "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.9.16" + }, + "colab": { + "provenance": [] + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file