From 2191a3590b245fe99a3843656e82ea437561af86 Mon Sep 17 00:00:00 2001 From: AditiRupade <30768250+AditiRupade@users.noreply.github.com> Date: Wed, 22 Sep 2021 23:18:33 +0530 Subject: [PATCH] add lab3 solutions --- .../.ipynb_checkpoints/lab3-checkpoint.ipynb | 2262 +++++++++++++++++ content/lab3/lab3.ipynb | 98 +- 2 files changed, 2316 insertions(+), 44 deletions(-) create mode 100644 content/lab3/.ipynb_checkpoints/lab3-checkpoint.ipynb diff --git a/content/lab3/.ipynb_checkpoints/lab3-checkpoint.ipynb b/content/lab3/.ipynb_checkpoints/lab3-checkpoint.ipynb new file mode 100644 index 0000000..9d0f1c2 --- /dev/null +++ b/content/lab3/.ipynb_checkpoints/lab3-checkpoint.ipynb @@ -0,0 +1,2262 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "convinced-medium", + "metadata": {}, + "source": [ + "
\n", + "

IBM Quantum Challenge Africa:

\n", + "

Quantum Chemistry for HIV

\n", + "
\n", + "\n", + "\n", + "\n", + "
\n", + "

Table of Contents

\n", + "
\n", + "\n", + "| Walk-through |\n", + "|:-|\n", + "|[Preface](#preface)|\n", + "|[Introduction](#intro)|\n", + "|[Step 1 : Defining the Molecular Geometry](#step_1)|\n", + "|[Step 2 : Calculating the Qubit Hamiltonian](#step_2)|\n", + "|[Step 2a: Constructing the Fermionic Hamiltonion](#step_3)|\n", + "|[Step 2b: Getting Ready to Convert to a Qubit Hamiltonian](#step_2b)|\n", + "|[Step 3 : Setting up the Variational Quantum Eigensolver (VQE)](#step_3)|\n", + "|[Step 3a: The V in VQE (i.e. the Variational form, a Trial state)](#step_3a)|\n", + "|[Step 3b: The Q in VQE: the Quantum environment](#step_3b)|\n", + "|[Step 3c: Initializing VQE](#step_3c)|\n", + "|[Step 4 : Solving for the Ground-state](#step_4)|\n", + "||\n", + "|[The HIV Challenge](#challenge)|\n", + "|[1. Refining Step 1: Varying the Molecule](#refine_step_1)|\n", + "|[2. Refining Step 2: Reducing the quantum workload](#refine_step_2)|\n", + "|[3. Refining Step 4: Energy Surface](#refine_step_4)|\n", + "|[4. Refining Step 3a](#refine_step_3a)|\n", + "|Exercises|\n", + "|[Exercise 3a: Molecular Definition of Macromolecule with Blocking Approach](#exercise_3a)|\n", + "|[Exercise 3b: Classical-Quantum Treatment Conceptual Questions (Multiple-Choice)](#exercise_3b)|\n", + "|[Exercise 3c: Energy Landscape, To bind or not to bind?](#exercise_3c)|\n", + "|[Exercise 3d: The effect of more repetitions](#exercise_3d)|\n", + "|[Exercise 3e: Open-ended: Find the best hardware_inspired_trial to minimize the Energy Error for the Macromolecule](#exercise_3e)|\n", + "|[Quantum Chemistry Resources](#qresource)|\n", + "\n", + "

Preface

\n", + "\n", + "\n", + "**HIV is a virus that has presented an immense challenge for public health, globally**. The ensuing disease dynamics touch on multiple societal dimensions including nutrition, access to health, education and research funding. To compound the difficulties, the virus mutates rapidly with different strains having different geographic footprints. In particular, the HIV-1-C and HIV-2 strains predominate mostly in Africa. Due to disparities in funding, research for treatments of the African strains lags behind other programmes. African researchers are striving to address this imbalance and should consider adding the latest technologies such as quantum computing to their toolkits.\n", + "\n", + "**Quantum computing promises spectacular improvements in drug-design**. In particular, in order to design new anti-retrovirals it is important to perform **chemical simulations** to confirm that the anti-retroviral binds with the virus protein. Such simulations are notoriously hard and sometimes ineffective on classical supercomputers. Quantum computers promise more accurate simulations allowing for a better drug-design workflow.\n", + "\n", + "In detail: anti-retrovirals are drugs that bind with and block a virus protein, called protease, that cleaves virus polyproteins into smaller proteins, ready for packaging. The protease can be thought of as a chemical scissor. The anti-retroviral can be thought of as a sticky obstacle that disrupts the ability of the scissor to cut. With the protease blocked, the virus cannot make more copies of itself.\n", + "\n", + "Mutations in the viral protease changes the binding propensity of a given anti-retroviral. Hence, when a mutation occurs and an anti-retroviral no longer binds well, the goal becomes to adjust the anti-retroviral molecule to again bind strongly.\n", + "\n", + "**The main goal of this challenge is to explore whether a toy anti-retroviral molecule binds with a toy virus protease.**\n", + "\n", + "Along the way, this challenge introduces **state-of-the-art hybrid classical-quantum embedded chemistry modelling** allowing the splitting of the work-load between classical approximations and more accurate quantum calculations.\n", + "\n", + "Finally, you need to tweak the setup of the quantum chemistry algorithm (without having to understand the nuts and bolts of quantum computing) to achieve the best performance for ideal quantum computing conditions." + ] + }, + { + "cell_type": "markdown", + "id": "93390da9", + "metadata": {}, + "source": [ + "*A video explaining how HIV infects and how anti-retroviral treatment works*:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "50e0523a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/jpeg": "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\n", + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import display, YouTubeVideo\n", + "YouTubeVideo('cSNaBui2IM8')" + ] + }, + { + "cell_type": "markdown", + "id": "fuzzy-huntington", + "metadata": {}, + "source": [ + "
\n", + "

Walk-through: Calculating the Ground-state Energy for the Simplest Molecule in the Universe

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "italian-canvas", + "metadata": {}, + "source": [ + "*Import relevant packages*" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "express-might", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import Aer\n", + "\n", + "from qiskit_nature.drivers import PySCFDriver, UnitsType, Molecule\n", + "from qiskit_nature.problems.second_quantization.electronic import ElectronicStructureProblem\n", + "from qiskit_nature.mappers.second_quantization import JordanWignerMapper, BravyiKitaevMapper\n", + "from qiskit_nature.converters.second_quantization import QubitConverter\n", + "\n", + "from qiskit_nature.transformers import ActiveSpaceTransformer\n", + "from qiskit_nature.algorithms import GroundStateEigensolver, BOPESSampler\n", + "from qiskit.algorithms import NumPyMinimumEigensolver\n", + "\n", + "from qiskit.utils import QuantumInstance\n", + "\n", + "from qiskit_nature.circuit.library.ansatzes import UCCSD\n", + "from qiskit_nature.circuit.library.initial_states import HartreeFock\n", + "from qiskit.circuit.library import TwoLocal\n", + "\n", + "from qiskit.algorithms import VQE\n", + "from qiskit.algorithms.optimizers import COBYLA\n", + "\n", + "from functools import partial as apply_variation_to_atom_pair\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "id": "homeless-cheat", + "metadata": {}, + "source": [ + "

Introduction

\n", + "\n", + "In the HIV Challenge, we are tasked with investigating whether the toy anti-retroviral molecule binds with and therefore, disrupts the toy protease molecule. Successful binding is determined by a lower total ground-state energy for the molecules when they are close together (forming a single macromolecule) compared to far apart.\n", + "\n", + "Total ground-state energy refers to the sum of the energies concerning the arrangement of the electrons and the nuclei. The nuclear energy is easy to calculate classically. It is the energy of the electron distribution (i.e. molecular spin-orbital occupation) that is extremely difficult and requires a quantum computer.\n", + "\n", + "We start with a walk-through tutorial, where we calculate the ground-state energy of a simple molecule and leave the more complicated set-up to the challenge section." + ] + }, + { + "cell_type": "markdown", + "id": "modified-jacob", + "metadata": {}, + "source": [ + "The ground-state of a molecule in some configuration consists of the locations of the nuclei, together with some distribution of electrons around the nuclei. The nucleus-nucleus, nuclei-electron and electron-electron forces/energy of attraction and repulsion are captured in a matrix called the **Hamiltonian**. Since the nuclei are relatively massive compared to the electrons, they move at a slower time-scale than the electrons. This allows us to split the calculation into two parts: placing the nuclei and calculating the electron distribution, followed by moving the nuclei and recalculating the electron distribution until a minimum total energy distribution is reached:" + ] + }, + { + "cell_type": "markdown", + "id": "d1b0bb46", + "metadata": {}, + "source": [ + "
\n", + "Algorithm: Find_total_ground_state\n", + "\n", + "Place nuclei\n", + " \n", + "Repeat until grid completed or no change in total_energy:\n", + " \n", + " - calculate electronic ground-state\n", + " \n", + " - total_energy = (nuclei repulsion + electronic energy)\n", + " \n", + " - move nuclei (either in grid or following gradient)\n", + "\n", + "return total_energy\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "metropolitan-works", + "metadata": {}, + "source": [ + "In the walk-through, we simply fix the nuclei positions; however, later, in the challenge section, we allow for a varying one-dimensional intermolecular distance between the anti-retroviral and the protease molecules, which represents the anti-retroviral approaching the protease molecule in an attempt to bind." + ] + }, + { + "cell_type": "markdown", + "id": "26dd8e8e", + "metadata": {}, + "source": [ + "

Step 1: Defining the Molecular Geometry

" + ] + }, + { + "cell_type": "markdown", + "id": "accepted-liberal", + "metadata": {}, + "source": [ + "For this walk-through, we work with the simplest non-trivial molecule possible: H$_2$, the hydrogen gas molecule.\n", + "\n", + "\n", + "\n", + "*The first thing to do is to fix the location of each nucleus. This is specified as a python list of nuclei, where each nucleus (as a list) contains a string corresponding to the atomic species and its 3D co-ordinates (as another list). We also specify the overall charge, which tells Qiskit to automatically calculate the number of needed electrons to produce that charge:*" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "threatened-accreditation", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_molecule = Molecule(geometry=\n", + " [['H', [0., 0., 0.]],\n", + " ['H', [0., 0., 0.735]]],\n", + " charge=0, multiplicity=1)" + ] + }, + { + "cell_type": "markdown", + "id": "52a426ce", + "metadata": {}, + "source": [ + "

Step 2: Calculating the Qubit Hamiltonian

" + ] + }, + { + "cell_type": "markdown", + "id": "lesbian-outline", + "metadata": {}, + "source": [ + "Once nuclei positions are fixed (the nucleus-nucleus forces are temporarily irrelevant), the only part of the Hamiltonian that then needs to be calculated on the quantum computer is the detailed electron-electron interaction. The nuclei-electron and a rough mean field electron-electron interaction can be pre-computed as *allowed molecular orbitals* on a classical computer via the, so called, Hartree-Fock approximation. With these allowed molecular orbitals and their pre-calculated overlaps, Qiskit automatically produces an interacting electron-electron **fermionic molecular-orbital Hamiltonian** (called Second Quantization). The molecular orbital and overlap pre-calculation are provided by classical packages, e.g. PySCF, and connected to Qiskit via a so-called *driver*, in particular, we use the PySCFDriver." + ] + }, + { + "cell_type": "markdown", + "id": "20058145", + "metadata": {}, + "source": [ + "

Step 2a: Constructing the Fermionic Hamiltonion

" + ] + }, + { + "cell_type": "markdown", + "id": "geographic-texas", + "metadata": {}, + "source": [ + "*We specify the driver to the classical software package that is to be used to calculate the resulting orbitals of the provided molecule after taking into account the nuclei-electron and mean-field interactions. The `basis` option selects the basis set in which the molecular orbitals are to be expanded in. `sto3g` is the smallest available basis set:*" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "6c557ec7", + "metadata": {}, + "outputs": [], + "source": [ + "molecular_hydrogen_orbital_maker = PySCFDriver(molecule=hydrogen_molecule, unit=UnitsType.ANGSTROM, basis='sto3g')" + ] + }, + { + "cell_type": "markdown", + "id": "15d9ab80", + "metadata": {}, + "source": [ + "*Qiskit provides a helpful Class named the ElectronicStructureProblem, which calls the driver in the right way to construct the molecular orbitals. We initialise ElectronicStructureProblem with the driver (which already has the molecular information stored in it from the previous step):*" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e1957fe5", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_fermionic_hamiltonian = ElectronicStructureProblem(molecular_hydrogen_orbital_maker)" + ] + }, + { + "cell_type": "markdown", + "id": "9e0ea2c8", + "metadata": {}, + "source": [ + "*Here, we instruct the ElectronicStructureProblem object to go ahead and create the fermionic molecular-orbital Hamiltonian (which gets stored internally):*" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "separated-detail", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Completed running classical package.\n", + "Fermionic molecular-orbital Hamiltonian calculated and stored internally.\n", + "An example of HF info available: Orbital Energies [-0.58062892 0.67633625]\n" + ] + } + ], + "source": [ + "hydrogen_fermionic_hamiltonian.second_q_ops()\n", + "print(\"Completed running classical package.\\nFermionic molecular-orbital Hamiltonian calculated and stored internally.\")\n", + "print(\"An example of HF info available: Orbital Energies\", hydrogen_fermionic_hamiltonian._molecule_data_transformed.orbital_energies)" + ] + }, + { + "cell_type": "markdown", + "id": "67d7064a", + "metadata": {}, + "source": [ + "(If this step is not run explicitly, and its outputs are not used in an intermediary step, the final ground_state solving step would run it automatically.)" + ] + }, + { + "cell_type": "markdown", + "id": "8607bc99", + "metadata": {}, + "source": [ + "

Step 2b: Getting Ready to Convert to a Qubit Hamiltonian

" + ] + }, + { + "cell_type": "markdown", + "id": "opposed-philadelphia", + "metadata": {}, + "source": [ + "Above, *fermionic* is a term to describe the behaviour of electrons (having an anti-symmetric wave-function obeying the Pauli Exclusion principle). In order to use the quantum computer we need to map the electrons (which exhibit fermionic behavior) to the quantum computer's qubits (which have closely related spin behaviour: Pauli Exclusion but not necessarily anti-symmetric). This mapping is a generic process, independent of the driver above." + ] + }, + { + "cell_type": "markdown", + "id": "continued-granny", + "metadata": {}, + "source": [ + "There are multiple mapping methods available, each with pros and cons, and constitutes something to experiment with." + ] + }, + { + "cell_type": "markdown", + "id": "distant-question", + "metadata": {}, + "source": [ + "*For now, we select the simplest qubit mapper/converter called the Jordan-Wigner Mapper:*" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "arctic-exhaust", + "metadata": {}, + "outputs": [], + "source": [ + "map_fermions_to_qubits = QubitConverter(JordanWignerMapper())\n", + "# e.g. alternative:\n", + "# map_fermions_to_qubits = QubitConverter(BravyiKitaevMapper())" + ] + }, + { + "cell_type": "markdown", + "id": "190cd577", + "metadata": {}, + "source": [ + "(Note, we have just chosen the mapper above, it has not yet been applied to the fermionic Hamiltonian.)" + ] + }, + { + "cell_type": "markdown", + "id": "ddcf6c41", + "metadata": {}, + "source": [ + "

Step 3: Setting up the Variational Quantum Eigensolver (VQE)

\n", + "\n", + "Now that we have defined the molecule and its mapping onto a quantum computer, we need to select an algorithm to solve for the ground state. There are two well-known approaches: Quantum Phase Estimation (QPE) and VQE. The first requires fault-tolerant quantum computers that have not yet been built. The second is suitable for current day, noisy **depth**-restricted quantum computers, because it is a hybrid quantum-classical method with short-depth quantum circuits. By *depth* of the circuit, it suffices to know that quantum computers can only be run for a short while, before noise completely scrambles the results.\n", + "\n", + "Therefore, for now, we only explore the VQE method. Furthermore, VQE offers many opportunities to tweak its configuration; thus, as an end-user you gain experience in quantum black-box tweaking.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "ba1aa361", + "metadata": {}, + "source": [ + "VQE is an algorithm for finding the ground-state of a molecule (or any Hamiltonian in general). It is a hybrid quantum-classical algorithm, which means that the algorithm consists of two interacting stages, a quantum stage and a classical stage. \n", + "\n", + "During the quantum stage, a trial molecular state is created on the quantum computer. The trial state is specified by a collection of **parameters** which are provided and adjusted by the classical stage. After the trial state is created, its energy is calculated on the quantum computer (by a few rounds of quantum-classical measurements). The result is finally available classically. \n", + "\n", + "At this stage, a classical optimization algorithm looks at the previous energy levels and the new energy level and decides how to adjust the trial state parameters. This process repeats until the energy essentially stops decreasing. The output of the whole algorithm is the final set of parameters that produced the winning approximation to the ground-state and its energy level." + ] + }, + { + "cell_type": "markdown", + "id": "becoming-special", + "metadata": {}, + "source": [ + "

Step 3a: The V in VQE (i.e. the Variational form, a Trial state)

\n", + "\n", + "VQE works by 'searching' for the electron orbital occupation distribution with the lowest energy, called the ground-state. The quantum computer is repeatedly used to calculate the energy of the search trial state.\n", + "\n", + "The trial state is specified by a collection of (randomly initialized) parameters that move the state around, in our search for the ground-state (we're minimizing the energy cost-function). The form of the 'movement' is something that can be tweaked (i.e., the definition of the structure of the *ansatz*/trial). There are two broad approaches we could follow. The first, let's call it *Chemistry-Inspired Trial-states*, is to use domain knowledge of what we expect the ground-state to look like from a chemistry point of view and build that into our trial state. The second, let's call it *Hardware-Inspired Trial-states*, is to simply try and create trial states that have as wide a reach as possible while taking into account the architecure of the available quantum computers.\n", + "\n", + "#### *Chemistry-Inspired Trial-states*\n", + "\n", + "Since chemistry gives us domain-specific prior information (e.g., the number of orbitals and electrons and the actual Hartree-Fock approximation), it makes sense to guide the trial state by baking this knowledge into the form of the trial." + ] + }, + { + "cell_type": "markdown", + "id": "dominant-tattoo", + "metadata": {}, + "source": [ + "*From the HF approximation we get the number of orbitals and from that we can calculate the number of spin orbitals:*" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "chronic-juvenile", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_molecule_info = hydrogen_fermionic_hamiltonian.molecule_data_transformed\n", + "num_hydrogen_molecular_orbitals = hydrogen_molecule_info.num_molecular_orbitals\n", + "num_hydrogen_spin_orbitals = 2 * num_hydrogen_molecular_orbitals" + ] + }, + { + "cell_type": "markdown", + "id": "approved-fantasy", + "metadata": {}, + "source": [ + "*Furthermore, we can also extract the number of electrons (spin up and spin down):*" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "rolled-harvey", + "metadata": {}, + "outputs": [], + "source": [ + "num_hydrogen_electrons_spin_up_spin_down = (hydrogen_molecule_info.num_alpha, hydrogen_molecule_info.num_beta)" + ] + }, + { + "cell_type": "markdown", + "id": "internal-binary", + "metadata": {}, + "source": [ + "*With the number of spin orbitals, the number of electrons able to fill them and the mapping from fermions to qubits, we can construct an initial quantum computing state for our trial state:*" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "piano-drilling", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_initial_state = HartreeFock(num_hydrogen_spin_orbitals,\n", + " num_hydrogen_electrons_spin_up_spin_down,\n", + " map_fermions_to_qubits)" + ] + }, + { + "cell_type": "markdown", + "id": "portable-pacific", + "metadata": {}, + "source": [ + "*Finally, Qiskit provides a Class (Unitary Coupled Cluster Single and Double excitations, `UCCSD`) that takes the above information and creates a parameterised state inspired by the HF approximation, that can be iteratively adjusted in our attempt to find the ground-state:*" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "acquired-equity", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_chemistry_inspired_trial = UCCSD(map_fermions_to_qubits,\n", + " num_hydrogen_electrons_spin_up_spin_down,\n", + " num_hydrogen_spin_orbitals,\n", + " initial_state=hydrogen_initial_state)" + ] + }, + { + "cell_type": "markdown", + "id": "governmental-paper", + "metadata": {}, + "source": [ + "#### *Hardware-Inspired Trial-states*\n", + "\n", + "The problem with the above \"chemistry-inspired\" trial-states, is that they are quite deep, quickly using up the available depth of current-day quantum computers. A potential solution is to forgo this chemistry knowledge and try to represent arbitrary states with trial states that are easy to prepare and parametrically \"move\" around on current hardware. There are two quantum operations that can be used to try and reach arbitrary states: mixing (our term for *conditional sub-space rotation*) and rotating (*unconditional rotation*). Detailed knowledge of how these operations and their sub-options work are not really needed, especially because it is not immediately obvious which settings produce the best results.\n", + "\n", + "##### Mixing (also called Entanglement maps)\n", + "\n", + "There are a set of available mixing strategies, that you may experiment with. This is specified with two arguments, *`entanglement`* (choosing what to mix) and *`entanglement_blocks`* (choosing how to mix):\n", + "\n", + "Possible *`entanglement`* values: `'linear'`, `'full'`, `'circular'`, `'sca'`\n", + "\n", + "Possible *`entanglement_blocks`* values: `'cz'`, `'cx'`\n", + "\n", + "For our purposes, it is acceptable to simply choose the first option for each setting.\n", + " \n", + "##### Rotation\n", + "\n", + "There are a set of available *parameterized* rotation strategies. The rotation strategies are specified as a single argument, *`rotation_blocks`*, in the form of a list of any combination of the following possibilities:\n", + "\n", + "Possible *`rotation_blocks`*: `'ry'`, `'rx'`,`'rz'`,`'h'`, ...\n", + "\n", + "Typically, this is the only place that parameters are introduced in the trial state. One parameter is introduced for every rotation, corresponding to the angle of rotation around the associated axis. (Note, `'h'` does not have any parameters and so can not be selected alone.)\n", + "\n", + "Again, for our purposes, an acceptable choice is the first option alone in the list." + ] + }, + { + "cell_type": "markdown", + "id": "9f0151fa", + "metadata": {}, + "source": [ + "*Qiskit provides a Class called `TwoLocal` for creating random trial states by local operations only. The number of **rounds** of the local operations is specified by the argument `reps`:*" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "polished-lounge", + "metadata": {}, + "outputs": [], + "source": [ + "hardware_inspired_trial = TwoLocal(rotation_blocks = ['ry'], entanglement_blocks = 'cz',\n", + " entanglement='linear', reps=2)" + ] + }, + { + "cell_type": "markdown", + "id": "21483bb4", + "metadata": {}, + "source": [ + "(Note, this trial state does not depend on the molecule.)" + ] + }, + { + "cell_type": "markdown", + "id": "37f09449", + "metadata": {}, + "source": [ + "*Just for convenience, let's choose between the two approaches by assiging the choice to a variable:*" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "cdd1d06f", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_trial_state = hydrogen_chemistry_inspired_trial\n", + "# OR\n", + "# hydrogen_trial_state = hardware_inspired_trial" + ] + }, + { + "cell_type": "markdown", + "id": "bf40f024", + "metadata": {}, + "source": [ + "

Step 3b: The Q in VQE: the Quantum environment

" + ] + }, + { + "cell_type": "markdown", + "id": "5f4b7dac", + "metadata": {}, + "source": [ + "Since VQE runs on a quantum computer, it needs information about this stage. For testing purposes, this can even be a simulation, both in the form of noise-free or noisy simulations. Ultimately, we would want to run VQE an actual (albeit noisy) quantum hardware and hopefully, in the not-too-distant future, achieve results unattainable classically. For this challenge, let us pursue noise-free simulation only." + ] + }, + { + "cell_type": "markdown", + "id": "ddaf4304", + "metadata": {}, + "source": [ + "#### Noise-Free Simulation\n", + "\n", + "*To set up a noise-free simulation:*" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "a63eb72f", + "metadata": {}, + "outputs": [], + "source": [ + "noise_free_quantum_environment = QuantumInstance(Aer.get_backend('statevector_simulator'))" + ] + }, + { + "cell_type": "markdown", + "id": "aa62f250", + "metadata": {}, + "source": [ + "

Step 3c: Initializing VQE

" + ] + }, + { + "cell_type": "markdown", + "id": "19ef3684", + "metadata": {}, + "source": [ + "Qiskit Nature provides a class called VQE, that implements the VQE algorithm. *It is initialized in a generic way (without reference to the molecule or the Hamiltonian) and requires the two pieces of information from above: the trial state and the quantum environment:*" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "88fe1466", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_vqe_solver = VQE(ansatz=hydrogen_trial_state, quantum_instance=noise_free_quantum_environment)" + ] + }, + { + "cell_type": "markdown", + "id": "3b5c2042", + "metadata": {}, + "source": [ + "(Note, the vqe solver is only tailored to hydrogen if the trial state is the hydrogen_chemistry_inspired_trial.)" + ] + }, + { + "cell_type": "markdown", + "id": "18ec5dbd", + "metadata": {}, + "source": [ + "

Step 4: Solving for the Ground-state

" + ] + }, + { + "cell_type": "markdown", + "id": "49b73822", + "metadata": {}, + "source": [ + "**Qiskit Nature provides a class called GroundStateEigensolver to calculate the ground-state of a molecule.**\n", + "\n", + "This class first gets initialised with information that is independent of any molecule. It can then be applied to specific molecules using the same generic setup.\n", + "\n", + "To initialise a GroundStateEigensolver object, we need to provide the two generic algorithmic sub-components from above, the mapping method (Step 2b) and the solving method (Step 3). For testing purposes, an alternative to the VQE solver is a classical solver (see numpy_solver below)." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "74baf354", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_ground_state = GroundStateEigensolver(map_fermions_to_qubits, hydrogen_vqe_solver)" + ] + }, + { + "cell_type": "markdown", + "id": "fe21cd26", + "metadata": {}, + "source": [ + "We are finally ready to solve for the ground-state energy of our molecule.\n", + "\n", + "We apply the GroundStateEigensolver to the fermionic Hamiltonian (Step 2a) which has encoded in it the molecule (Step 1). The already specified mapper and VQE solver is then automatically applied for us to produce the ground-state (approximation)." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "238b43eb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== GROUND STATE ENERGY ===\n", + " \n", + "* Electronic ground state energy (Hartree): -1.857275030145\n", + " - computed part: -1.857275030145\n", + "~ Nuclear repulsion energy (Hartree): 0.719968994449\n", + "> Total ground state energy (Hartree): -1.137306035696\n", + " \n", + "=== MEASURED OBSERVABLES ===\n", + " \n", + " 0: # Particles: 2.000 S: 0.000 S^2: 0.000 M: -0.000\n", + " \n", + "=== DIPOLE MOMENTS ===\n", + " \n", + "~ Nuclear dipole moment (a.u.): [0.0 0.0 1.3889487]\n", + " \n", + " 0: \n", + " * Electronic dipole moment (a.u.): [0.0 0.0 1.38894854]\n", + " - computed part: [0.0 0.0 1.38894854]\n", + " > Dipole moment (a.u.): [0.0 0.0 0.00000016] Total: 0.00000016\n", + " (debye): [0.0 0.0 0.00000039] Total: 0.00000039\n", + " \n" + ] + } + ], + "source": [ + "hydrogen_ground_state_info = hydrogen_ground_state.solve(hydrogen_fermionic_hamiltonian)\n", + "\n", + "print(hydrogen_ground_state_info)" + ] + }, + { + "cell_type": "markdown", + "id": "1b031d40", + "metadata": {}, + "source": [ + "As you can see, we have calculated the Ground-state energy of the electron distribution: -1.85 Hartree\n", + "\n", + "From the placement of the nuclei, we are also conveniently given the repulsion energy (a simple classical calculation).\n", + "\n", + "Finally, when it comes to the ground-state of the overall molecule it is the total ground state energy that we are trying to minimise.\n", + "\n", + "So the next step would be to move the nuclei and recalculate the **total ground state energy** in search of the stable nuclei positions." + ] + }, + { + "cell_type": "markdown", + "id": "9cd772db", + "metadata": {}, + "source": [ + "To end our discussion, let us compare the quantum-calculated energy to an accuracy-equivalent (but slower) classical calculation." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "837f75f8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ground-state electronic energy (via classical calculations): -1.8572750301451932 Hartree\n" + ] + } + ], + "source": [ + "#Alternative Step 3b\n", + "numpy_solver = NumPyMinimumEigensolver()\n", + "\n", + "#Alternative Step 4\n", + "ground_state_classical = GroundStateEigensolver(map_fermions_to_qubits, numpy_solver)\n", + "hydrogen_ground_state_info_classical = ground_state_classical.solve(hydrogen_fermionic_hamiltonian)\n", + "\n", + "hydrogen_energy_classical = hydrogen_ground_state_info.computed_energies[0]\n", + "print(\"Ground-state electronic energy (via classical calculations): \", hydrogen_energy_classical, \"Hartree\")" + ] + }, + { + "cell_type": "markdown", + "id": "d8e3b94c", + "metadata": {}, + "source": [ + "The agreement to so many decimal places tells us that, for this particular Hamiltonian, the VQE process is accurately finding the lowest eigenvalue (and interestingly, the ansatz/trial does not fail to capture the ground-state, probably because it spans the entire Hilbert space). However, when comparing to nature or very accurate classical simulations of $H_2$, we find that the energy is only accurate to two decimal places, e.g. total energy VQE: -1.137 Hartree vs highly accurate classical simulation: -1.166 Hartree, which only agrees two decimal places. The reason for this is that in our above treatment there are sources of modelling error including: the placement of nuclei and a number of approximations that come with the Hartree-Fock expansion. For $H_2$ these can be addressed, but ultimately, in general, the more tricky of these sources can never be fully handled because finding the perfect ground-state is QMA-complete, i.e. the quantum version of NP-complete (i.e. 'unsolvable' for certain Hamiltonians). Then again, nature itself is not expected to be finding this perfect ground-state, so future experimention is needed to see how close a given quantum computing solution approximates nature's solution." + ] + }, + { + "cell_type": "markdown", + "id": "d305e345", + "metadata": {}, + "source": [ + "
\n", + "

Walk-through Finished

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "67f68b5f", + "metadata": {}, + "source": [ + "\n", + "***\n" + ] + }, + { + "cell_type": "markdown", + "id": "51a3a8fa", + "metadata": {}, + "source": [ + "
\n", + "

The HIV Challenge

\n", + "
\n", + "\n", + "Now that we have completed the walk-through, we frame the challenge as the task to refine steps 1-4 while answering related questions." + ] + }, + { + "cell_type": "markdown", + "id": "bd9ab721", + "metadata": {}, + "source": [ + "

1. Refining Step 1: Varying the Molecule

\n", + "\n", + "In Step 1, we defined our molecule. For the challenge, we need to firstly define a new molecule, corresponding to our toy protease molecule (the *scissor*) with an approaching toy anti-retroviral (the *blocker*), forming a *macromolecule*. Secondly, we need to instruct Qiskit to vary the approach distance. Let's learn how to do the second step with the familiar hydrogen molecule." + ] + }, + { + "cell_type": "markdown", + "id": "79c7a2dd", + "metadata": {}, + "source": [ + "*Here is how to specify the type of molecular variation we are interested in (namely, changing the approach distance in absolute steps)*:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "2ec7406c", + "metadata": {}, + "outputs": [], + "source": [ + "molecular_variation = Molecule.absolute_stretching\n", + "\n", + "#Other types of molecular variation:\n", + "#molecular_variation = Molecule.relative_stretching\n", + "#molecular_variation = Molecule.absolute_bending\n", + "#molecular_variation = Molecule.relative_bending" + ] + }, + { + "cell_type": "markdown", + "id": "4ab7b2d1", + "metadata": {}, + "source": [ + "*Here is how we specify which atoms the variation applies to. The numbers refer to the index of the atom in the geometric definition list. The first atom of the specified atom_pair, is moved closer to the left-alone second atom:*" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "57c5fe06", + "metadata": {}, + "outputs": [], + "source": [ + "specific_molecular_variation = apply_variation_to_atom_pair(molecular_variation, atom_pair=(1, 0))" + ] + }, + { + "cell_type": "markdown", + "id": "1ddcac81", + "metadata": {}, + "source": [ + "*Finally, here is how we alter the original molecular definition that you have already seen in the walk-through:*" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "dd7823ab", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_molecule_stretchable = Molecule(geometry=\n", + " [['H', [0., 0., 0.]],\n", + " ['H', [0., 0., 0.735]]],\n", + " charge=0, multiplicity=1,\n", + " degrees_of_freedom=[specific_molecular_variation])" + ] + }, + { + "cell_type": "markdown", + "id": "3640e80d", + "metadata": {}, + "source": [ + "If we wanted to test that the variation is working, we could manually specify a given amount of variation (Qiskit calls it a *perturbation*) and then see what the new geometry is:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "d9ce5a29", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_molecule_stretchable.perturbations = [0.1]" + ] + }, + { + "cell_type": "markdown", + "id": "f5e05326", + "metadata": {}, + "source": [ + "(If the above were not specified, a perturbation of zero would be assumed, defaulting to the original geometry.)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "76f95c95", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[['H', [0.0, 0.0, 0.0]], ('H', [0.0, 0.0, 0.835])]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hydrogen_molecule_stretchable.geometry" + ] + }, + { + "cell_type": "markdown", + "id": "fc42a8c7", + "metadata": {}, + "source": [ + "Notice how only the second atom of our geometry list (index 1, specified first in the atom_pair) has moved closer to the other atom by the amount we specified. When it comes time to scanning across different approach distances this is very helpfully automated by Qiskit." + ] + }, + { + "cell_type": "markdown", + "id": "2bfd15df", + "metadata": {}, + "source": [ + "## Specifying the Protease+Anti-retroviral Macromolecule" + ] + }, + { + "cell_type": "markdown", + "id": "f57ed84c", + "metadata": {}, + "source": [ + "### Protease\n", + "A real protease molecule is made up of two polypeptide chains of around one hundred amino-acids in each chain (the two chains are folded together), with neighbouring pairs connected by the so-called *peptide-bond*.\n", + "\n", + "\n", + "\n", + "For our toy protease molecule, we have decided to take inspiration from this peptide bond since it is the basic building structure holding successive amino acids in proteins together. It is one of the most important factors in determining the chemistry of proteins, including protein folding in general and the HIV protease's cleaving ability, in particular.\n", + "\n", + "To simplify the calculations, let us choose to focus on the O=C-N part of molecule. We keep and also add enough hydrogen atoms to try and make the molecule as realistic as possible (indeed, HCONH$_2$, Formamide, is a stable molecule, which, incidentally, is an ionic solvent, so it does \"cut\" ionic bonds).\n", + "\n", + "Making O=C-N our toy protease molecule is an extreme simplification, but nevertheless biologically motivated.\n", + "\n", + "\n", + "Here is our toy protease:\n", + "\n", + "\n", + "\n", + "```\n", + "\"O\": (1.1280, 0.2091, 0.0000)\n", + "\"N\": (-1.1878, 0.1791, 0.0000)\n", + "\"C\": (0.0598, -0.3882, 0.0000)\n", + "\"H\": (-1.3085, 1.1864, 0.0001)\n", + "\"H\": (-2.0305, -0.3861, -0.0001)\n", + "\"H\": (-0.0014, -1.4883, -0.0001)\n", + "```\n", + "\n", + "Just for fun, you may imagine that this molecule is a pair of scissors, ready to cut the HIV master protein (Gag-Pol polyprotein), in the process of making copies of the HI virus:\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "4fa2f195", + "metadata": {}, + "source": [ + "### Anti-retroviral\n", + "The anti-retroviral is a molecule that binds with the protease to **inhibit/block the cleaving mechanism**. For this challenge, we select a single carbon atom to be our stand-in for the anti-retroviral molecule.\n", + "\n", + "\n", + "\n", + "### Macromolecule\n", + "Even though the two molecules are separate in our minds, when they approach, they form a single macro-molecule, with the outer-electrons forming molecular orbitals around all the atoms.\n", + "\n", + "As explained in the walk-through, the quantum electronic distribution is calculated for fixed atom positions, thus we have to separately place the atoms. For the first and second task, let us fix the protease's co-ordinates and only vary the anti-retroviral's position along a straight line.\n", + "\n", + "We arbitrarily select a line of approach passing through a given point and approaching the nitrogen atom. This \"blocking\" approach tries to obstruct the scissor from cutting. If it \"sticks\", it's working and successfully disrupts the duplication efforts of the HIV.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "99c5e4d4", + "metadata": {}, + "source": [ + "

Exercise 3a: Molecular Definition of Macromolecule with Blocking Approach

\n", + "\n", + "Construct the molecular definition and molecular variation to represent the anti-retroviral approaching the nitrogen atom, between the \"blades\":\n", + "\n", + " ```\n", + " \"C\": (-0.1805, 1.3955, 0.0000)\n", + " ```" + ] + }, + { + "cell_type": "markdown", + "id": "0a596fe3", + "metadata": {}, + "source": [ + "## Write your answer code here:" + ] + }, + { + "cell_type": "markdown", + "id": "8fb75014", + "metadata": {}, + "source": [ + "Create a your molecule in the cell below. Make sure to name the molecule `macromolecule`." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "58c8ca15", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[['H', [-0.0014, -1.4883, -0.0001]], ['C', [0.0598, -0.3882, 0.0]], ['O', [1.128, 0.2091, 0.0]], ['N', [-1.1878, 0.1791, 0.0]], ['H', [-1.3085, 1.1864, 0.0001]], ['H', [-2.0305, -0.3861, -0.0001]], ['C', [-0.1805, 1.3955, 0.0]]]\n" + ] + } + ], + "source": [ + "molecular_variation = Molecule.absolute_stretching\n", + "specific_molecular_variation = apply_variation_to_atom_pair(molecular_variation, atom_pair=(6, 3))\n", + "macromolecule = Molecule(geometry=\n", + " [['H', [-0.0014, -1.4883, -0.0001]],\n", + " ['C', [0.0598, -0.3882, 0.0000]],\n", + " ['O', [1.1280, 0.2091, 0.0000]], \n", + " ['N', [-1.1878, 0.1791, 0.0000]],\n", + " ['H', [-1.3085, 1.1864, 0.0001]],\n", + " ['H', [-2.0305, -0.3861, -0.0001]],\n", + " ['C', [-0.1805, 1.3955, 0.0000]]],\n", + " charge=0, multiplicity=1,\n", + " degrees_of_freedom=[specific_molecular_variation])\n", + "\n", + "print(macromolecule.geometry)" + ] + }, + { + "cell_type": "markdown", + "id": "8bcfd2f6", + "metadata": {}, + "source": [ + "To submit your molecule to the grader, run the cell below." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "c7ea62b7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "😢 Your answer is incorrect.\n", + "You didn't appear to pass a `Molecule` object instance.\n" + ] + } + ], + "source": [ + "from qc_grader import grade_ex3a\n", + "\n", + "grade_ex3a(molecule=macromolecule)" + ] + }, + { + "cell_type": "markdown", + "id": "1695bfa0", + "metadata": {}, + "source": [ + "

2. Refining Step 2: Reducing the quantum workload

" + ] + }, + { + "cell_type": "markdown", + "id": "fbb29d03", + "metadata": {}, + "source": [ + "In Step 2, we constructed the qubit Hamiltonian. If we tried to apply Step 2 and beyond to our macromolecule above, the ground state calculation simulation would fail. The reason is because since we specified a zero charge, Qiskit knows that it must work with 30 (= 2\\*6+7+8+3\\*1) electrons. After second quantization, this translates into, say, 60 spin-orbitals which requires 60 qubits. 60 qubits is beyond our ability to simulate classically and while there are IBM Quantum systems with more than 60 qubits available, the noise levels are currently too high to produce accurate results when using that many qubits. Thus, for the purpose of this Challenge we need to reduce the number of qubits. Fortunately, this is well-motivated from a chemistry point of view as well: the classical Hartree-Fock approximation for core-electrons is sometimes sufficient to obtain accurate chemical results. Doubly fortunately, Qiskit has just recently been extended to seamlessly allow for users to specify that certain electrons should receive quantum-computing treatment while the remaining electrons should be classically approximated. Even as more qubits come on online, this facility may prove very useful in allowing near-term quantum computers to tackle very large molecules that would otherwise be out of reach." + ] + }, + { + "cell_type": "markdown", + "id": "a9c818c1", + "metadata": {}, + "source": [ + "*Therefore, we next demonstrate how to instruct Qiskit to give a certain number of electrons quantum-computing treatment:*" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "77c28972", + "metadata": {}, + "outputs": [], + "source": [ + "macro_molecular_orbital_maker = PySCFDriver(molecule=macromolecule, unit=UnitsType.ANGSTROM, basis='sto3g')\n", + "split_into_classical_and_quantum = ActiveSpaceTransformer(num_electrons=2, num_molecular_orbitals=2)\n", + "macro_fermionic_hamiltonian = ElectronicStructureProblem(macro_molecular_orbital_maker, [split_into_classical_and_quantum])" + ] + }, + { + "cell_type": "markdown", + "id": "5706e5e8", + "metadata": {}, + "source": [ + "Above, Qiskit provides a class called **ActiveSpaceTransformer** that takes in two arguments. The first is the number of electrons that should receive quantum-computing treatment (selected from the outermost electrons, counting inwards). The second is the number of orbitals to allow those electrons to roam over (around the so-called Fermi level). It is the second number that determines how many qubits are needed." + ] + }, + { + "cell_type": "markdown", + "id": "970d2992", + "metadata": {}, + "source": [ + "

Exercise 3b: Classical-Quantum Treatment Conceptual Questions (Multiple-Choice)

\n", + "\n", + "Q1: Why does giving quantum treatment to outer electrons of the macromolecule first, make more heuristic sense?\n", + "\n", + "```\n", + "A: Outer electrons have higher binding energies and therefore swing the ground state energy more, therefore requiring quantum treatment.\n", + "B: Outer electrons exhibit more quantum interference because their orbitals are more spread out.\n", + "C: Inner core-electrons typically occupy orbitals more straightforwardly, because they mostly orbit a single nucleus and therefore do not lower the energy much by interacting/entangling with outer electrons.\n", + "```\n", + "\n", + "Q2: For a fixed number of quantum-treatment electrons, as you increase the number of orbitals that those electrons roam over (have access to), does the calculated ground-state energy approach the asymptotic energy from above or below?\n", + "\n", + "```\n", + "A: The asymptotic energy is approached from above, because as you increase the possible orbitals that the electrons have access to, the lower the ground state could be.\n", + "B: The asymptotic energy is approached from below, because as you increase the possible orbitals the more accurate is your simulation, adding energy that was left out before.\n", + "C: The asymptotic energy is approached from below, because as you increase the possible orbitals that the electrons have access to, the lower the ground state could be.\n", + "D: The asymptotic energy is approached from above, because as you increase the possible orbitals the more accurate is your simulation, adding energy that was left out before.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "11f430fb", + "metadata": {}, + "source": [ + "**Uncomment your answers to these multiple choice questions in the code-cell below. Run the cell to submit your answers.**" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "e745078d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "😢 Your answer is incorrect.\n", + "Message from grader: Your Q1 answer is incorrect\n" + ] + } + ], + "source": [ + "from qc_grader import grade_ex3b\n", + "\n", + "## Q1\n", + "answer_for_ex3b_q1 = 'C'\n", + "##\n", + "\n", + "## Q2\n", + "answer_for_ex3b_q2 = 'A'\n", + "##\n", + "\n", + "grade_ex3b(answer_for_ex3b_q1, answer_for_ex3b_q2)" + ] + }, + { + "cell_type": "markdown", + "id": "0bb32012", + "metadata": {}, + "source": [ + "

3. Refining Step 4: Energy Surface

" + ] + }, + { + "cell_type": "markdown", + "id": "1d07692a", + "metadata": {}, + "source": [ + "In Step 4, we ran the ground_state solver on a given molecule once only and we haven't yet explained how to instruct Qiskit to vary the molecular geometry using the specification introduced above. As explained in the introduction, changing the nuclei positions and comparing the total energy levels, is a method for finding the nuclei arrangement with the lowest energy. If the lowest energy is **not** at \"infinity\", this corresponds to a \"stable\" bound state of the molecule at the energy minimum. The energy as a function of atomic separation is thus a crucial object of study. This function is called the **Born-Oppenheimer Potential Energy Surface (BOPES)**. Qiskit provides a helpful python Class that manages this process of varying the geometry and repeatedly calling the ground_state solver: **BOPESSampler**.\n", + "\n", + "Let's demonstrate BOPESSampler for the hydrogen molecule.\n", + "\n", + "*The only steps of the hydrogen molecule walk-through that need to be re-run are Steps 1 and 2a:*" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "9fec6daa", + "metadata": {}, + "outputs": [], + "source": [ + "hydrogen_stretchable_molecular_orbital_maker = PySCFDriver(molecule=hydrogen_molecule_stretchable, unit=UnitsType.ANGSTROM, basis='sto3g')\n", + "hydrogen_stretchable_fermionic_hamiltonian = ElectronicStructureProblem(hydrogen_stretchable_molecular_orbital_maker)" + ] + }, + { + "cell_type": "markdown", + "id": "bc4fbfd7", + "metadata": {}, + "source": [ + "*Secondly, here is how to call the sampler:*" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "0d9bcd10", + "metadata": {}, + "outputs": [], + "source": [ + "energy_surface = BOPESSampler(gss=hydrogen_ground_state, bootstrap=False) # same solver suffices, since the trial is the same\n", + "perturbation_steps = np.linspace(-0.5, 2, 25) # 25 equally spaced points from -0.5 to 2, inclusive.\n", + "\n", + "energy_surface_result = energy_surface.sample(hydrogen_stretchable_fermionic_hamiltonian, perturbation_steps)" + ] + }, + { + "cell_type": "markdown", + "id": "8a1fc171", + "metadata": {}, + "source": [ + "*Thirdly, here is how to produce the famous energy landscape plot:*" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "f2586481", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "def plot_energy_landscape(energy_surface_result):\n", + " if len(energy_surface_result.points) > 1:\n", + " plt.plot(energy_surface_result.points, energy_surface_result.energies, label=\"VQE Energy\")\n", + " plt.xlabel('Atomic distance Deviation(Angstrom)')\n", + " plt.ylabel('Energy (hartree)')\n", + " plt.legend()\n", + " plt.show()\n", + " else:\n", + " print(\"Total Energy is: \", energy_surface_result.energies[0], \"hartree\")\n", + " print(\"(No need to plot, only one configuration calculated.)\")\n", + " \n", + "plot_energy_landscape(energy_surface_result)" + ] + }, + { + "cell_type": "markdown", + "id": "820f64b4", + "metadata": {}, + "source": [ + "For extra intuition, you may think of the energy landscape as a mountain, next to a valley, next to a plateau that a ball rolls on (the x co-ordinate of the ball corresponds the separation between the two hydrogen atoms). If the ball is not rolling too fast down the plateau (right to left) it may settle in the valley. The ball slowly rolls down the plateau because the slope is positive (representing a force of attraction between the two hydrogen atoms). If the ball overshoots the minimum point of the valley, it meets the steep negative slope of the mountain and quickly rolls back (the hydrogen atoms repell each other).\n", + "\n", + "Notice the minimum is at zero. This is because we defined the hydrogen molecule's nuclei positions at the known ground state positions.\n", + "\n", + "By the way, if we had used the hardware_inspired_trial we would have produced a similiar plot, however it would have had bumps because the anzatz does not capture the electronic ground state equally well at different bond lengths." + ] + }, + { + "cell_type": "markdown", + "id": "66aae076", + "metadata": {}, + "source": [ + "

Exercise 3c: Energy Landscape, To bind or not to bind?

\n", + "\n", + "The million-dollar question: Does our toy anti-retrovial bind and thus block the protease?\n", + "\n", + " - Search for the minimum from -0.5 to 5 for 30 points.\n", + " - Give quantum-computing treatment to 2 electrons roaming over 2 orbitals\n", + "\n", + "Q1. Submit the energy landscape for the anti-retroviral approaching the protease.\n", + "\n", + "Q2. Is there a clear minimum at a finite separation? Does binding occur?\n", + "\n", + "```\n", + "A. Yes, there is a clear minimum at 0, so binding does occur.\n", + "B. Yes, there is a clear minimum at infinity, so binding only happens at infinity.\n", + "C. No, there is no clear minimum for any separation, so binding occurs because there is no seperation.\n", + "D. No, there is no clear minimum for any separation, so there is no binding.\n", + "```\n", + "\n", + "(Don't preempt the answer. Furthermore, the answer might change for other approaches and other settings, so please stick to the requested settings.)" + ] + }, + { + "cell_type": "markdown", + "id": "8c8ad577", + "metadata": {}, + "source": [ + "*Feel free to use the following function, which collects the entire walk-through and refinements to Step 2 and 4. It takes in a Molecule (of refinement Step 1 type), the inputs for the other refinements and boolean choice of whether to use VQE or the numpy solver:*" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "f482e3ab", + "metadata": {}, + "outputs": [], + "source": [ + "def construct_hamiltonian_solve_ground_state(\n", + " molecule,\n", + " num_electrons=2,\n", + " num_molecular_orbitals=2,\n", + " chemistry_inspired=True,\n", + " hardware_inspired_trial=None,\n", + " vqe=True,\n", + " perturbation_steps=np.linspace(-1, 1, 3),\n", + "):\n", + " \"\"\"Creates fermionic Hamiltonion and solves for the energy surface.\n", + "\n", + " Args:\n", + " molecule (Union[qiskit_nature.drivers.molecule.Molecule, NoneType]): The molecule to simulate.\n", + " num_electrons (int, optional): Number of electrons for the `ActiveSpaceTransformer`. Defaults to 2.\n", + " num_molecular_orbitals (int, optional): Number of electron orbitals for the `ActiveSpaceTransformer`. Defaults to 2.\n", + " chemistry_inspired (bool, optional): Whether to create a chemistry inspired trial state. `hardware_inspired_trial` must be `None` when used. Defaults to True.\n", + " hardware_inspired_trial (QuantumCircuit, optional): The hardware inspired trial state to use. `chemistry_inspired` must be False when used. Defaults to None.\n", + " vqe (bool, optional): Whether to use VQE to calculate the energy surface. Uses `NumPyMinimumEigensolver if False. Defaults to True.\n", + " perturbation_steps (Union(list,numpy.ndarray), optional): The points along the degrees of freedom to evaluate, in this case a distance in angstroms. Defaults to np.linspace(-1, 1, 3).\n", + "\n", + " Raises:\n", + " RuntimeError: `chemistry_inspired` and `hardware_inspired_trial` cannot be used together. Either `chemistry_inspired` is False or `hardware_inspired_trial` is `None`.\n", + "\n", + " Returns:\n", + " qiskit_nature.results.BOPESSamplerResult: The surface energy as a BOPESSamplerResult object.\n", + " \"\"\"\n", + " # Verify that `chemistry_inspired` and `hardware_inspired_trial` do not conflict\n", + " if chemistry_inspired and hardware_inspired_trial is not None:\n", + " raise RuntimeError(\n", + " (\n", + " \"chemistry_inspired and hardware_inspired_trial\"\n", + " \" cannot both be set. Either chemistry_inspired\"\n", + " \" must be False or hardware_inspired_trial must be none.\"\n", + " )\n", + " )\n", + "\n", + " # Step 1 including refinement, passed in\n", + "\n", + " # Step 2a\n", + " molecular_orbital_maker = PySCFDriver(\n", + " molecule=molecule, unit=UnitsType.ANGSTROM, basis=\"sto3g\"\n", + " )\n", + "\n", + " # Refinement to Step 2a\n", + " split_into_classical_and_quantum = ActiveSpaceTransformer(\n", + " num_electrons=num_electrons, num_molecular_orbitals=num_molecular_orbitals\n", + " )\n", + "\n", + " fermionic_hamiltonian = ElectronicStructureProblem(\n", + " molecular_orbital_maker, [split_into_classical_and_quantum]\n", + " )\n", + " fermionic_hamiltonian.second_q_ops()\n", + "\n", + " # Step 2b\n", + " map_fermions_to_qubits = QubitConverter(JordanWignerMapper())\n", + "\n", + " # Step 3a\n", + " if chemistry_inspired:\n", + " molecule_info = fermionic_hamiltonian.molecule_data_transformed\n", + " num_molecular_orbitals = molecule_info.num_molecular_orbitals\n", + " num_spin_orbitals = 2 * num_molecular_orbitals\n", + " num_electrons_spin_up_spin_down = (\n", + " molecule_info.num_alpha,\n", + " molecule_info.num_beta,\n", + " )\n", + " initial_state = HartreeFock(\n", + " num_spin_orbitals, num_electrons_spin_up_spin_down, map_fermions_to_qubits\n", + " )\n", + "\n", + " chemistry_inspired_trial = UCCSD(\n", + " map_fermions_to_qubits,\n", + " num_electrons_spin_up_spin_down,\n", + " num_spin_orbitals,\n", + " initial_state=initial_state,\n", + " )\n", + "\n", + " trial_state = chemistry_inspired_trial\n", + " else:\n", + " if hardware_inspired_trial is None:\n", + " hardware_inspired_trial = TwoLocal(\n", + " rotation_blocks=[\"ry\"],\n", + " entanglement_blocks=\"cz\",\n", + " entanglement=\"linear\",\n", + " reps=2,\n", + " )\n", + "\n", + " trial_state = hardware_inspired_trial\n", + "\n", + " # Step 3b and alternative\n", + " if vqe:\n", + " noise_free_quantum_environment = QuantumInstance(Aer.get_backend('statevector_simulator'))\n", + " solver = VQE(ansatz=trial_state, quantum_instance=noise_free_quantum_environment)\n", + " else:\n", + " solver = NumPyMinimumEigensolver()\n", + "\n", + " # Step 4 and alternative\n", + " ground_state = GroundStateEigensolver(map_fermions_to_qubits, solver)\n", + "\n", + " # Refinement to Step 4\n", + " energy_surface = BOPESSampler(gss=ground_state, bootstrap=False)\n", + " energy_surface_result = energy_surface.sample(\n", + " fermionic_hamiltonian, perturbation_steps\n", + " )\n", + "\n", + " return energy_surface_result" + ] + }, + { + "cell_type": "markdown", + "id": "eaeca112", + "metadata": {}, + "source": [ + "### Your answer" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da2660b0", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "0502e7a3", + "metadata": {}, + "source": [ + "The following code cells give a skeleton to call `construct_hamiltonian_solve_ground_state` and plot the results. Once you are confident with your results, submit them in the code-cell that follows.\n", + "\n", + "**Note: `construct_hamiltonian_solve_ground_state` will take some time to run (approximately 2 minutes). Do not worry if it doesn't return a result immediately.**" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "6dda17b8", + "metadata": {}, + "outputs": [], + "source": [ + "# Q1\n", + "\n", + "# Calculate the energies\n", + "q1_energy_surface_result = construct_hamiltonian_solve_ground_state(\n", + " molecule=macromolecule,\n", + " num_electrons=2,\n", + " num_molecular_orbitals=2,\n", + " chemistry_inspired=True,\n", + " vqe=True,\n", + " perturbation_steps=np.linspace(-0.5, 5, 30)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "6c6c95e0", + "metadata": {}, + "outputs": [], + "source": [ + "# Plot the energies to visualize the results\n", + "plot_energy_landscape(energy_surface_result)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "f45d1e10", + "metadata": {}, + "outputs": [], + "source": [ + "## Q2\n", + "answer_for_ex3c_q2 = 'D'" + ] + }, + { + "cell_type": "markdown", + "id": "8f65c9ca", + "metadata": {}, + "source": [ + "Once you are happy with the results you have acquired, submit the energies and parameters for `construct_hamiltonian_solve_ground_state` in the following cell. Change the values for all parameters, except `energy_surface`, to have the same value that you used in your call of `construct_hamiltonian_solve_ground_state`" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "5d3e2d70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "😢 Your answer is incorrect.\n", + "Message from grader: You didn't appear to pass a `Molecule` object instance.\n" + ] + } + ], + "source": [ + "from qc_grader import grade_ex3c\n", + "\n", + "grade_ex3c(\n", + " energy_surface=q1_energy_surface_result.energies, #q1_energy_surface_result.energies,\n", + " molecule=macromolecule,\n", + " num_electrons=2,\n", + " num_molecular_orbitals=2,\n", + " chemistry_inspired=True,\n", + " hardware_inspired_trial=None,\n", + " vqe=True,\n", + " perturbation_steps=np.linspace(-0.5, 5, 30),\n", + " q2_multiple_choice='D'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "2b9500d6", + "metadata": {}, + "source": [ + "

4. Refining Step 3a

" + ] + }, + { + "cell_type": "markdown", + "id": "7ad9f2f9", + "metadata": {}, + "source": [ + "The last refinement is a lesson in how black-box tweaking can improve results.\n", + "\n", + "In Step 3a, the hardware_inspired_trial is designed to run on actual current-day hardware. Recall this line from the walk-through:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "bb6d4ed0", + "metadata": {}, + "outputs": [], + "source": [ + "hardware_inspired_trial = TwoLocal(rotation_blocks = ['ry'], entanglement_blocks = 'cz',\n", + " entanglement='linear', reps=2)" + ] + }, + { + "cell_type": "markdown", + "id": "90e2c58b", + "metadata": {}, + "source": [ + "Let us get a feel for the `reps` (repetition) parameter. This parameter controls how many rounds of mix and rotate are applied in the trial state. In more detail: there is an initial round of rotations, before mix (often containing no parameters) and another round of rotations are repeated. Certain gates don't generate parameters (e.g. `h`, `cz`). Each round of rotations adds an extra set of parameters that the classical optimizer adjusts in the search for the ground state.\n", + "\n", + "Let's relook at the simple hydrogen molecule and compute the \"ideal\" lowest energy electronic energy using the chemistry trial, the numpy solver and a single zero perturbation (i.e., no perturbations):" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "150518f4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total Energy is: -1.137306035753404 hartree\n", + "(No need to plot, only one configuration calculated.)\n" + ] + } + ], + "source": [ + "true_total_energy = construct_hamiltonian_solve_ground_state(\n", + " molecule=hydrogen_molecule_stretchable, # Step 1\n", + " num_electrons=2, # Step 2a\n", + " num_molecular_orbitals=2, # Step 2a\n", + " chemistry_inspired=True, # Step 3a\n", + " vqe=False, # Step 3b\n", + " perturbation_steps = [0]) # Step 4\n", + "plot_energy_landscape(true_total_energy)" + ] + }, + { + "cell_type": "markdown", + "id": "99e78a74", + "metadata": {}, + "source": [ + "We take this as the true value for the rest of our experiment.\n", + "\n", + "*Next, select `chemistry_inspired=False`, `vqe=True` and pass in a hardware trial with 1 round*:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "180d2ea6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total Energy is: -1.1169696904286086 hartree\n", + "(No need to plot, only one configuration calculated.)\n" + ] + } + ], + "source": [ + "hardware_inspired_trial = TwoLocal(rotation_blocks = ['ry'], entanglement_blocks = 'cz',\n", + " entanglement='linear', reps=1)\n", + "\n", + "quantum_calc_total_energy = construct_hamiltonian_solve_ground_state(\n", + " molecule=hydrogen_molecule_stretchable, # Step 1\n", + " num_electrons=2, # Step 2a\n", + " num_molecular_orbitals=2, # Step 2a\n", + " chemistry_inspired=False, # Step 3a\n", + " hardware_inspired_trial=hardware_inspired_trial, # Step 3a\n", + " vqe=True, # Step 3b\n", + " perturbation_steps = [0]) # Step 4\n", + "plot_energy_landscape(quantum_calc_total_energy)" + ] + }, + { + "cell_type": "markdown", + "id": "bd901827", + "metadata": {}, + "source": [ + "*Notice the difference is small and positive:*\n" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "d8fad5fc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.020336345324795335" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "quantum_calc_total_energy.energies[0] - true_total_energy.energies[0]" + ] + }, + { + "cell_type": "markdown", + "id": "419a6963", + "metadata": {}, + "source": [ + "*Let's see how many parameters are used to specify the trial state:*" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "025442ba", + "metadata": {}, + "outputs": [], + "source": [ + "total_number_of_parameters = len(hardware_inspired_trial._ordered_parameters)\n", + "print(\"Total number of adjustable parameters: \", total_number_of_parameters)" + ] + }, + { + "cell_type": "markdown", + "id": "ce384845", + "metadata": {}, + "source": [ + "

Exercise 3d: The effect of more repetitions

" + ] + }, + { + "cell_type": "markdown", + "id": "95bf928e", + "metadata": {}, + "source": [ + "Q1: Try reps equal to 1 (done for you) and 2 and compare the errors. What happens to the error? Does it increase, decrease, or stay the same?\n", + "Be aware that:\n", + " - VQE is a statistical algorithm, so run it a few times before observing the pattern.\n", + " - Going beyond 2 may not continue the pattern.\n", + " - Note that `reps` is defined in `TwoLocal`\n", + "\n", + "Q2: Check the total number of parameters for reps equal 1 and 2. How many parameters are introduced per round of rotations?" + ] + }, + { + "cell_type": "markdown", + "id": "2fc6d83c", + "metadata": {}, + "source": [ + "## Write your answer here:" + ] + }, + { + "cell_type": "markdown", + "id": "901ddd8f", + "metadata": {}, + "source": [ + "**Enter your answer to the first multiple choice question in the code-cell below and add your answer for Q2. Run the cell to submit your answers.**" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "c8a8f056", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "😢 Your answer is incorrect.\n", + "Message from grader: Your Q1 answer is incorrect\n" + ] + } + ], + "source": [ + "from qc_grader import grade_ex3d\n", + "\n", + "## Q1\n", + "#answer_for_ex3d_q1 = 'decreases'\n", + "# answer_for_ex3d_q1 = 'increases'\n", + "# answer_for_ex3d_q1 = 'stays the same'\n", + "##\n", + "answer_for_ex3d_q1 = 'decreases'\n", + "\n", + "## Q2\n", + "answer_for_ex3d_q2 = 4\n", + "##\n", + "\n", + "grade_ex3d(answer_for_ex3d_q1, answer_for_ex3d_q2)" + ] + }, + { + "cell_type": "markdown", + "id": "69a30466", + "metadata": {}, + "source": [ + "

Exercise 3e: Open-ended: Find the best hardware_inspired_trial to minimize the Energy Error for the Macromolecule

" + ] + }, + { + "cell_type": "markdown", + "id": "e1ad16dd", + "metadata": {}, + "source": [ + "Turning to the macromolecule again. Using, `chemistry_inspired=False`, `vqe=True`, `perturbation_steps = [0]`, a maximum of 8 qubits, and your own hardware_inspired_trial with any combination of options from the walk-through; find the lowest energy. Your answer to this exercise includes all parameters passed to `construct_hamiltonian_solve_ground_state` and the result object it returns. This exercise is scored based on how close your computed energy $E_{computed}$ is to the \"true\" minimum energy of the macromolecule $E_{true}$. This score is calculated as shown below, rounded to the nearest integer." + ] + }, + { + "cell_type": "markdown", + "id": "e3c609e1", + "metadata": {}, + "source": [ + "$$\\text{score} = -10 \\times \\log_{10}{\\left(\\left\\lvert{\\frac{E_{true} - E_{computed}}{E_{true}}}\\right\\rvert\\right)}$$" + ] + }, + { + "cell_type": "markdown", + "id": "e87535fb", + "metadata": {}, + "source": [ + "Achieving a smaller error in your computed energy will increase your score. For example, if the true energy is -42.141 and you compute -40.0, you would have a score of 13. Use the following code cell to trial different `hardware_inspired_trial`s." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "fe495d32", + "metadata": {}, + "outputs": [], + "source": [ + "# Modify the following variables\n", + "num_electrons =2\n", + "num_molecular_orbitals =2\n", + "hardware_inspired_trial = TwoLocal(rotation_blocks = ['ry'], entanglement_blocks = 'cz',\n", + " entanglement='linear', reps=1)\n", + "#\n", + "\n", + "computed_macromolecule_energy_result = construct_hamiltonian_solve_ground_state(\n", + " molecule=macromolecule,\n", + " num_electrons=num_electrons,\n", + " num_molecular_orbitals=num_molecular_orbitals,\n", + " chemistry_inspired=False,\n", + " hardware_inspired_trial=hardware_inspired_trial,\n", + " vqe=True,\n", + " perturbation_steps=[0],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "6c017a73", + "metadata": {}, + "source": [ + "Once you are ready to submit your answer, run the following code cell to have your computed energy scored. You can submit multiple times." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "aab9c236", + "metadata": {}, + "outputs": [], + "source": [ + "from qc_grader import grade_ex3e\n", + "\n", + "grade_ex3e(\n", + " energy_surface_result=computed_macromolecule_energy_result,\n", + " molecule=macromolecule,\n", + " num_electrons=num_electrons,\n", + " num_molecular_orbitals=num_molecular_orbitals,\n", + " chemistry_inspired=False,\n", + " hardware_inspired_trial=hardware_inspired_trial,\n", + " vqe=True,\n", + " perturbation_steps=[0],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c21201e4", + "metadata": {}, + "source": [ + "----------------" + ] + }, + { + "cell_type": "markdown", + "id": "c2e20ca9", + "metadata": {}, + "source": [ + "#### Quantum Chemistry Resources\n", + "*Videos*\n", + "- *Quantum Chemistry I: Obtaining the Qubit Hamiltonian* \n", + " - https://www.youtube.com/watch?v=2XEjrwWhr88\n", + "- *Quantum Chemistry II: Finding the Ground States* \n", + " - https://www.youtube.com/watch?v=_UW6puuGa5E \n", + " - https://www.youtube.com/watch?v=o4BAOKbcd3o\n", + "*Tutorials*\n", + "- https://qiskit.org/documentation/nature/tutorials/01_electronic_structure.html \n", + "- https://qiskit.org/documentation/nature/tutorials/03_ground_state_solvers.html \n", + "- https://qiskit.org/documentation/nature/tutorials/05_Sampling_potential_energy_surfaces.html\n", + "*Code References*\n", + "- UCCSD : https://qiskit.org/documentation/stubs/qiskit.chemistry.components.variational_forms.UCCSD.html\n", + "- ActiveSpaceTransformer: https://qiskit.org/documentation/nature/stubs/qiskit_nature.transformers.second_quantization.electronic.ActiveSpaceTransformer.html?highlight=activespacetransformer#qiskit_nature.transformers.second_quantization.electronic.ActiveSpaceTransformer" + ] + }, + { + "cell_type": "markdown", + "id": "17ba3869", + "metadata": {}, + "source": [ + "Licensing and notes:\n", + "- All images used, with gratitude, are listed below with their respective licenses:\n", + " - https://de.wikipedia.org/wiki/Datei:Teppichschere.jpg by CrazyD is licensed under CC BY-SA 3.0\n", + " - https://commons.wikimedia.org/wiki/File:The_structure_of_the_immature_HIV-1_capsid_in_intact_virus_particles.png by MarinaVladivostok is licensed under CC0 1.0\n", + " - https://commons.wikimedia.org/wiki/File:Peptidformationball.svg by YassineMrabet is licensed under the public domain\n", + " - The remaining images are either IBM-owned, or hand-generated by the authors of this notebook.\n", + "\n", + "- HCONH2 (Formamide) co-ordinates kindly provided by the National Library of Medicine:\n", + " - `National Center for Biotechnology Information (2021). PubChem Compound Summary for CID 713, Formamide. https://pubchem.ncbi.nlm.nih.gov/compound/Formamide.`\n", + "- For further information about the Pauli exclusion principle:\n", + "https://en.wikipedia.org/wiki/Pauli_exclusion_principle\n", + "- We would like to thank collaborators, Prof Yasien and Prof Munro from Wits for extensive assistance.\n", + "- We would like to thank all the testers and feedback providers for their valuable input.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "45ef65da", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

Version Information

Qiskit SoftwareVersion
qiskit-terra0.18.1
qiskit-aer0.8.2
qiskit-ignis0.6.0
qiskit-ibmq-provider0.16.0
qiskit-aqua0.9.4
qiskit0.29.0
qiskit-nature0.1.5
qiskit-finance0.2.0
qiskit-optimization0.2.1
qiskit-machine-learning0.2.0
System information
Python3.8.10 | packaged by conda-forge | (default, May 11 2021, 07:01:05) \n", + "[GCC 9.3.0]
OSLinux
CPUs8
Memory (Gb)31.400043487548828
Wed Sep 08 20:30:41 2021 UTC
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

This code is a part of Qiskit

© Copyright IBM 2017, 2021.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import qiskit.tools.jupyter\n", + "%qiskit_version_table\n", + "%qiskit_copyright" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40b15c80", + "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.7.11" + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": { + "1532e6e002b0440dacbd4be1b4d53476": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "grid_template_areas": "\n \". . . . right \"\n ", + "grid_template_columns": "20% 20% 20% 20% 20%", + "width": "100%" + } + }, + "24a88eb6eb8146cfb6add2eeff79995e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "layout": "IPY_MODEL_bf9f53a1a564437699e515036a0ce2d2", + "style": "IPY_MODEL_24ea4da5007b48bba0eefb815bf355f2", + "value": "
Queue
" + } + }, + "24ea4da5007b48bba0eefb815bf355f2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "description_width": "" + } + }, + "34d6eb0ecc3f4693a22590d777c01bff": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "GridBoxModel", + "state": { + "children": [ + "IPY_MODEL_a2e9a4a096f3492fa00157a542ca6aab" + ], + "layout": "IPY_MODEL_1532e6e002b0440dacbd4be1b4d53476" + } + }, + "34f4126d27b94cbdb95b5e3db42d4c90": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "description_width": "" + } + }, + "5364e21dbf6c4b1490ce18485212f71f": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "grid_area": "right", + "padding": "0px 0px 0px 0px", + "width": "70px" + } + }, + "6a54cf2cc3b64f3c9c4e06b776734063": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "description_width": "" + } + }, + "6ad5c0d1255b40b99977d37bc5c81f4b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "margin": "0px 0px 0px 37px", + "width": "600px" + } + }, + "77614d7f30b14d12af707f227aae6405": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "description_width": "" + } + }, + "878f6c771bf745fabce67abe28c59bce": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": {} + }, + "93f4be9613a647aa9cc2d75a687ddabe": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "children": [ + "IPY_MODEL_ad6328519fa8493aa822d8ea2b454abf", + "IPY_MODEL_b795ed9f92e7455caba35006a8fae03c", + "IPY_MODEL_a26f42befbc2428da5a457404a753b69", + "IPY_MODEL_24a88eb6eb8146cfb6add2eeff79995e", + "IPY_MODEL_f786ddfaed9f45e78e95bd3a4ad90b56" + ], + "layout": "IPY_MODEL_6ad5c0d1255b40b99977d37bc5c81f4b" + } + }, + "a26f42befbc2428da5a457404a753b69": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "layout": "IPY_MODEL_e55cd86f1091451e8364b0ee7347d648", + "style": "IPY_MODEL_34f4126d27b94cbdb95b5e3db42d4c90", + "value": "
Status
" + } + }, + "a2e9a4a096f3492fa00157a542ca6aab": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonModel", + "state": { + "button_style": "primary", + "description": "Clear", + "layout": "IPY_MODEL_5364e21dbf6c4b1490ce18485212f71f", + "style": "IPY_MODEL_bcacef5c97424317afc00ef5a8e97b8d" + } + }, + "a859d46109714988b0c840d8ffa97305": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "layout": "IPY_MODEL_ca86e5598b72444c8475309e38b6741c", + "style": "IPY_MODEL_c7c10e6fac2c42aba8f8640097b8530f", + "value": "

Circuit Properties

" + } + }, + "ad6328519fa8493aa822d8ea2b454abf": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "layout": "IPY_MODEL_f876a81e03e6499b9d7a65ba2f45702c", + "style": "IPY_MODEL_6a54cf2cc3b64f3c9c4e06b776734063", + "value": "
Job ID
" + } + }, + "b795ed9f92e7455caba35006a8fae03c": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "layout": "IPY_MODEL_c435ffe76a164843b08ba1e426130c00", + "style": "IPY_MODEL_d4f9f1267263426ba03d6e805b012d9f", + "value": "
Backend
" + } + }, + "bcacef5c97424317afc00ef5a8e97b8d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ButtonStyleModel", + "state": {} + }, + "bf9f53a1a564437699e515036a0ce2d2": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "width": "70px" + } + }, + "c435ffe76a164843b08ba1e426130c00": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "width": "145px" + } + }, + "c7c10e6fac2c42aba8f8640097b8530f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "description_width": "" + } + }, + "ca86e5598b72444c8475309e38b6741c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "margin": "0px 0px 10px 0px" + } + }, + "d4f9f1267263426ba03d6e805b012d9f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "description_width": "" + } + }, + "e55cd86f1091451e8364b0ee7347d648": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "width": "95px" + } + }, + "f786ddfaed9f45e78e95bd3a4ad90b56": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "layout": "IPY_MODEL_878f6c771bf745fabce67abe28c59bce", + "style": "IPY_MODEL_77614d7f30b14d12af707f227aae6405", + "value": "
Message
" + } + }, + "f876a81e03e6499b9d7a65ba2f45702c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "width": "190px" + } + } + }, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/content/lab3/lab3.ipynb b/content/lab3/lab3.ipynb index e221736..9d0f1c2 100644 --- a/content/lab3/lab3.ipynb +++ b/content/lab3/lab3.ipynb @@ -1045,14 +1045,33 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 14, "id": "58c8ca15", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[['H', [-0.0014, -1.4883, -0.0001]], ['C', [0.0598, -0.3882, 0.0]], ['O', [1.128, 0.2091, 0.0]], ['N', [-1.1878, 0.1791, 0.0]], ['H', [-1.3085, 1.1864, 0.0001]], ['H', [-2.0305, -0.3861, -0.0001]], ['C', [-0.1805, 1.3955, 0.0]]]\n" + ] + } + ], "source": [ - "## Add your code here\n", - "macromolecule = None\n", - "##" + "molecular_variation = Molecule.absolute_stretching\n", + "specific_molecular_variation = apply_variation_to_atom_pair(molecular_variation, atom_pair=(6, 3))\n", + "macromolecule = Molecule(geometry=\n", + " [['H', [-0.0014, -1.4883, -0.0001]],\n", + " ['C', [0.0598, -0.3882, 0.0000]],\n", + " ['O', [1.1280, 0.2091, 0.0000]], \n", + " ['N', [-1.1878, 0.1791, 0.0000]],\n", + " ['H', [-1.3085, 1.1864, 0.0001]],\n", + " ['H', [-2.0305, -0.3861, -0.0001]],\n", + " ['C', [-0.1805, 1.3955, 0.0000]]],\n", + " charge=0, multiplicity=1,\n", + " degrees_of_freedom=[specific_molecular_variation])\n", + "\n", + "print(macromolecule.geometry)" ] }, { @@ -1180,18 +1199,12 @@ "from qc_grader import grade_ex3b\n", "\n", "## Q1\n", - "# answer_for_ex3b_q1 = 'A'\n", - "# answer_for_ex3b_q1 = 'B'\n", - "# answer_for_ex3b_q1 = 'C'\n", + "answer_for_ex3b_q1 = 'C'\n", "##\n", - "answer_for_ex3b_q1 = ''\n", + "\n", "## Q2\n", - "# answer_for_ex3b_q2 = 'A'\n", - "# answer_for_ex3b_q2 = 'B'\n", - "# answer_for_ex3b_q2 = 'C'\n", - "# answer_for_ex3b_q2 = 'D'\n", + "answer_for_ex3b_q2 = 'A'\n", "##\n", - "answer_for_ex3b_q2 = ''\n", "\n", "grade_ex3b(answer_for_ex3b_q1, answer_for_ex3b_q2)" ] @@ -1486,14 +1499,14 @@ "# Q1\n", "\n", "# Calculate the energies\n", - "#q1_energy_surface_result = construct_hamiltonian_solve_ground_state(\n", - "# molecule=None,\n", - "# num_electrons=None,\n", - "# num_molecular_orbitals=None,\n", - "# chemistry_inspired=None,\n", - "# vqe=None,\n", - "# perturbation_steps=None,\n", - "#)" + "q1_energy_surface_result = construct_hamiltonian_solve_ground_state(\n", + " molecule=macromolecule,\n", + " num_electrons=2,\n", + " num_molecular_orbitals=2,\n", + " chemistry_inspired=True,\n", + " vqe=True,\n", + " perturbation_steps=np.linspace(-0.5, 5, 30)\n", + ")" ] }, { @@ -1504,7 +1517,7 @@ "outputs": [], "source": [ "# Plot the energies to visualize the results\n", - "# plot_energy_landscape(energy_surface_result)" + "plot_energy_landscape(energy_surface_result)" ] }, { @@ -1515,11 +1528,7 @@ "outputs": [], "source": [ "## Q2\n", - "# answer_for_ex3c_q2 = 'A'\n", - "# answer_for_ex3c_q2 = 'B'\n", - "# answer_for_ex3c_q2 = 'C'\n", - "# answer_for_ex3c_q2 = 'D'\n", - "answer_for_ex3c_q2 = ''" + "answer_for_ex3c_q2 = 'D'" ] }, { @@ -1549,15 +1558,15 @@ "from qc_grader import grade_ex3c\n", "\n", "grade_ex3c(\n", - " energy_surface=None, #q1_energy_surface_result.energies,\n", - " molecule=None,\n", - " num_electrons=None,\n", - " num_molecular_orbitals=None,\n", - " chemistry_inspired=None,\n", + " energy_surface=q1_energy_surface_result.energies, #q1_energy_surface_result.energies,\n", + " molecule=macromolecule,\n", + " num_electrons=2,\n", + " num_molecular_orbitals=2,\n", + " chemistry_inspired=True,\n", " hardware_inspired_trial=None,\n", - " vqe=None,\n", - " perturbation_steps=None,\n", - " q2_multiple_choice=answer_for_ex3c_q2\n", + " vqe=True,\n", + " perturbation_steps=np.linspace(-0.5, 5, 30),\n", + " q2_multiple_choice='D'\n", ")" ] }, @@ -1771,14 +1780,14 @@ "from qc_grader import grade_ex3d\n", "\n", "## Q1\n", - "# answer_for_ex3d_q1 = 'decreases'\n", + "#answer_for_ex3d_q1 = 'decreases'\n", "# answer_for_ex3d_q1 = 'increases'\n", "# answer_for_ex3d_q1 = 'stays the same'\n", "##\n", - "answer_for_ex3d_q1 = ''\n", + "answer_for_ex3d_q1 = 'decreases'\n", "\n", "## Q2\n", - "answer_for_ex3d_q2 = 0\n", + "answer_for_ex3d_q2 = 4\n", "##\n", "\n", "grade_ex3d(answer_for_ex3d_q1, answer_for_ex3d_q2)" @@ -1824,9 +1833,10 @@ "outputs": [], "source": [ "# Modify the following variables\n", - "num_electrons =\n", - "num_molecular_orbitals =\n", - "hardware_inspired_trial = \n", + "num_electrons =2\n", + "num_molecular_orbitals =2\n", + "hardware_inspired_trial = TwoLocal(rotation_blocks = ['ry'], entanglement_blocks = 'cz',\n", + " entanglement='linear', reps=1)\n", "#\n", "\n", "computed_macromolecule_energy_result = construct_hamiltonian_solve_ground_state(\n", @@ -1967,7 +1977,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Qiskit v0.29.0", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -1981,7 +1991,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.7.11" }, "varInspector": { "cols": {