diff --git a/examples/chemistry/excited_states.ipynb b/examples/chemistry/excited_states.ipynb
index 35ff65f..211f960 100644
--- a/examples/chemistry/excited_states.ipynb
+++ b/examples/chemistry/excited_states.ipynb
@@ -1,1384 +1,1812 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "mOclGIFNL8wf"
- },
- "source": [
- "# Excited States in Tangelo"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "8BtSmADsL8wj"
- },
- "source": [
- "## Introduction\n",
- "\n",
- "One impactful application of quantum chemistry, in both academia and industry, is the study of the interaction of light with matter. Absorption (resp. emission) of a photon by a molecule can promote (resp. demote) an electron from a lower (resp. higher) electronic state to a higher (resp. lower) energy electronic state. The photon wavelength (i.e. energy) required for these transitions to occur is determined by the difference between the two respective electronic states. Therefore, it is imperative to be able to calculate accurate energies for both ground and excited states to study light/matter interations. These energy differences play a central role in many technologies such as solar panels, light-emitting diodes (LED), displays, and colorants. "
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {
- "id": "ZjlMQmjsL8wk"
- },
- "source": [
- "To be more concrete, a colorant must emit light in a narrow region in the visible spectrum to be appropriate for the purpose, that is to say it must exhibit a specific wavelength. Another example is solar panels, where the absorption spectrum of a molecule is tuned via chemical functionalization to fit the solar emission spectrum to optimize the energy output efficiency. Here we show an example of a spectrum for the BODIPY molecule, a molecule widely used for fluorescent dyes. BODIPY absorbs light at a lower wavelength (higher energy) and emits light at a higher wavelength (lower energy). To compute this spectrum, one needs to calculate the ground and excited state energies and calculate their intensities. The absorption spectrum for the simplest BODIPY is shown below. Different absorption and emission wavelengths can be targeted by substituting the hydrogen atoms with different functional groups [J. Chem. Phys. 155, 244102 (2021)](https://aip.scitation.org/doi/10.1063/5.0076787).\n",
- "\n",
- "![BODIPY](../img/bodipy_absorption.png)\n",
- "\n",
- "As there are a very large number of compounds to be considered, predicting absorption/emission UV-visible spectra would be a valuable asset to the scientific community.\n",
- "\n",
- "To achieve complete understanding of light interaction with a molecule, the quantum chemistry community has worked on several algorithms. In general, one must compute the relevant molecular electronic structures for the prediction of UV light absorption/emission. This notebook shows how Tangelo enables excited states calculations by implementing a few existing quantum algorithms. These are broadly grouped into variational optimization algorithms and algorithms that rely on Hamiltonian simulation. Along the way, we keep track of the quantum computational resources required by each of these approaches, and summarize this information at the end of the notebook. The use case here is Li $_2$ for expediency but many of these quantum algorithms can, in principle, be extended to much larger systems such as the BODIPY molecule above.\n",
- "\n",
- "It is worth noting that even with all the computed excited states, non-trivial effects can happen (solvation effect, geometry change, etc.) in which all modify the shape of a spectrum. In this notebook, we do not discuss how these effects are accounted for, but the calculations presented here are the necessary first steps towards computing excited states."
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {
- "id": "iujthgTEPHjH"
- },
- "source": [
- "## Installation & Background\n",
- "In order to successfully run this notebook, you need to install Tangelo. It is also important to be somewhat familiar with the variational quantum eigensolver (VQE). Information about VQE can be found in our [VQE with Tangelo](../variational_methods/vqe.ipynb) notebook. Information about each algorithm can be found by following the references linked when each method is introduced. The cell below installs Tangelo in your environment, if it has not been done already."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "try:\n",
- " import tangelo\n",
- "except ModuleNotFoundError:\n",
- " !pip install git+https://github.com/goodchemistryco/Tangelo.git@develop --quiet\n",
- "\n",
- "# Download the data folder at https://github.com/goodchemistryco/Tangelo-Examples/tree/main/examples/chemistry/data\n",
- "import os\n",
- "if not os.path.isdir(\"data\"):\n",
- " !sudo apt install subversion\n",
- " !svn checkout https://github.com/goodchemistryco/Tangelo-Examples/branches/main/examples/chemistry/data"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "xPrfVi8IL8wl"
- },
- "source": [
- "## Table of Contents\n",
- "* [1. Obtaining excited state energies classically](#1)\n",
- "* [2. Variational optimization algorithms](#2)\n",
- " * [2.1 VQE for lowest singlet and triplet state ](#21)\n",
- " * [2.2 VQE Deflation](#22)\n",
- " * [2.3 Quantum Subspace Expansion](#23)\n",
- " * [2.4 State-Averaged VQE](#24)\n",
- " * [2.5 Multi-state contracted VQE (MC-VQE)](#25)\n",
- " * [2.6 State-Averaged VQE with deflation](#26)\n",
- " * [2.7 State-Averaged Orbital-Optimized VQE](#27)\n",
- "* [3. Hamiltonian Simulation algorithms](#3)\n",
- " * [3.1 Multi-Reference Selected Quantum Krylov](#31)\n",
- " * [3.2 Rodeo Algorithm](#32)\n",
- "* [4. Closing words](#4)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "knX1VqLsL8wl"
- },
- "source": [
- "The molecular system we use to illustrate a number of excited state algorithms in this notebook is Li $_2$ near its equilibrium geometry. The full calculation of the Li $_2$ energies would be non-trivial and very computationally expensive; we therefore restrict ourselves to an active space of 2 electrons in 2 orbitals which involve 4 qubits when mapped to a qubit Hamiltonian using the Jordan-Wigner mapping. However, there are still non-trivial effects that occur with this small problem, made particularly evident in section [2.7](#27). We define two molecule objects:\n",
- "\n",
- "- `mol_li2` defined as the ground state configuration with 2 electrons in the HOMO.\n",
- "- `mol_li2_t` defined as the triplet configuration with an alpha electron in each of the HOMO and LUMO."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "from tangelo import SecondQuantizedMolecule as SQMol\n",
- "li2= \"\"\"Li 0. 0. 0.\n",
- " Li 3.0 0. 0. \"\"\"\n",
- "\n",
- "# 2 electrons in 2 orbitals\n",
- "fo = [0,1]+[i for i in range(4,28)]\n",
- "\n",
- "# Runs RHF calculation\n",
- "mol_Li2 = SQMol(li2, q=0, spin=0, basis='6-31g(d,p)', frozen_orbitals=fo, symmetry=True)\n",
- "\n",
- "# Runs ROHF calculation\n",
- "mol_Li2_t = SQMol(li2, q=0, spin=2, basis=\"6-31g(d,p)\", frozen_orbitals=fo, symmetry=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "D-72nuJ3L8wn"
- },
- "source": [
- "Since we set `symmetry=True` in the initialization, the symmetry labels of all the \n",
- "orbitals have been populated in `mol_li2.mo_symm_labels`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " # Energy Symm Occ\n",
- " 1 -2.4478 A1g 2\n",
- " 2 -2.4478 A1u 2\n",
- " 3 -0.1716 A1g 2\n",
- " 4 0.0129 A1u 0\n",
- "Number of active electrons: 2\n",
- "Number of active orbtials: 2\n"
- ]
- }
- ],
- "source": [
- "# Symmetry labels and occupations for frozen core and active orbitals\n",
- "print(\" # Energy Symm Occ\")\n",
- "for i in range(4):\n",
- " print(f\"{i+1:3d}{mol_Li2.mo_energies[i]: 9.4f} {mol_Li2.mo_symm_labels[i]} {int(mol_Li2.mo_occ[i])}\")\n",
- "\n",
- "# Active electrons, Active orbitals\n",
- "print(f\"Number of active electrons: {mol_Li2.n_active_electrons}\")\n",
- "print(f\"Number of active orbtials: {mol_Li2.n_active_mos}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "INDk1VI0L8wo"
- },
- "source": [
- "We can examine the molecular orbitals by exporting them as cube files. These can then be read in by your favourite orbital viewer.\n",
- "\n",
- "```python\n",
- "from pyscf.tools import cubegen\n",
- "# Output cube files for active orbitals\n",
- "for i in [2, 3]:\n",
- " cubegen.orbital(mol_Li2.to_pyscf(basis = mol_Li2.basis), f'li2_{i+1}.cube', mol_Li2.mean_field.mo_coeff[:, i])\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "wwUS06EwL8wp"
- },
- "source": [
- "## 1. Obtaining excited state energies classically \n",
- "\n",
- "In order to compare the various quantum algorithms, it is useful to have the classically calculated values. Below we will calculate the two A1g and A2g states using PySCF CASCI implementation (https://pyscf.org/user/mcscf.html)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Calculation for A1g symmetry\n",
- "\n",
- "WARN: Mulitple states found in CASCI solver. First state is used to compute the Fock matrix and natural orbitals in active space.\n",
- "\n",
- "CASCI state 0 E = -14.8696203037798 E(CI) = -0.575225247721381 S^2 = 0.0000000\n",
- "CASCI state 1 E = -14.6801959955889 E(CI) = -0.385800939530508 S^2 = 0.0000000\n",
- "\n",
- " Calculation for A1u symmetry\n",
- "\n",
- "WARN: Mulitple states found in CASCI solver. First state is used to compute the Fock matrix and natural orbitals in active space.\n",
- "\n",
- "CASCI state 0 E = -14.8387663453888 E(CI) = -0.544371289330403 S^2 = 2.0000000\n",
- "CASCI state 1 E = -14.7840383314395 E(CI) = -0.489643275381141 S^2 = 0.0000000\n"
- ]
- }
- ],
- "source": [
- "from pyscf import mcscf\n",
- "\n",
- "myhf = mol_Li2.mean_field\n",
- "ncore = {\"A1g\": 1, \"A1u\": 1}\n",
- "ncas = {\"A1g\": 1, \"A1u\": 1}\n",
- "\n",
- "print(\"Calculation for A1g symmetry\")\n",
- "mc = mcscf.CASCI(myhf, 2, (1, 1))\n",
- "mo = mc.sort_mo_by_irrep(cas_irrep_nocc=ncas, cas_irrep_ncore=ncore)\n",
- "mc.fcisolver.wfnsym = \"A1g\"\n",
- "mc.fcisolver.nroots = 2\n",
- "emc_A1g = mc.casci(mo)[0]\n",
- "\n",
- "print(\"\\n Calculation for A1u symmetry\")\n",
- "mc = mcscf.CASCI(myhf, 2, (1, 1))\n",
- "mc.fcisolver.wfnsym = \"A1u\"\n",
- "mc.fcisolver.nroots = 2\n",
- "emc_A1u = mc.casci(mo)[0] "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "mE9Dp_XZL8wq"
- },
- "source": [
- "## 2. Variational algorithms\n",
- "\n",
- "We start by showing how different approaches based on VQE can be used to obtain excited states. For more information about VQE and the `VQESolver` class, feel free to have a look at our dedicated tutorials. "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "Y6t3SWGdL8wq"
- },
- "source": [
- "### 2.1 VQE for lowest singlet and triplet states \n",
- "\n",
- "Both the lowest singlet (ground state) and lowest triplet (first excited state) can be computed using `VQESolver`. The `FCISolver` class can be used to produce a classically-computed reference value, to get a sense of the accuracy of VQE in this situation. Along the way, we capture the quantum computational resources required for each algorithm in the dictionary `algorithm_resources`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- " Ground Singlet state\n",
- "VQE energy = -14.869620302757237\n",
- "CASCI energy = -14.869620303779788\n",
- "\n",
- " Lowest Triplet state\n",
- "VQE energy = -14.853462489026848\n",
- "CASCI energy = -14.853462489027107\n"
- ]
- }
- ],
- "source": [
- "from tangelo.algorithms.variational import VQESolver, BuiltInAnsatze\n",
- "from tangelo.algorithms.classical import FCISolver\n",
- "\n",
- "# Dictionary of resources for each algorithm\n",
- "algorithm_resources = dict()\n",
- "\n",
- "# Ground state energy calculation with VQE, reference values with FCI\n",
- "vqe_options = {\"molecule\": mol_Li2, \"ansatz\": BuiltInAnsatze.UCCSD}\n",
- "vqe_solver = VQESolver(vqe_options)\n",
- "vqe_solver.build()\n",
- "vqe_energy = vqe_solver.simulate()\n",
- "print(\"\\n Ground Singlet state\")\n",
- "print(f\"VQE energy = {vqe_energy}\")\n",
- "print(f\"CASCI energy = {FCISolver(mol_Li2).simulate()}\")\n",
- "algorithm_resources[\"vqe_ground_state\"] = vqe_solver.get_resources()\n",
- "\n",
- "# First excited state energy calculation with VQE, reference values with FCI\n",
- "vqe_options = {\"molecule\": mol_Li2_t, \"ansatz\": BuiltInAnsatze.UpCCGSD}\n",
- "vqe_solver_t = VQESolver(vqe_options)\n",
- "vqe_solver_t.build()\n",
- "vqe_energy_t = vqe_solver_t.simulate()\n",
- "print(\"\\n Lowest Triplet state\")\n",
- "print(f\"VQE energy = {vqe_energy_t}\")\n",
- "print(f\"CASCI energy = {FCISolver(mol_Li2_t).simulate()}\")\n",
- "algorithm_resources[\"vqe_triplet_state\"] = vqe_solver_t.get_resources()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "iXSSQBsvL8wr"
- },
- "source": [
- "### 2.2 VQE Deflation \n",
- "\n",
- "Deflation can be used to gradually obtain higher and higher excited states, by applying an orthogonality penalty against all previous VQE calculations. This idea was introduced in [arXiv:2205.09203](https://arxiv.org/abs/2205.09203).\n",
- "\n",
- "This approach can be implented by using the deflation options built in the `VQESolver` class:\n",
- "\n",
- "- The keyword `\"deflation_circuits\"` allows the user to provide a list of circuits to use in the deflation process.\n",
- "- Additionally, the keyword `\"deflation_coeff\"` allows a user to specify the weight in front of the penalty term. This coefficient must be larger than the difference in energy between the ground and the target excited state."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Excited state #1 \t VQE energy = -14.784037073785134\n",
- "Excited state #2 \t VQE energy = -14.680196061799991\n"
- ]
- }
- ],
- "source": [
- "# Add initial VQE optimal circuit to the deflation circuits list\n",
- "deflation_circuits = [vqe_solver.optimal_circuit.copy()]\n",
- "\n",
- "# Calculate first and second excited states by adding optimal circuits to deflation_circuits\n",
- "for i in range(2):\n",
- " vqe_options = {\"molecule\": mol_Li2, \"ansatz\": BuiltInAnsatze.UpCCGSD, \n",
- " \"deflation_circuits\": deflation_circuits, \"deflation_coeff\": 0.4}\n",
- " vqe_solver = VQESolver(vqe_options)\n",
- " vqe_solver.build()\n",
- " vqe_energy = vqe_solver.simulate()\n",
- " print(f\"Excited state #{i+1} \\t VQE energy = {vqe_energy}\")\n",
- " algorithm_resources[f\"vqe_deflation_state_{i+1}\"] = vqe_solver.get_resources()\n",
- "\n",
- " deflation_circuits.append(vqe_solver.optimal_circuit.copy())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "gZVPYZHGL8wr"
- },
- "source": [
- "The deflation above generated the singlet states. Sometimes it is useful to use a different reference state. In the next example of deflation, we use a reference state with 2 alpha electrons and 0 beta electrons to calculate the triplet state. The reference state is defined by alternating up then down ordering, which yields `{\"ref_state\": [1, 0, 1, 0]}` for 2 alpha electrons in 2 orbitals for this situation."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "VQE energy = -14.838766345424574\n"
- ]
- }
- ],
- "source": [
- "vqe_options = {\"molecule\": mol_Li2, \"ansatz\": BuiltInAnsatze.UpCCGSD, \n",
- " \"deflation_circuits\": deflation_circuits,\n",
- " \"deflation_coeff\": 0.4, \"ref_state\": [1, 0, 1, 0]}\n",
- "vqe_solver_triplet = VQESolver(vqe_options)\n",
- "vqe_solver_triplet.build()\n",
- "vqe_energy = vqe_solver_triplet.simulate()\n",
- "print(f\"VQE energy = {vqe_energy}\")\n",
- "algorithm_resources[f\"vqe_deflation_state_{3}\"] = vqe_solver_triplet.get_resources()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "_odsQd-dL8ws"
- },
- "source": [
- "This value is a great match for the triplet CASCI reference values we obtained earlier. We calculated all the excited states calculated using CASCI using deflation by running `VQESolver` 4 times.\n",
- "\n",
- "The `deflation_circuits` option is also available for the SA-VQE solver shown in another section of this notebook (`SA_VQESolver`), as well as ADAPT (`ADAPTSolver`)."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "uTRtGu2XL8ws"
- },
- "source": [
- "### 2.3 Quantum Subspace Expansion \n",
- "\n",
- "Another way to obtain excited states is to define a pool of operators providing a good approximation to the excitations needed to represent the excited states from the ground state calculations produced by `VQESolver`. This idea was presented in [arXiv:1603.05681](https://arxiv.org/abs/1603.05681).\n",
- "\n",
- "For this example, we choose a pool of operators of the form $O_p=a_i^{\\dagger}a_j$.\n",
- "\n",
- "We then have to solve $FU = SUE$, where $F_{pq}=\\left<\\psi\\right|O_p^* H O_q\\left|\\psi\\right>$ and $S_{pq}=\\left<\\psi\\right|O_p^* O_q\\left|\\psi\\right>$.\n",
- "\n",
- "For simplicity here, we keep all wavefunction symmetry excitations. However, the matrix we need to diagonalize can be made smaller by only keeping excitations that respect the desired wavefunction symmetry of the excited state."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "from scipy.linalg import eigh\n",
- "from openfermion.utils import hermitian_conjugated as hc\n",
- "\n",
- "from tangelo.toolboxes.operators import FermionOperator\n",
- "from tangelo.toolboxes.qubit_mappings.mapping_transform import fermion_to_qubit_mapping as f2q_mapping\n",
- "\n",
- "# Generate all single excitations as qubit operators\n",
- "op_list = list()\n",
- "for i in range(2):\n",
- " for j in range(i+1, 2):\n",
- " op_list += [f2q_mapping(FermionOperator(((2*i, 1), (2*j, 0))), \"jw\")] #spin-up transition\n",
- " op_list += [f2q_mapping(FermionOperator(((2*i+1, 1), (2*j+1, 0))), \"jw\")] #spin-down transition\n",
- " op_list += [f2q_mapping(FermionOperator(((2*i+1, 1), (2*j, 0))), \"jw\")] #spin-up to spin-down\n",
- " op_list += [f2q_mapping(FermionOperator(((2*i, 1), (2*j+1, 0))), \"jw\")] #spin-down to spin-up\n",
- "\n",
- "# Compute F and S matrices.\n",
- "size_mat = len(op_list)\n",
- "h = np.zeros((size_mat, size_mat))\n",
- "s = np.zeros((size_mat, size_mat))\n",
- "state_circuit = vqe_solver.optimal_circuit\n",
- "for i, op1 in enumerate(op_list):\n",
- " for j, op2 in enumerate(op_list):\n",
- " h[i, j] = np.real(vqe_solver.backend.get_expectation_value(hc(op1)*vqe_solver.qubit_hamiltonian*op2, state_circuit))\n",
- " s[i, j] = np.real(vqe_solver.backend.get_expectation_value(hc(op1)*op2, state_circuit))\n",
- "\n",
- "label = \"quantum_subspace_expansion\"\n",
- "algorithm_resources[label] = vqe_solver.get_resources()\n",
- "algorithm_resources[label][\"n_post_terms\"] = len(op_list)**2*algorithm_resources[label][\"qubit_hamiltonian_terms\"]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "MrS38WBO2DBF"
- },
- "source": [
- "After generating the matrices on the quantum computer. We need to perform the classical post-processing to obtain the energies by solving the $FU = SUE$ eigenvalue problem."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Quantum Subspace Expansion energies: \n",
- " [-14.83876635 -14.83876635 -14.83876635 -14.7840384 ]\n"
- ]
- }
- ],
- "source": [
- "# Solve FU = SUE\n",
- "e, v = eigh(h,s)\n",
- "print(f\"Quantum Subspace Expansion energies: \\n {e}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "YCqaM-2SL8ws"
- },
- "source": [
- "We can see that we have obtained the correct energies for CASCI state A1g state 1, and A2 state 0 and 1. A1g state 1 was not recovered. We would therefore need to measure more excitations in $F$."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "SLJrouJXL8wt"
- },
- "source": [
- "### 2.4 State-Averaged VQE \n",
- "\n",
- "Another method to obtain excited states is to use the State-Averaged VQE Solver (SA-VQE). SA-VQE minimizes the average energy of multiple orthogonal reference states using the same ansatz circuit. As the reference states are orthogonal, using the same circuit transformation (a unitary), results in final states that are also orthogonal. This idea can be found in [arXiv:2009.11417](https://arxiv.org/pdf/2009.11417.pdf).\n",
- "\n",
- "Here, we target singlet states only. This can be accomplished by adding a penalty term with `\"penalty_terms\": {\"S^2\": [2, 0]}`. This means that the target Hamiltonian to be minimized is $H = H_0 + 2 (\\hat{S}^2 - 0)^2$, where $H_0$ is the original molecular Hamiltonian."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Singlet State 0 has energy -14.742180682021289\n",
- "Singlet State 1 has energy -14.812125666941942\n",
- "Singlet State 2 has energy -14.7795400653701\n"
- ]
- }
- ],
- "source": [
- "from tangelo.algorithms.variational import SA_VQESolver\n",
- "\n",
- "vqe_options = {\"molecule\": mol_Li2, \"ref_states\": [[1,1,0,0], [1,0,0,1], [0,0,1,1]],\n",
- " \"weights\": [1, 1, 1], \"penalty_terms\": {\"S^2\": [2, 0]},\n",
- " \"qubit_mapping\": \"jw\", \"ansatz\": BuiltInAnsatze.UpCCGSD,\n",
- " }\n",
- "vqe_solver = SA_VQESolver(vqe_options)\n",
- "vqe_solver.build()\n",
- "enernew = vqe_solver.simulate()\n",
- "for i, energy in enumerate(vqe_solver.state_energies):\n",
- " print(f\"Singlet State {i} has energy {energy}\")\n",
- "\n",
- "algorithm_resources[\"sa_vqe\"] = vqe_solver.get_resources()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "kpLLy2N2L8wt"
- },
- "source": [
- "The energies above are inaccurate, as the calculated states are restricted to linear combinations of the three lowest singlet states. We can use MC-VQE to generate the exact eigenvectors, as shown in the next section.\n",
- "\n",
- "However, the cell below shows the $\\hat{S}^2$ expectation value is nearly zero for all states, so they are all singlet as expected when using the penalty term."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "State 0 has S^2 = 3.529243208788557e-08\n",
- "State 1 has S^2 = 2.0223862616242094e-06\n",
- "State 2 has S^2 = 7.838201587784255e-09\n"
- ]
- }
- ],
- "source": [
- "from tangelo.toolboxes.ansatz_generator.fermionic_operators import spin2_operator\n",
- "\n",
- "s2op = f2q_mapping(spin2_operator(2), \"jw\")\n",
- "for i in range(3):\n",
- " print(f\"State {i} has S^2 = {vqe_solver.backend.get_expectation_value(s2op, vqe_solver.reference_circuits[i]+vqe_solver.optimal_circuit)}\")\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "G6afws2QL8wt"
- },
- "source": [
- "### 2.5 Multistate, contracted VQE (MC-VQE) \n",
- "\n",
- "To obtain the energies of the individual states, we can use multistate contracted VQE (MC-VQE), as introduced in [arXiv:1901.01234](https://arxiv.org/abs/1901.01234). This process defines a small matrix by measuring the Hamiltonian expectation values of $(\\left|\\theta_i\\right>+\\left|\\theta_j\\right>)/\\sqrt{2}$ and $(\\left|\\theta_i\\right>-\\left|\\theta_j\\right>)/\\sqrt{2}$ for all combinations of our final states ($\\left|\\theta_i\\right>$) resulting from the SA-VQE procedure. \n",
- "\n",
- "In general, the reference states are simple occupations so generating $(\\left|\\theta_i\\right>+\\left|\\theta_j\\right>)/\\sqrt{2}$ and $(\\left|\\theta_i\\right>-\\left|\\theta_j\\right>)/\\sqrt{2}$ by hand should be \"fairly straightforward\". In this notebook, we use Tangelo to obtain these statevectors and then generate the expectation values."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Generate individual statevectors\n",
- "ref_svs = list()\n",
- "for circuit in vqe_solver.reference_circuits:\n",
- " _, sv = vqe_solver.backend.simulate(circuit, return_statevector=True)\n",
- " ref_svs.append(sv)\n",
- "\n",
- "# Generate Equation (2) using equation (4) and (5) of arXiv:1901.01234\n",
- "h_theta_theta = np.zeros((3,3))\n",
- "for i, sv1 in enumerate(ref_svs):\n",
- " for j, sv2 in enumerate(ref_svs):\n",
- " if i != j:\n",
- " sv_plus = (sv1 + sv2)/np.sqrt(2)\n",
- " sv_minus = (sv1 - sv2)/np.sqrt(2)\n",
- " exp_plus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, vqe_solver.optimal_circuit, initial_statevector=sv_plus)\n",
- " exp_minus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, vqe_solver.optimal_circuit, initial_statevector=sv_minus)\n",
- " h_theta_theta[i, j] = (exp_plus-exp_minus)/2\n",
- " else:\n",
- " h_theta_theta[i, j] = vqe_solver.state_energies[i]\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "10myRMdfHJoJ"
- },
- "source": [
- "Accurate energies can be recovered by solving the resulting eigenproblem classically:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Singlet State 0 \t MC-VQE energy = -14.869616815256682\n",
- "Singlet State 1 \t MC-VQE energy = -14.784034669938677\n",
- "Singlet State 2 \t MC-VQE energy = -14.68019492913796\n"
- ]
- }
- ],
- "source": [
- "e, _ = np.linalg.eigh(h_theta_theta)\n",
- "for i, energy in enumerate(e):\n",
- " print(f\"Singlet State {i} \\t MC-VQE energy = {energy}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "JtJADlmZL8wu"
- },
- "source": [
- "We can see that these singlet energies are all close to the exact answer. "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "IrcmQn8cL8wu"
- },
- "source": [
- "#### Using StateVector for MC-VQE\n",
- "The code below can be used obtain the same MC-VQE result by using `StateVector` to automatically generate circuits for $(\\left|\\theta_i\\right>+\\left|\\theta_j\\right>)/\\sqrt{2}$ and $(\\left|\\theta_i\\right>-\\left|\\theta_j\\right>)/\\sqrt{2}$. However, the circuits created by StateVector are generally inefficient and one should try to create the circuits that generate these states by hand if running on a real quantum device."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [],
- "source": [
- "from tangelo.linq.helpers import StateVector\n",
- "\n",
- "# Generate individual statevectors\n",
- "ref_svs = list()\n",
- "for state in vqe_solver.ref_states:\n",
- " sv = np.zeros(2**4)\n",
- " # Generate bitstring representation of each ref_state and populate that position in the statevector\n",
- " bitstring = \"\".join([str(i) for i in reversed(state)])\n",
- " sv[int(bitstring, base=2)] = 1\n",
- " ref_svs.append(sv)\n",
- "\n",
- "# Generate Equation (2) using equation (4) and (5) of arXiv:1901.01234\n",
- "h_theta_theta = np.zeros((len(ref_svs), len(ref_svs)))\n",
- "for i, sv1 in enumerate(ref_svs):\n",
- " for j, sv2 in enumerate(ref_svs):\n",
- " if i != j:\n",
- " sv_plus = (sv1 + sv2)/np.sqrt(2)\n",
- " sv_plus = StateVector(sv_plus)\n",
- " ref_circ_plus = sv_plus.initializing_circuit()\n",
- " exp_plus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, ref_circ_plus + vqe_solver.optimal_circuit)\n",
- "\n",
- " sv_minus = (sv1 - sv2)/np.sqrt(2)\n",
- " sv_minus = StateVector(sv_minus)\n",
- " ref_circ_minus = sv_minus.initializing_circuit()\n",
- " exp_minus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, ref_circ_minus + vqe_solver.optimal_circuit)\n",
- "\n",
- " h_theta_theta[i, j] = (exp_plus-exp_minus)/2\n",
- " else:\n",
- " h_theta_theta[i, j] = vqe_solver.state_energies[i]\n",
- "\n",
- "algorithm_resources[\"mc_vqe\"] = vqe_solver.get_resources()\n",
- "algorithm_resources[\"mc_vqe\"][\"n_post_terms\"] = len(ref_svs)**2*algorithm_resources[\"mc_vqe\"][\"qubit_hamiltonian_terms\"]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Singlet State 0 \t MC-VQE energy = -14.869616815256672\n",
- "Singlet State 1 \t MC-VQE energy = -14.784034669938706\n",
- "Singlet State 2 \t MC-VQE energy = -14.680194929137963\n"
- ]
- }
- ],
- "source": [
- "e, _ = np.linalg.eigh(h_theta_theta)\n",
- "for i, energy in enumerate(e):\n",
- " print(f\"Singlet State {i} \\t MC-VQE energy = {energy}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "p6odrzVoL8wv"
- },
- "source": [
- "### 2.6 State-Averaged VQE with deflation \n",
- "We can obtain the final excited state by using deflation for the three singlet states above and removing the penalty term. We define a reference state with `\"ref_states\": [[1, 0, 1, 0]]` that better targets the remaining triplet state. We can revert back to the UCCSD ansatz for this state as we do not need as expressive an ansatz anymore."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Triplet State 0 has energy -14.83876634542472\n"
- ]
- }
- ],
- "source": [
- "vqe_options = {\"molecule\": mol_Li2, \"ref_states\": [[1, 0, 1, 0]],\n",
- " \"weights\": [1], \"deflation_circuits\": [vqe_solver.reference_circuits[i]+vqe_solver.optimal_circuit for i in range(3)],\n",
- " \"qubit_mapping\": \"jw\", \"ansatz\": BuiltInAnsatze.UCCSD,\n",
- " }\n",
- "vqe_solver_deflate = SA_VQESolver(vqe_options)\n",
- "vqe_solver_deflate.build()\n",
- "enernew = vqe_solver_deflate.simulate()\n",
- "\n",
- "for i, energy in enumerate(vqe_solver_deflate.state_energies):\n",
- " print(f\"Triplet State {i} has energy {energy}\")\n",
- "\n",
- "algorithm_resources[f\"sa_vqe_deflation\"] = vqe_solver_deflate.get_resources()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "JrU59nB3L8wv"
- },
- "source": [
- "This is the correct triplet state energy."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "FNeQXqbIL8wv"
- },
- "source": [
- "### 2.7 State-Averaged Orbital-Optimized VQE \n",
- "\n",
- "This performs the equivalent of a CASSCF calculation using a quantum computer. This approach runs multiple iterations comprised of the two following steps:\n",
- "\n",
- "- SA-VQE calculation\n",
- "- orbital optimization \n",
- "\n",
- "These iterations are called by using the `iterate()` call. The `simulate()` method from `SA_OO_Solver` only performs a State-Averated VQE simulation. The reference for this method is [arXiv:2009.11417](https://arxiv.org/pdf/2009.11417.pdf)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "State 0 has energy -14.87559934824753\n",
- "State 1 has energy -14.85178914846094\n"
- ]
- }
- ],
- "source": [
- "from tangelo.algorithms.variational import SA_OO_Solver\n",
- "\n",
- "mol_Li2_nosym = SQMol(li2, q=0, spin=0, basis='6-31g(d,p)',\n",
- " frozen_orbitals=fo, symmetry=False)\n",
- "vqe_options = {\"molecule\": mol_Li2_nosym, \"ref_states\": [[1,1,0,0], [1,0,1,0]],\n",
- " \"weights\": [1, 1],\n",
- " \"qubit_mapping\": \"jw\", \"ansatz\": BuiltInAnsatze.UpCCGSD, \"ansatz_options\": {\"k\": 2}\n",
- " }\n",
- "vqe_solver = SA_OO_Solver(vqe_options)\n",
- "vqe_solver.build()\n",
- "enernew = vqe_solver.iterate()\n",
- "for i, energy in enumerate(vqe_solver.state_energies):\n",
- " print(f\"State {i} has energy {energy}\")\n",
- "\n",
- "algorithm_resources[\"sa_oo_vqe\"] = vqe_solver.get_resources()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "PD3cQc1GL8ww"
- },
- "source": [
- "Comparing the `SA_OO_VQE` solution to CASSCF calculations from a library such as pyscf shows similar results."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CASSCF energy = -14.8636942982906\n",
- "CASCI E = -14.8636942982906 E(CI) = -0.569133524449606 S^2 = 1.0000000\n",
- "CASCI state-averaged energy = -14.8636942982906\n",
- "CASCI energy for each state\n",
- " State 0 weight 0.5 E = -14.8756048775827 S^2 = 0.0000000\n",
- " State 1 weight 0.5 E = -14.8517837189985 S^2 = 2.0000000\n"
- ]
- }
- ],
- "source": [
- "mol_Li2_no_sym_copy = SQMol(li2, q=0, spin=0, basis='6-31g(d,p)',\n",
- " frozen_orbitals=fo, symmetry=False)\n",
- "mc = mcscf.CASSCF(mol_Li2_no_sym_copy.mean_field, 2, 2).state_average([0.5, 0.5])\n",
- "energy = mc.kernel()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "N7ZIjE-ML8ww"
- },
- "source": [
- "`SA_OO_Solver` has optimized the orbitals in `mol_Li2_nosym` to minimize the average energy of the states above. We can then use the code below to output the optimized molecular orbitals as cube files and compare to the unoptimized orbitals from the top of the notebook.\n",
- "\n",
- "```python\n",
- "from pyscf.tools import cubegen\n",
- "# loop over active orbitals i.e. 2, 3\n",
- "for i in [2, 3]:\n",
- " cubegen.orbital(mol_Li2_nosym.to_pyscf(basis = mol_Li2_nosym.basis), f'li2_{i+1}_opt.cube', mol_Li2_nosym.mean_field.mo_coeff[:, i])\n",
- "```"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {
- "id": "_uXgf8A7L8ww"
- },
- "source": [
- "Using [Avogadro](https://avogadro.cc/) to generate the two figures below with the .cube files outputted above, we see that the original fourth molecular orbital and the optimized fourth molecular orbital look very different:\n",
- "\n",
- "
\n",
- "
\n",
- "
\n",
- " Original molecular orbital \n",
- "
\n",
- "
\n",
- " Optimized molecular orbital\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "JzCzgcA1L8ww"
- },
- "source": [
- "Li ${_2}$ is a molecule that requires CASSCF type optimization to exihibit the correct qualitative behavior when using a small active space. Below, we run `SA_OO_VQE` for multiple different bond lengths and compare to CASCI. This calculation can take more than one minute, depending on your computer."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Computing state-averaged orbital-optimized VQE energy for r=2.0\n",
- "Computing state-averaged orbital-optimized VQE energy for r=2.2\n",
- "Computing state-averaged orbital-optimized VQE energy for r=2.5\n",
- "Computing state-averaged orbital-optimized VQE energy for r=3.0\n",
- "Computing state-averaged orbital-optimized VQE energy for r=3.5\n",
- "Computing state-averaged orbital-optimized VQE energy for r=4.0\n",
- "Computing state-averaged orbital-optimized VQE energy for r=4.5\n",
- "Computing state-averaged orbital-optimized VQE energy for r=5.0\n",
- "Computing state-averaged orbital-optimized VQE energy for r=6.0\n",
- "Computing state-averaged orbital-optimized VQE energy for r=7.0\n",
- "Computing state-averaged orbital-optimized VQE energy for r=9.0\n"
- ]
- }
- ],
- "source": [
- "sa_oo_eners = list()\n",
- "casci_eners = list()\n",
- "xvals = np.array([2, 2.2, 2.5, 3., 3.5, 4., 4.5, 5., 6., 7., 9.])\n",
- "\n",
- "for r in xvals:\n",
- " print(f\"Computing state-averaged orbital-optimized VQE energy for r={r}\")\n",
- " li2_xyz = [('Li', (0, 0, 0)),('Li', (r, 0, 0))]\n",
- " \n",
- " mol_Li2_nosym_copy = SQMol(li2_xyz, q=0, spin=0, basis='6-31g(d,p)',\n",
- " frozen_orbitals=fo, symmetry=False)\n",
- " mc = mcscf.CASCI(mol_Li2_nosym_copy.mean_field, 2, 2)\n",
- " mc.fcisolver.nroots = 2\n",
- " mc.verbose = 0\n",
- " e = mc.kernel()\n",
- " casci_eners.append(e[0])\n",
- "\n",
- " # Compute SA-OO-VQE energy\n",
- " mol_Li2_nosym = SQMol(li2_xyz, q=0, spin=0, basis='6-31g(d,p)',\n",
- " frozen_orbitals=fo, symmetry=False)\n",
- " vqe_options = {\"molecule\": mol_Li2_nosym, \"ref_states\": [[1, 1, 0, 0], [1, 0, 1, 0]], \"tol\": 1.e-3,\n",
- " \"ansatz\": BuiltInAnsatze.UCCGD, \"weights\": [1, 1], \"n_oo_per_iter\": 1}\n",
- " vqe_solver = SA_OO_Solver(vqe_options)\n",
- " vqe_solver.build()\n",
- " enernew = vqe_solver.iterate()\n",
- " sa_oo_eners.append(vqe_solver.state_energies)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "E_fA-ed2L8wx"
- },
- "source": [
- "The plot below shows the resulting potential energy curves, and illustrates the impact of orbital optimization for our use case:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- },
- {
- "data": {
- "image/png": "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sH//fj755BP0ej0Wi6VS8dak7OxsunfvzgcffFC7N77i0smi2lR0teprdeKRkUpMq9ZK6s+La/Q+QghRm3Jzc5WYmBglNzf30k6rVVFMWbW/Wa0Vijk1NVUBlHXr1l313MzMTMXd3V05fPiwMnToUGXy5MkV/rPZunWrAiizZ88udezFF19UdDqdkpCQoCiKovz3v/9VAOW3334rde59992n+Pn5KVlZWWXeZ8aMGUpoaGi5caxdu1YBSmxvvfWWoiiKMn/+fKVTp06Ku7u70rBhQ2X48OHKhQsXFEVRlPj4+FLXjRw5UlEURbFYLMqUKVOU0NBQxcXFRYmMjFQWLVpUoT+XonZ379591XPL/P0qVNHvb6mU7mRcIiLI2bZN5lEJIZxfQQ5MCar9+752FvRuVz2taL29X375hZtuugmDwVDuuQsXLqR169a0atWKESNGMHbsWCZMmIBKpbrqfX788Ufc3d15+umnSx176aWX+Pjjj1m8eDFjx47lhx9+IDw8nAEDBpR57pIlS1i5ciWDBg0qdTwwMJBz586xYcMGevbsWep4t27dmDlzJhMnTiQ2Ntb+ZwBQUFDAu+++S6tWrbh48SIvvvgijz76KMuXLyckJITFixczePBgYmNj8fT0xGg0AjB16lQWLFjAl19+ScuWLdmwYQMjRozA39+fXr16XfXPpjZJQuVk5Ek/IYSoG7RaLd999x1PPvkkX375JR07dqRXr14MGzaMyMjIEufOmzePESNGAHDnnXeSnp7O+vXrueWWW656n7i4OJo3b45ery91LCgoCE9PT+Li4uznRhQ+wHS5ov1F515uyJAh/Pnnn/Tq1YvAwEBuuukm+vTpwyOPPIKnpyd6vR4vLy9UKhWBgYElrh01apT9dVhYGLNnz6ZLly5kZWXh7u6Or68vYFtmp2gOlslkYsqUKaxatYquXbvar920aRNz5syRhErUrKJaVKZDh1CsVlRqmSYnhHBSOldbb5Ej7ltBgwcPpl+/fmzcuJG///6bP/74g2nTpjF37lweffRRAGJjY9m+fTv/+9//AFsiNnToUObNm1ehhApsc6MqqjLnFqfRaPj222957733WLNmDdu2bWPKlCl88MEHbN++nUaNGpV77a5du3j77bfZu3cvqampWK1WABISEmjTpk2Z1xw9epScnBxuv/32Evvz8/OJjo6u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",
- "text/plain": [
- "
"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "import matplotlib.pyplot as plt\n",
- "\n",
- "sa_oo_eners=np.array(sa_oo_eners)\n",
- "casci_eners= np.array(casci_eners)\n",
- "\n",
- "fig, ax = plt.subplots()\n",
- "ax.plot(xvals, sa_oo_eners[:, 0], label=\"SA_OO State 0\")\n",
- "ax.plot(xvals, sa_oo_eners[:, 1], label=\"SA_OO State 1\")\n",
- "ax.plot(xvals, casci_eners[:, 0], label=\"CASCI State 0\")\n",
- "ax.plot(xvals, casci_eners[:, 1], label=\"CASCI State 1\")\n",
- "ax.set_xlabel('r (Angstrom)')\n",
- "ax.set_ylabel('Energy (Hartree)')\n",
- "ax.legend()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "rpnEQfLZL8wx"
- },
- "source": [
- "## 3. Hamiltonian Simulation algorithms \n",
- "\n",
- "We now illustrate a few other approches based on time-evolution of the Hamiltonian. Although these algorithms are not NISQ-friendly, they do not require non-linear optimization of parameters like the variational methods encountered in the previous sections. They may be a better choice for future fault-tolerant architectures.\n",
- "\n",
- "### 3.1 Multi-Reference Selected Quantum Krylov (MRSQK) \n",
- "\n",
- "The multi-reference selected Quantum Krylov algorithm as outlined in [arXiv:1911.05163](https://arxiv.org/abs/1911.05163) uses multiple reference states and performs multiple time evolutions $U = e^{-iH\\tau}$ for time $\\tau$, to generate a Krylov representation of the system. The method relies on building two matrices ${\\cal{H}}$ and $S$, whose elements are defined by ${\\cal{H}_{ia,jb}} = \\left<\\phi_a\\right|U^i H U^j\\left|\\phi_b\\right>$ and $S_{ia,jb} = \\left<\\phi_a\\right|U^i U^j\\left|\\phi_b\\right>$, where $\\phi_a, \\phi_b$ denote different reference configurations. The matrix elements are measured using the procedure outlined in [arXiv:1911.05163](https://arxiv.org/abs/1911.05163) and the energies obtained through solving ${\\cal{H}}V = SVE$.\n",
- "\n",
- "In [arXiv:2109.06868](https://arxiv.org/abs/2109.06868), it was further noticed that one can use any function of $\\cal{H}$ to obtain the eigenvalues. For example, one could use $f({\\cal{H}})=e^{-iH\\tau}=U$. The same procedure results in the matrix elements $f({\\cal{H}})_{ia,jb} = \\left<\\phi_a\\right|U^i U U^j\\left|\\phi_b\\right>, S_{ia,jb} = \\left<\\phi_a\\right|U^i U^j\\left|\\phi_b\\right>$ for the eigenvalue problem $f({\\cal{H}})V=SVf(E)$. As $E$ is a diagonal matrix, the correct energies can be obtained by calculating the phase of the eigenvalues ($f(E)=e^{-iE\\tau}$) and dividing by $\\tau$. (i.e. $\\arctan \\left[\\Im(f(E))/\\Re(f(E)) \\right]/\\tau$). The resulting circuit is slightly longer but much fewer measurements are required. It is worth mentioning that [qubitization](https://arxiv.org/abs/1610.06546), which natively implements $e^{i \\arccos(H\\tau)}$, can be used without issue. Qubitization is currently one of the most efficient algorithms that implements time-evolution."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {},
- "outputs": [],
- "source": [
- "from itertools import product\n",
- "from scipy.linalg import eigh, eigvals\n",
- "\n",
- "from tangelo.linq import get_backend, Circuit, Gate\n",
- "from tangelo.toolboxes.operators import QubitOperator, count_qubits\n",
- "from tangelo.toolboxes.qubit_mappings.statevector_mapping import vector_to_circuit\n",
- "from tangelo.toolboxes.ansatz_generator.ansatz_utils import controlled_pauliwords, trotterize"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "The HV=SVE energies are [-14.8696203 -14.83876634 -14.78403833 -14.680196 ]\n",
- "The f(H)V=SVf(E) energies are [-14.86962029 -14.680196 -14.83876634 -14.78403833]\n"
- ]
- }
- ],
- "source": [
- "# Number of Krylov vectors\n",
- "n_krylov = 4\n",
- "# Simulation time for each unitary\n",
- "tau = 0.04\n",
- "# Qubit Mapping\n",
- "mapping = \"jw\"\n",
- "\n",
- "backend = get_backend()\n",
- "\n",
- "# Qubit operator for Li2\n",
- "qu_op = f2q_mapping(mol_Li2.fermionic_hamiltonian, mapping, mol_Li2.n_active_sos,\n",
- " mol_Li2.n_active_electrons, up_then_down=False, spin=mol_Li2.spin)\n",
- "\n",
- "# control qubit\n",
- "c_q = count_qubits(qu_op)\n",
- "\n",
- "# Operator that measures off-diagonal matrix elements i.e. 2|0><1|\n",
- "zeroone = (QubitOperator(f\"X{c_q}\", 1) + QubitOperator(f\"Y{c_q}\", 1j))\n",
- "\n",
- "# Controlled unitaries for each term in qu_op\n",
- "c_qu = controlled_pauliwords(qubit_op=qu_op, control=c_q, n_qubits=5)\n",
- "\n",
- "# Controlled time-evolution of qu_op\n",
- "c_trott = trotterize(qu_op, time=tau, n_trotter_steps=1, trotter_order=1, control=4)\n",
- "\n",
- "# Generate multiple controlled-reference states.\n",
- "reference_states = list()\n",
- "reference_vecs = [[1, 1, 0, 0], [1, 0, 0, 1]]\n",
- "for vec in reference_vecs:\n",
- " circ = vector_to_circuit(vec)\n",
- " gates = [Gate(\"C\"+gate.name, target=gate.target, control=4) for gate in circ]\n",
- " reference_states += [Circuit(gates)]\n",
- "\n",
- "# Calculate MRSQK\n",
- "sab = np.zeros((n_krylov, n_krylov), dtype=complex)\n",
- "hab = np.zeros((n_krylov, n_krylov), dtype=complex)\n",
- "fhab = np.zeros((n_krylov, n_krylov), dtype=complex)\n",
- "\n",
- "for a, b in product(range(n_krylov), range(n_krylov)):\n",
- " # Generate Ua and Ub unitaries\n",
- " ua = reference_states[a%2] + c_trott * (a//2) if a > 1 else reference_states[a%2]\n",
- " ub = reference_states[b%2] + c_trott * (b//2) if b > 1 else reference_states[b%2]\n",
- " \n",
- " # Build circuit from Figure 2 for off-diagonal overlap\n",
- " hab_circuit = Circuit([Gate(\"H\", c_q)]) + ua + Circuit([Gate(\"X\", c_q)]) + ub\n",
- " sab[a, b] = backend.get_expectation_value(zeroone, hab_circuit) / 2\n",
- " sab[b, a] = sab[a, b].conj()\n",
- "\n",
- " # Hamiltonian matrix element for f(H) = e^{-i H \\tau}\n",
- " fhab[a, b] = backend.get_expectation_value(zeroone, hab_circuit+c_trott.inverse())/2\n",
- "\n",
- " # Return statevector for faster calculation of Hamiltonian matrix elements\n",
- " _ , initial_state = backend.simulate(hab_circuit, return_statevector=True)\n",
- " for i, (term, coeff) in enumerate(qu_op.terms.items()):\n",
- "\n",
- " # From calculated statevector append controlled-pauliword for each term in Hamiltonian and measure zeroone\n",
- " expect = coeff*backend.get_expectation_value(zeroone, c_qu[i], initial_statevector=initial_state) / 2\n",
- "\n",
- " # Add term to sum\n",
- " hab[a, b] += expect\n",
- "\n",
- "e, v = eigh(hab, sab)\n",
- "print(f\"The HV=SVE energies are {e}\")\n",
- "e = eigvals(fhab, sab)\n",
- "print(f\"The f(H)V=SVf(E) energies are {np.arctan2(np.imag(e), np.real(e))/tau}\")\n",
- "\n",
- "algorithm_resources[\"mrsqk\"] = dict()\n",
- "algorithm_resources[\"mrsqk\"][\"qubit_hamiltonian_terms\"] = 0\n",
- "algorithm_resources[\"mrsqk\"][\"circuit_2qubit_gates\"] = hab_circuit.counts.get(\"CNOT\", 0)\n",
- "algorithm_resources[\"mrsqk\"][\"n_post_terms\"] = n_krylov**2"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "QiFCp4e6L8wy"
- },
- "source": [
- "The calculated energies are very close to the exact energies calculated at the top of the notebook."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "xwrLpY95L8wy"
- },
- "source": [
- "### 3.2 Rodeo Algorithm \n",
- "\n",
- "Another method based on Hamiltonian simulation that can be used to obtain energies is the Rodeo Algorithm. This simulates the Hamiltonian for many random lengths of time with different input energies. The probability of the ancilla qubit being 0 for a given energy $E$ is $P_0(E) = \\frac{1 + e^{-\\sigma^2 (E_i - E)^2/2}}{2}$ where $E_i$ is one of the eigenvalues of the Hamiltonian. The algorithm is outlined in [arXiv:2110.07747](https://arxiv.org/abs/2110.07747). When the energy $E$ is close to an eigenvalue $E_i$, the probability is maximized. Therefore, one would observe peaks in success probability when the input energy $E$ is an eigenvalue. \n",
- "\n",
- "The cell illustrates this process over 10 iterations for each energy, for simplicity. We however show a plot resulting from 1,000 iterations afterwards. To reduce the computational complexity, we also use the [symmetry-conserving Bravyi-Kitaev](https://arXiv.org/abs/1701.08213) mapping to reduce the number of qubits to 2 by remove qubits corresponding to spin and electron number. This means we can only obtain the singlet state energies. A separate calculation would be needed to calculate the triplet energy."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {},
- "outputs": [],
- "source": [
- "# One rodeo cycle as defined in Fig.1 of arXiv.2110.07747\n",
- "def rodeo_cycle(hobj, energy, t, i):\n",
- " circuit = Circuit([Gate(\"H\", i)])\n",
- " circuit += trotterize(hobj, time=t, control=i, trotter_order=2, n_trotter_steps=40)\n",
- " circuit += Circuit([Gate(\"PHASE\", i, parameter=energy*t), Gate(\"H\", i)])\n",
- " return circuit"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {},
- "outputs": [],
- "source": [
- "from tangelo.toolboxes.qubit_mappings.statevector_mapping import do_scbk_transform\n",
- "\n",
- "h_obj = f2q_mapping(mol_Li2.fermionic_hamiltonian, \"scbk\", mol_Li2.n_active_sos,\n",
- " mol_Li2.n_active_electrons, up_then_down=True, spin=mol_Li2.spin)\n",
- "\n",
- "n_qubits = count_qubits(h_obj)\n",
- "\n",
- "# Stretch factor of 300 to make eigenvalue gap larger. Therefore, time evolution needs to be shorter.\n",
- "h_obj = 300*(h_obj - QubitOperator((), -14.85))\n",
- "\n",
- "sim = get_backend()\n",
- "\n",
- "sigma = 0.4\n",
- "\n",
- "# We will use multiple reference states as probability depends on overlap with starting state.\n",
- "ref_states = [vector_to_circuit(do_scbk_transform([1, 1, 0, 0], 4)),\n",
- " vector_to_circuit(do_scbk_transform([1, 0, 1, 0], 4)),\n",
- " vector_to_circuit(do_scbk_transform([0, 0, 1, 1], 4))]\n",
- "\n",
- "# Equivalent to energies from -14.9 -> 14.75 for 10 iterations.\n",
- "energies = [-0.05*300 +300*0.005*i for i in range(30)]\n",
- "success_prob = list()\n",
- "for energy in energies:\n",
- " success=0\n",
- " for sample in range(10):\n",
- " t = np.random.normal(0, sigma, 1)\n",
- " circuit = np.random.choice(ref_states)\n",
- " for i, tk in enumerate(t):\n",
- " circuit += rodeo_cycle(h_obj, energy, tk, i+n_qubits)\n",
- " f, _ = sim.simulate(circuit)\n",
- " for key, v in f.items():\n",
- " if key[2:] == \"0\":\n",
- " success += v\n",
- " success_prob.append(success/10)\n",
- "\n",
- "algorithm_resources[\"rodeo\"] = dict()\n",
- "algorithm_resources[\"rodeo\"][\"qubit_hamiltonian_terms\"] = 0\n",
- "algorithm_resources[\"rodeo\"][\"circuit_2qubit_gates\"] = circuit.counts.get(\"CNOT\", 0)\n",
- "algorithm_resources[\"rodeo\"][\"n_post_terms\"] = 30"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "Text(0, 0.5, 'Success Probability')"
- ]
- },
- "execution_count": 25,
- "metadata": {},
- "output_type": "execute_result"
- },
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- "
"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "fig, ax = plt.subplots()\n",
- "fig.patch.set_facecolor('w')\n",
- "ax.set_facecolor('w')\n",
- "evals = [-14.8696203, -14.83876635, -14.78403833]\n",
- "for e in evals:\n",
- " ax.axvline(x=e, color='r',ls='--')\n",
- "ax.plot(np.array(energies)/300-14.85, success_prob)\n",
- "ax.set_xlabel('Energy (Hartree)')\n",
- "ax.set_ylabel('Success Probability')"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {
- "id": "ZD4RJ1RML8wz"
- },
- "source": [
- "The above plot shows promise that the correct energies indeed align with peaks in the success probability, despite our small number of iterations. To save time, below is the result after running the above code for 1000 iterations. The peaks are centered on the exact energies, represented by the vertical red dashed lines.\n",
- "\n",
- "\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "RUwlEQ-AL8wz"
- },
- "source": [
- "## 4. Closing words \n",
- "\n",
- "We have shown a few of the many different algorithms that can be used to calculate excited states using Tangelo. Unlike ground states, the use of variational methods requires either penalizing against previously calculated states or the optimization of a collection of orthogonal states. Outside of variational methods, we have shown a few Hamiltonian simulation based algorithms to calculate excited states. \n",
- "\n",
- "But quantum resource requirements are an important aspect of quantum algorithm design: let's have a look at the resources required for each algorithm we tried on our use case. In particular, the following metrics:\n",
- "\n",
- "- `# measurements basis` is the number of distinct measurements for each function evaluation in the variational optimization process.\n",
- "- `# CNOT gates` is the number of CNOT gates in each circuit.\n",
- "- `# post measurements basis` is the number of measurements needed to successfully post-process the output of the algorithm. \n",
- "\n",
- "We note that `# CNOT gates` for each variational algorithm could be improved greatly if an algorithm such as ADAPT-VQE was used to create an ansatz. Similarly, `# CNOT gates` could be reduced for the time-evolution algorithms with more advanced approaches such as qubitization."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Algorithm # measurements # CNOT gates # post measurements \n",
- "vqe_ground_state 15 64 0 \n",
- "vqe_triplet_state 15 128 0 \n",
- "vqe_deflation_state_1 16 192 0 \n",
- "vqe_deflation_state_2 17 192 0 \n",
- "vqe_deflation_state_3 18 192 0 \n",
- "quantum_subspace_expansion 18 192 288 \n",
- "sa_vqe 60 128 0 \n",
- "mc_vqe 60 128 540 \n",
- "sa_vqe_deflation 18 192 0 \n",
- "sa_oo_vqe 30 128 0 \n",
- "mrsqk 0 72 16 \n",
- "rodeo 0 320 30 \n"
- ]
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "mOclGIFNL8wf"
+ },
+ "source": [
+ "# Excited States in Tangelo"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8BtSmADsL8wj"
+ },
+ "source": [
+ "## Introduction\n",
+ "\n",
+ "One impactful application of quantum chemistry, in both academia and industry, is the study of the interaction of light with matter. Absorption (resp. emission) of a photon by a molecule can promote (resp. demote) an electron from a lower (resp. higher) electronic state to a higher (resp. lower) energy electronic state. The photon wavelength (i.e. energy) required for these transitions to occur is determined by the difference between the two respective electronic states. Therefore, it is imperative to be able to calculate accurate energies for both ground and excited states to study light/matter interations. These energy differences play a central role in many technologies such as solar panels, light-emitting diodes (LED), displays, and colorants."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZjlMQmjsL8wk"
+ },
+ "source": [
+ "To be more concrete, a colorant must emit light in a narrow region in the visible spectrum to be appropriate for the purpose, that is to say it must exhibit a specific wavelength. Another example is solar panels, where the absorption spectrum of a molecule is tuned via chemical functionalization to fit the solar emission spectrum to optimize the energy output efficiency. Here we show an example of a spectrum for the BODIPY molecule, a molecule widely used for fluorescent dyes. BODIPY absorbs light at a lower wavelength (higher energy) and emits light at a higher wavelength (lower energy). To compute this spectrum, one needs to calculate the ground and excited state energies and calculate their intensities. The absorption spectrum for the simplest BODIPY is shown below. Different absorption and emission wavelengths can be targeted by substituting the hydrogen atoms with different functional groups [J. Chem. Phys. 155, 244102 (2021)](https://aip.scitation.org/doi/10.1063/5.0076787).\n",
+ "\n",
+ "![BODIPY](https://github.com/sandbox-quantum/Tangelo-Examples/blob/main/examples/img/bodipy_absorption.png?raw=1)\n",
+ "\n",
+ "As there are a very large number of compounds to be considered, predicting absorption/emission UV-visible spectra would be a valuable asset to the scientific community.\n",
+ "\n",
+ "To achieve complete understanding of light interaction with a molecule, the quantum chemistry community has worked on several algorithms. In general, one must compute the relevant molecular electronic structures for the prediction of UV light absorption/emission. This notebook shows how Tangelo enables excited states calculations by implementing a few existing quantum algorithms. These are broadly grouped into variational optimization algorithms and algorithms that rely on Hamiltonian simulation. Along the way, we keep track of the quantum computational resources required by each of these approaches, and summarize this information at the end of the notebook. The use case here is Li $_2$ for expediency but many of these quantum algorithms can, in principle, be extended to much larger systems such as the BODIPY molecule above.\n",
+ "\n",
+ "It is worth noting that even with all the computed excited states, non-trivial effects can happen (solvation effect, geometry change, etc.) in which all modify the shape of a spectrum. In this notebook, we do not discuss how these effects are accounted for, but the calculations presented here are the necessary first steps towards computing excited states."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iujthgTEPHjH"
+ },
+ "source": [
+ "## Installation & Background\n",
+ "In order to successfully run this notebook, you need to install Tangelo. It is also important to be somewhat familiar with the variational quantum eigensolver (VQE). Information about VQE can be found in our [VQE with Tangelo](../variational_methods/vqe.ipynb) notebook. Information about each algorithm can be found by following the references linked when each method is introduced. The cell below installs Tangelo in your environment, if it has not been done already."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "QHfbVqHzxPwY",
+ "outputId": "dfb2c373-12a7-41f3-bd41-e3651e45d7f1"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m288.3/288.3 kB\u001b[0m \u001b[31m13.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m26.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m34.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[?25h Building wheel for tangelo-gc (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ " Building wheel for pubchempy (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ "Reading package lists... Done\n",
+ "Building dependency tree... Done\n",
+ "Reading state information... Done\n",
+ "git is already the newest version (1:2.34.1-1ubuntu1.11).\n",
+ "0 upgraded, 0 newly installed, 0 to remove and 49 not upgraded.\n",
+ "Cloning into 'Tangelo-Examples'...\n",
+ "remote: Enumerating objects: 2251, done.\u001b[K\n",
+ "remote: Counting objects: 100% (218/218), done.\u001b[K\n",
+ "remote: Compressing objects: 100% (144/144), done.\u001b[K\n",
+ "remote: Total 2251 (delta 98), reused 76 (delta 71), pack-reused 2033 (from 1)\u001b[K\n",
+ "Receiving objects: 100% (2251/2251), 10.09 MiB | 24.90 MiB/s, done.\n",
+ "Resolving deltas: 100% (1469/1469), done.\n"
+ ]
+ }
+ ],
+ "source": [
+ "try:\n",
+ " import tangelo\n",
+ "except ModuleNotFoundError:\n",
+ " !pip install git+https://github.com/goodchemistryco/Tangelo.git@develop --quiet\n",
+ "\n",
+ "# Download the data folder at https://github.com/goodchemistryco/Tangelo-Examples/tree/main/examples/chemistry/data\n",
+ "import os\n",
+ "if not os.path.isdir(\"data\"):\n",
+ " !sudo apt install git\n",
+ " !git clone https://github.com/sandbox-quantum/Tangelo-Examples.git\n",
+ " !mkdir data\n",
+ " !cp -a Tangelo-Examples/examples/chemistry/data/. ./data/"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "We'll also need to install pycsf, to support basic quantum chemistry features :"
+ ],
+ "metadata": {
+ "id": "KcBCl55KAhvE"
+ }
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "7HwWqzwizb9I",
+ "outputId": "84b58e65-ca05-4206-873c-3fad2fa7f3f0"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Collecting pyscf==2.3.0\n",
+ " Downloading pyscf-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.1 kB)\n",
+ "Requirement already satisfied: numpy!=1.16,!=1.17,>=1.13 in /usr/local/lib/python3.10/dist-packages (from pyscf==2.3.0) (1.26.4)\n",
+ "Requirement already satisfied: scipy!=1.5.0,!=1.5.1 in /usr/local/lib/python3.10/dist-packages (from pyscf==2.3.0) (1.13.1)\n",
+ "Requirement already satisfied: h5py>=2.7 in /usr/local/lib/python3.10/dist-packages (from pyscf==2.3.0) (3.11.0)\n",
+ "Downloading pyscf-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (47.2 MB)\n",
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m47.2/47.2 MB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+ "\u001b[?25hInstalling collected packages: pyscf\n",
+ "Successfully installed pyscf-2.3.0\n"
+ ]
+ }
+ ],
+ "source": [
+ "!pip install --prefer-binary pyscf==2.3.0"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xPrfVi8IL8wl"
+ },
+ "source": [
+ "## Table of Contents\n",
+ "* [1. Obtaining excited state energies classically](#1)\n",
+ "* [2. Variational optimization algorithms](#2)\n",
+ " * [2.1 VQE for lowest singlet and triplet state ](#21)\n",
+ " * [2.2 VQE Deflation](#22)\n",
+ " * [2.3 Quantum Subspace Expansion](#23)\n",
+ " * [2.4 State-Averaged VQE](#24)\n",
+ " * [2.5 Multi-state contracted VQE (MC-VQE)](#25)\n",
+ " * [2.6 State-Averaged VQE with deflation](#26)\n",
+ " * [2.7 State-Averaged Orbital-Optimized VQE](#27)\n",
+ "* [3. Hamiltonian Simulation algorithms](#3)\n",
+ " * [3.1 Multi-Reference Selected Quantum Krylov](#31)\n",
+ " * [3.2 Rodeo Algorithm](#32)\n",
+ "* [4. Closing words](#4)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "knX1VqLsL8wl"
+ },
+ "source": [
+ "The molecular system we use to illustrate a number of excited state algorithms in this notebook is Li $_2$ near its equilibrium geometry. The full calculation of the Li $_2$ energies would be non-trivial and very computationally expensive; we therefore restrict ourselves to an active space of 2 electrons in 2 orbitals which involve 4 qubits when mapped to a qubit Hamiltonian using the Jordan-Wigner mapping. However, there are still non-trivial effects that occur with this small problem, made particularly evident in section [2.7](#27). We define two molecule objects:\n",
+ "\n",
+ "- `mol_li2` defined as the ground state configuration with 2 electrons in the HOMO.\n",
+ "- `mol_li2_t` defined as the triplet configuration with an alpha electron in each of the HOMO and LUMO."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "sZnJKujyxPwZ",
+ "outputId": "a5356826-25ef-4013-9384-250f5819f091"
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.10/dist-packages/pyscf/dft/libxc.py:772: UserWarning: Since PySCF-2.3, B3LYP (and B3P86) are changed to the VWN-RPA variant, the same to the B3LYP functional in Gaussian and ORCA (issue 1480). To restore the VWN5 definition, you can put the setting \"B3LYP_WITH_VWN5 = True\" in pyscf_conf.py\n",
+ " warnings.warn('Since PySCF-2.3, B3LYP (and B3P86) are changed to the VWN-RPA variant, '\n"
+ ]
+ }
+ ],
+ "source": [
+ "from tangelo import SecondQuantizedMolecule as SQMol\n",
+ "li2= \"\"\"Li 0. 0. 0.\n",
+ " Li 3.0 0. 0. \"\"\"\n",
+ "\n",
+ "# 2 electrons in 2 orbitals\n",
+ "fo = [0,1]+[i for i in range(4,28)]\n",
+ "\n",
+ "# Runs RHF calculation\n",
+ "mol_Li2 = SQMol(li2, q=0, spin=0, basis='6-31g(d,p)', frozen_orbitals=fo, symmetry=True)\n",
+ "\n",
+ "# Runs ROHF calculation\n",
+ "mol_Li2_t = SQMol(li2, q=0, spin=2, basis=\"6-31g(d,p)\", frozen_orbitals=fo, symmetry=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "D-72nuJ3L8wn"
+ },
+ "source": [
+ "Since we set `symmetry=True` in the initialization, the symmetry labels of all the\n",
+ "orbitals have been populated in `mol_li2.mo_symm_labels`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "p31n7vJfxPwa",
+ "outputId": "a781ea46-895b-4f7d-90f9-6e1e15629e5a"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " # Energy Symm Occ\n",
+ " 1 -2.4479 A1g 2\n",
+ " 2 -2.4478 A1u 2\n",
+ " 3 -0.1716 A1g 2\n",
+ " 4 0.0129 A1u 0\n",
+ "Number of active electrons: 2\n",
+ "Number of active orbtials: 2\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Symmetry labels and occupations for frozen core and active orbitals\n",
+ "print(\" # Energy Symm Occ\")\n",
+ "for i in range(4):\n",
+ " print(f\"{i+1:3d}{mol_Li2.mo_energies[i]: 9.4f} {mol_Li2.mo_symm_labels[i]} {int(mol_Li2.mo_occ[i])}\")\n",
+ "\n",
+ "# Active electrons, Active orbitals\n",
+ "print(f\"Number of active electrons: {mol_Li2.n_active_electrons}\")\n",
+ "print(f\"Number of active orbtials: {mol_Li2.n_active_mos}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "INDk1VI0L8wo"
+ },
+ "source": [
+ "We can examine the molecular orbitals by exporting them as cube files. These can then be read in by your favourite orbital viewer.\n",
+ "\n",
+ "```python\n",
+ "from pyscf.tools import cubegen\n",
+ "# Output cube files for active orbitals\n",
+ "for i in [2, 3]:\n",
+ " cubegen.orbital(mol_Li2.to_pyscf(basis = mol_Li2.basis), f'li2_{i+1}.cube', mol_Li2.mean_field.mo_coeff[:, i])\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wwUS06EwL8wp"
+ },
+ "source": [
+ "## 1. Obtaining excited state energies classically \n",
+ "\n",
+ "In order to compare the various quantum algorithms, it is useful to have the classically calculated values. Below we will calculate the two A1g and A2g states using PySCF CASCI implementation (https://pyscf.org/user/mcscf.html)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "-KscqbilxPwa",
+ "outputId": "e5b56a6f-afdf-4cc1-adc2-7b1340fb676e"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Calculation for A1g symmetry\n",
+ "\n",
+ "WARN: Mulitple states found in CASCI solver. First state is used to compute the Fock matrix and natural orbitals in active space.\n",
+ "\n",
+ "CASCI state 0 E = -14.8696203628269 E(CI) = -0.575225299756584 S^2 = 0.0000000\n",
+ "CASCI state 1 E = -14.6801962666144 E(CI) = -0.385801203544137 S^2 = 0.0000000\n",
+ "\n",
+ " Calculation for A1u symmetry\n",
+ "\n",
+ "WARN: Mulitple states found in CASCI solver. First state is used to compute the Fock matrix and natural orbitals in active space.\n",
+ "\n",
+ "CASCI state 0 E = -14.8387664606074 E(CI) = -0.544371397537086 S^2 = 2.0000000\n",
+ "CASCI state 1 E = -14.7840380866340 E(CI) = -0.489643023563765 S^2 = 0.0000000\n"
+ ]
+ }
+ ],
+ "source": [
+ "from pyscf import mcscf\n",
+ "\n",
+ "myhf = mol_Li2.mean_field\n",
+ "ncore = {\"A1g\": 1, \"A1u\": 1}\n",
+ "ncas = {\"A1g\": 1, \"A1u\": 1}\n",
+ "\n",
+ "print(\"Calculation for A1g symmetry\")\n",
+ "mc = mcscf.CASCI(myhf, 2, (1, 1))\n",
+ "mo = mc.sort_mo_by_irrep(cas_irrep_nocc=ncas, cas_irrep_ncore=ncore)\n",
+ "mc.fcisolver.wfnsym = \"A1g\"\n",
+ "mc.fcisolver.nroots = 2\n",
+ "emc_A1g = mc.casci(mo)[0]\n",
+ "\n",
+ "print(\"\\n Calculation for A1u symmetry\")\n",
+ "mc = mcscf.CASCI(myhf, 2, (1, 1))\n",
+ "mc.fcisolver.wfnsym = \"A1u\"\n",
+ "mc.fcisolver.nroots = 2\n",
+ "emc_A1u = mc.casci(mo)[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "mE9Dp_XZL8wq"
+ },
+ "source": [
+ "## 2. Variational algorithms\n",
+ "\n",
+ "We start by showing how different approaches based on VQE can be used to obtain excited states. For more information about VQE and the `VQESolver` class, feel free to have a look at our dedicated tutorials."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Y6t3SWGdL8wq"
+ },
+ "source": [
+ "### 2.1 VQE for lowest singlet and triplet states \n",
+ "\n",
+ "Both the lowest singlet (ground state) and lowest triplet (first excited state) can be computed using `VQESolver`. The `FCISolver` class can be used to produce a classically-computed reference value, to get a sense of the accuracy of VQE in this situation. Along the way, we capture the quantum computational resources required for each algorithm in the dictionary `algorithm_resources`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "GzD9VBbzxPwa",
+ "outputId": "6ae173b3-8c27-4494-cbb4-5a78cbb570f4"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ " Ground Singlet state\n",
+ "VQE energy = -14.869620361804333\n",
+ "CASCI energy = -14.869620362826867\n",
+ "\n",
+ " Lowest Triplet state\n",
+ "VQE energy = -14.853462489027093\n",
+ "CASCI energy = -14.853462489027102\n"
+ ]
+ }
+ ],
+ "source": [
+ "from tangelo.algorithms.variational import VQESolver, BuiltInAnsatze\n",
+ "from tangelo.algorithms.classical import FCISolver\n",
+ "\n",
+ "# Dictionary of resources for each algorithm\n",
+ "algorithm_resources = dict()\n",
+ "\n",
+ "# Ground state energy calculation with VQE, reference values with FCI\n",
+ "vqe_options = {\"molecule\": mol_Li2, \"ansatz\": BuiltInAnsatze.UCCSD}\n",
+ "vqe_solver = VQESolver(vqe_options)\n",
+ "vqe_solver.build()\n",
+ "vqe_energy = vqe_solver.simulate()\n",
+ "print(\"\\n Ground Singlet state\")\n",
+ "print(f\"VQE energy = {vqe_energy}\")\n",
+ "print(f\"CASCI energy = {FCISolver(mol_Li2).simulate()}\")\n",
+ "algorithm_resources[\"vqe_ground_state\"] = vqe_solver.get_resources()\n",
+ "\n",
+ "# First excited state energy calculation with VQE, reference values with FCI\n",
+ "vqe_options = {\"molecule\": mol_Li2_t, \"ansatz\": BuiltInAnsatze.UpCCGSD}\n",
+ "vqe_solver_t = VQESolver(vqe_options)\n",
+ "vqe_solver_t.build()\n",
+ "vqe_energy_t = vqe_solver_t.simulate()\n",
+ "print(\"\\n Lowest Triplet state\")\n",
+ "print(f\"VQE energy = {vqe_energy_t}\")\n",
+ "print(f\"CASCI energy = {FCISolver(mol_Li2_t).simulate()}\")\n",
+ "algorithm_resources[\"vqe_triplet_state\"] = vqe_solver_t.get_resources()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iXSSQBsvL8wr"
+ },
+ "source": [
+ "### 2.2 VQE Deflation \n",
+ "\n",
+ "Deflation can be used to gradually obtain higher and higher excited states, by applying an orthogonality penalty against all previous VQE calculations. This idea was introduced in [arXiv:2205.09203](https://arxiv.org/abs/2205.09203).\n",
+ "\n",
+ "This approach can be implented by using the deflation options built in the `VQESolver` class:\n",
+ "\n",
+ "- The keyword `\"deflation_circuits\"` allows the user to provide a list of circuits to use in the deflation process.\n",
+ "- Additionally, the keyword `\"deflation_coeff\"` allows a user to specify the weight in front of the penalty term. This coefficient must be larger than the difference in energy between the ground and the target excited state."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "background_save": true,
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "8XNANL08xPwb",
+ "outputId": "1add933d-26a9-4f6d-b942-8d43b50bbf91"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Excited state #1 \t VQE energy = -14.784036828632091\n",
+ "Excited state #2 \t VQE energy = -14.680196332828123\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Add initial VQE optimal circuit to the deflation circuits list\n",
+ "deflation_circuits = [vqe_solver.optimal_circuit.copy()]\n",
+ "\n",
+ "# Calculate first and second excited states by adding optimal circuits to deflation_circuits\n",
+ "for i in range(2):\n",
+ " vqe_options = {\"molecule\": mol_Li2, \"ansatz\": BuiltInAnsatze.UpCCGSD,\n",
+ " \"deflation_circuits\": deflation_circuits, \"deflation_coeff\": 0.4}\n",
+ " vqe_solver = VQESolver(vqe_options)\n",
+ " vqe_solver.build()\n",
+ " vqe_energy = vqe_solver.simulate()\n",
+ " print(f\"Excited state #{i+1} \\t VQE energy = {vqe_energy}\")\n",
+ " algorithm_resources[f\"vqe_deflation_state_{i+1}\"] = vqe_solver.get_resources()\n",
+ "\n",
+ " deflation_circuits.append(vqe_solver.optimal_circuit.copy())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gZVPYZHGL8wr"
+ },
+ "source": [
+ "The deflation above generated the singlet states. Sometimes it is useful to use a different reference state. In the next example of deflation, we use a reference state with 2 alpha electrons and 0 beta electrons to calculate the triplet state. The reference state is defined by alternating up then down ordering, which yields `{\"ref_state\": [1, 0, 1, 0]}` for 2 alpha electrons in 2 orbitals for this situation."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "GUnTIo8HxPwb",
+ "outputId": "82c4f3bf-bfdb-40ba-f56f-a1ba74bb6ac0"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "VQE energy = -14.838766460607367\n"
+ ]
+ }
+ ],
+ "source": [
+ "vqe_options = {\"molecule\": mol_Li2, \"ansatz\": BuiltInAnsatze.UpCCGSD,\n",
+ " \"deflation_circuits\": deflation_circuits,\n",
+ " \"deflation_coeff\": 0.4, \"ref_state\": [1, 0, 1, 0]}\n",
+ "vqe_solver_triplet = VQESolver(vqe_options)\n",
+ "vqe_solver_triplet.build()\n",
+ "vqe_energy = vqe_solver_triplet.simulate()\n",
+ "print(f\"VQE energy = {vqe_energy}\")\n",
+ "algorithm_resources[f\"vqe_deflation_state_{3}\"] = vqe_solver_triplet.get_resources()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_odsQd-dL8ws"
+ },
+ "source": [
+ "This value is a great match for the triplet CASCI reference values we obtained earlier. We calculated all the excited states calculated using CASCI using deflation by running `VQESolver` 4 times.\n",
+ "\n",
+ "The `deflation_circuits` option is also available for the SA-VQE solver shown in another section of this notebook (`SA_VQESolver`), as well as ADAPT (`ADAPTSolver`)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uTRtGu2XL8ws"
+ },
+ "source": [
+ "### 2.3 Quantum Subspace Expansion \n",
+ "\n",
+ "Another way to obtain excited states is to define a pool of operators providing a good approximation to the excitations needed to represent the excited states from the ground state calculations produced by `VQESolver`. This idea was presented in [arXiv:1603.05681](https://arxiv.org/abs/1603.05681).\n",
+ "\n",
+ "For this example, we choose a pool of operators of the form $O_p=a_i^{\\dagger}a_j$.\n",
+ "\n",
+ "We then have to solve $FU = SUE$, where $F_{pq}=\\left<\\psi\\right|O_p^* H O_q\\left|\\psi\\right>$ and $S_{pq}=\\left<\\psi\\right|O_p^* O_q\\left|\\psi\\right>$.\n",
+ "\n",
+ "For simplicity here, we keep all wavefunction symmetry excitations. However, the matrix we need to diagonalize can be made smaller by only keeping excitations that respect the desired wavefunction symmetry of the excited state."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "oMEMRT1TxPwb"
+ },
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "from scipy.linalg import eigh\n",
+ "from openfermion.utils import hermitian_conjugated as hc\n",
+ "\n",
+ "from tangelo.toolboxes.operators import FermionOperator\n",
+ "from tangelo.toolboxes.qubit_mappings.mapping_transform import fermion_to_qubit_mapping as f2q_mapping\n",
+ "\n",
+ "# Generate all single excitations as qubit operators\n",
+ "op_list = list()\n",
+ "for i in range(2):\n",
+ " for j in range(i+1, 2):\n",
+ " op_list += [f2q_mapping(FermionOperator(((2*i, 1), (2*j, 0))), \"jw\")] #spin-up transition\n",
+ " op_list += [f2q_mapping(FermionOperator(((2*i+1, 1), (2*j+1, 0))), \"jw\")] #spin-down transition\n",
+ " op_list += [f2q_mapping(FermionOperator(((2*i+1, 1), (2*j, 0))), \"jw\")] #spin-up to spin-down\n",
+ " op_list += [f2q_mapping(FermionOperator(((2*i, 1), (2*j+1, 0))), \"jw\")] #spin-down to spin-up\n",
+ "\n",
+ "# Compute F and S matrices.\n",
+ "size_mat = len(op_list)\n",
+ "h = np.zeros((size_mat, size_mat))\n",
+ "s = np.zeros((size_mat, size_mat))\n",
+ "state_circuit = vqe_solver.optimal_circuit\n",
+ "for i, op1 in enumerate(op_list):\n",
+ " for j, op2 in enumerate(op_list):\n",
+ " h[i, j] = np.real(vqe_solver.backend.get_expectation_value(hc(op1)*vqe_solver.qubit_hamiltonian*op2, state_circuit))\n",
+ " s[i, j] = np.real(vqe_solver.backend.get_expectation_value(hc(op1)*op2, state_circuit))\n",
+ "\n",
+ "label = \"quantum_subspace_expansion\"\n",
+ "algorithm_resources[label] = vqe_solver.get_resources()\n",
+ "algorithm_resources[label][\"n_post_terms\"] = len(op_list)**2*algorithm_resources[label][\"qubit_hamiltonian_terms\"]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MrS38WBO2DBF"
+ },
+ "source": [
+ "After generating the matrices on the quantum computer. We need to perform the classical post-processing to obtain the energies by solving the $FU = SUE$ eigenvalue problem."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "DCQggLfFxPwb",
+ "outputId": "4512038b-4bc7-418a-d996-f9fd72f7addc"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Quantum Subspace Expansion energies: \n",
+ " [-14.83876646 -14.83876646 -14.83876646 -14.78403816]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Solve FU = SUE\n",
+ "e, v = eigh(h,s)\n",
+ "print(f\"Quantum Subspace Expansion energies: \\n {e}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YCqaM-2SL8ws"
+ },
+ "source": [
+ "We can see that we have obtained the correct energies for CASCI state A1g state 1, and A2 state 0 and 1. A1g state 1 was not recovered. We would therefore need to measure more excitations in $F$."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SLJrouJXL8wt"
+ },
+ "source": [
+ "### 2.4 State-Averaged VQE \n",
+ "\n",
+ "Another method to obtain excited states is to use the State-Averaged VQE Solver (SA-VQE). SA-VQE minimizes the average energy of multiple orthogonal reference states using the same ansatz circuit. As the reference states are orthogonal, using the same circuit transformation (a unitary), results in final states that are also orthogonal. This idea can be found in [arXiv:2009.11417](https://arxiv.org/pdf/2009.11417.pdf).\n",
+ "\n",
+ "Here, we target singlet states only. This can be accomplished by adding a penalty term with `\"penalty_terms\": {\"S^2\": [2, 0]}`. This means that the target Hamiltonian to be minimized is $H = H_0 + 2 (\\hat{S}^2 - 0)^2$, where $H_0$ is the original molecular Hamiltonian."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "dBxaLp3sxPwb",
+ "outputId": "44b5e891-eb1d-4a06-90ef-65fb8961ce1a"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Singlet State 0 has energy -14.742180662780802\n",
+ "Singlet State 1 has energy -14.812125758504438\n",
+ "Singlet State 2 has energy -14.779540078255247\n"
+ ]
+ }
+ ],
+ "source": [
+ "from tangelo.algorithms.variational import SA_VQESolver\n",
+ "\n",
+ "vqe_options = {\"molecule\": mol_Li2, \"ref_states\": [[1,1,0,0], [1,0,0,1], [0,0,1,1]],\n",
+ " \"weights\": [1, 1, 1], \"penalty_terms\": {\"S^2\": [2, 0]},\n",
+ " \"qubit_mapping\": \"jw\", \"ansatz\": BuiltInAnsatze.UpCCGSD,\n",
+ " }\n",
+ "vqe_solver = SA_VQESolver(vqe_options)\n",
+ "vqe_solver.build()\n",
+ "enernew = vqe_solver.simulate()\n",
+ "for i, energy in enumerate(vqe_solver.state_energies):\n",
+ " print(f\"Singlet State {i} has energy {energy}\")\n",
+ "\n",
+ "algorithm_resources[\"sa_vqe\"] = vqe_solver.get_resources()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kpLLy2N2L8wt"
+ },
+ "source": [
+ "The energies above are inaccurate, as the calculated states are restricted to linear combinations of the three lowest singlet states. We can use MC-VQE to generate the exact eigenvectors, as shown in the next section.\n",
+ "\n",
+ "However, the cell below shows the $\\hat{S}^2$ expectation value is nearly zero for all states, so they are all singlet as expected when using the penalty term."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "wKI5LzTPxPwb",
+ "outputId": "6369ac62-b2f6-4679-b35d-fa386246c0f8"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "State 0 has S^2 = 3.5292665678809954e-08\n",
+ "State 1 has S^2 = 2.0223931609386625e-06\n",
+ "State 2 has S^2 = 7.838162452422637e-09\n"
+ ]
+ }
+ ],
+ "source": [
+ "from tangelo.toolboxes.ansatz_generator.fermionic_operators import spin2_operator\n",
+ "\n",
+ "s2op = f2q_mapping(spin2_operator(2), \"jw\")\n",
+ "for i in range(3):\n",
+ " print(f\"State {i} has S^2 = {vqe_solver.backend.get_expectation_value(s2op, vqe_solver.reference_circuits[i]+vqe_solver.optimal_circuit)}\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "G6afws2QL8wt"
+ },
+ "source": [
+ "### 2.5 Multistate, contracted VQE (MC-VQE) \n",
+ "\n",
+ "To obtain the energies of the individual states, we can use multistate contracted VQE (MC-VQE), as introduced in [arXiv:1901.01234](https://arxiv.org/abs/1901.01234). This process defines a small matrix by measuring the Hamiltonian expectation values of $(\\left|\\theta_i\\right>+\\left|\\theta_j\\right>)/\\sqrt{2}$ and $(\\left|\\theta_i\\right>-\\left|\\theta_j\\right>)/\\sqrt{2}$ for all combinations of our final states ($\\left|\\theta_i\\right>$) resulting from the SA-VQE procedure.\n",
+ "\n",
+ "In general, the reference states are simple occupations so generating $(\\left|\\theta_i\\right>+\\left|\\theta_j\\right>)/\\sqrt{2}$ and $(\\left|\\theta_i\\right>-\\left|\\theta_j\\right>)/\\sqrt{2}$ by hand should be \"fairly straightforward\". In this notebook, we use Tangelo to obtain these statevectors and then generate the expectation values."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "nKUl43KZxPwb"
+ },
+ "outputs": [],
+ "source": [
+ "# Generate individual statevectors\n",
+ "ref_svs = list()\n",
+ "for circuit in vqe_solver.reference_circuits:\n",
+ " _, sv = vqe_solver.backend.simulate(circuit, return_statevector=True)\n",
+ " ref_svs.append(sv)\n",
+ "\n",
+ "# Generate Equation (2) using equation (4) and (5) of arXiv:1901.01234\n",
+ "h_theta_theta = np.zeros((3,3))\n",
+ "for i, sv1 in enumerate(ref_svs):\n",
+ " for j, sv2 in enumerate(ref_svs):\n",
+ " if i != j:\n",
+ " sv_plus = (sv1 + sv2)/np.sqrt(2)\n",
+ " sv_minus = (sv1 - sv2)/np.sqrt(2)\n",
+ " exp_plus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, vqe_solver.optimal_circuit, initial_statevector=sv_plus)\n",
+ " exp_minus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, vqe_solver.optimal_circuit, initial_statevector=sv_minus)\n",
+ " h_theta_theta[i, j] = (exp_plus-exp_minus)/2\n",
+ " else:\n",
+ " h_theta_theta[i, j] = vqe_solver.state_energies[i]\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "10myRMdfHJoJ"
+ },
+ "source": [
+ "Accurate energies can be recovered by solving the resulting eigenproblem classically:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "q1po_RIxxPwc",
+ "outputId": "09041799-e45d-4251-ab7d-b6c8e33d9c1c"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Singlet State 0 \t MC-VQE energy = -14.869616874285468\n",
+ "Singlet State 1 \t MC-VQE energy = -14.784034425090708\n",
+ "Singlet State 2 \t MC-VQE energy = -14.680195200164317\n"
+ ]
+ }
+ ],
+ "source": [
+ "e, _ = np.linalg.eigh(h_theta_theta)\n",
+ "for i, energy in enumerate(e):\n",
+ " print(f\"Singlet State {i} \\t MC-VQE energy = {energy}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JtJADlmZL8wu"
+ },
+ "source": [
+ "We can see that these singlet energies are all close to the exact answer."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IrcmQn8cL8wu"
+ },
+ "source": [
+ "#### Using StateVector for MC-VQE\n",
+ "The code below can be used obtain the same MC-VQE result by using `StateVector` to automatically generate circuits for $(\\left|\\theta_i\\right>+\\left|\\theta_j\\right>)/\\sqrt{2}$ and $(\\left|\\theta_i\\right>-\\left|\\theta_j\\right>)/\\sqrt{2}$. However, the circuits created by StateVector are generally inefficient and one should try to create the circuits that generate these states by hand if running on a real quantum device."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "Tqc7a0dmxPwc"
+ },
+ "outputs": [],
+ "source": [
+ "from tangelo.linq.helpers import StateVector\n",
+ "\n",
+ "# Generate individual statevectors\n",
+ "ref_svs = list()\n",
+ "for state in vqe_solver.ref_states:\n",
+ " sv = np.zeros(2**4)\n",
+ " # Generate bitstring representation of each ref_state and populate that position in the statevector\n",
+ " bitstring = \"\".join([str(i) for i in reversed(state)])\n",
+ " sv[int(bitstring, base=2)] = 1\n",
+ " ref_svs.append(sv)\n",
+ "\n",
+ "# Generate Equation (2) using equation (4) and (5) of arXiv:1901.01234\n",
+ "h_theta_theta = np.zeros((len(ref_svs), len(ref_svs)))\n",
+ "for i, sv1 in enumerate(ref_svs):\n",
+ " for j, sv2 in enumerate(ref_svs):\n",
+ " if i != j:\n",
+ " sv_plus = (sv1 + sv2)/np.sqrt(2)\n",
+ " sv_plus = StateVector(sv_plus)\n",
+ " ref_circ_plus = sv_plus.initializing_circuit()\n",
+ " exp_plus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, ref_circ_plus + vqe_solver.optimal_circuit)\n",
+ "\n",
+ " sv_minus = (sv1 - sv2)/np.sqrt(2)\n",
+ " sv_minus = StateVector(sv_minus)\n",
+ " ref_circ_minus = sv_minus.initializing_circuit()\n",
+ " exp_minus = vqe_solver.backend.get_expectation_value(vqe_solver.qubit_hamiltonian, ref_circ_minus + vqe_solver.optimal_circuit)\n",
+ "\n",
+ " h_theta_theta[i, j] = (exp_plus-exp_minus)/2\n",
+ " else:\n",
+ " h_theta_theta[i, j] = vqe_solver.state_energies[i]\n",
+ "\n",
+ "algorithm_resources[\"mc_vqe\"] = vqe_solver.get_resources()\n",
+ "algorithm_resources[\"mc_vqe\"][\"n_post_terms\"] = len(ref_svs)**2*algorithm_resources[\"mc_vqe\"][\"qubit_hamiltonian_terms\"]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "S_TP1ww5xPwc",
+ "outputId": "4f3b4973-d48d-4124-c912-9ea0492c6185"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Singlet State 0 \t MC-VQE energy = -14.869616874285464\n",
+ "Singlet State 1 \t MC-VQE energy = -14.784034425090713\n",
+ "Singlet State 2 \t MC-VQE energy = -14.680195200164313\n"
+ ]
+ }
+ ],
+ "source": [
+ "e, _ = np.linalg.eigh(h_theta_theta)\n",
+ "for i, energy in enumerate(e):\n",
+ " print(f\"Singlet State {i} \\t MC-VQE energy = {energy}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "p6odrzVoL8wv"
+ },
+ "source": [
+ "### 2.6 State-Averaged VQE with deflation \n",
+ "We can obtain the final excited state by using deflation for the three singlet states above and removing the penalty term. We define a reference state with `\"ref_states\": [[1, 0, 1, 0]]` that better targets the remaining triplet state. We can revert back to the UCCSD ansatz for this state as we do not need as expressive an ansatz anymore."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "RnZ1_QYFxPwf",
+ "outputId": "e684c58c-2303-4c0d-d58c-e3322d4e79ec"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Triplet State 0 has energy -14.838766460607367\n"
+ ]
+ }
+ ],
+ "source": [
+ "vqe_options = {\"molecule\": mol_Li2, \"ref_states\": [[1, 0, 1, 0]],\n",
+ " \"weights\": [1], \"deflation_circuits\": [vqe_solver.reference_circuits[i]+vqe_solver.optimal_circuit for i in range(3)],\n",
+ " \"qubit_mapping\": \"jw\", \"ansatz\": BuiltInAnsatze.UCCSD,\n",
+ " }\n",
+ "vqe_solver_deflate = SA_VQESolver(vqe_options)\n",
+ "vqe_solver_deflate.build()\n",
+ "enernew = vqe_solver_deflate.simulate()\n",
+ "\n",
+ "for i, energy in enumerate(vqe_solver_deflate.state_energies):\n",
+ " print(f\"Triplet State {i} has energy {energy}\")\n",
+ "\n",
+ "algorithm_resources[f\"sa_vqe_deflation\"] = vqe_solver_deflate.get_resources()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JrU59nB3L8wv"
+ },
+ "source": [
+ "This is the correct triplet state energy."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FNeQXqbIL8wv"
+ },
+ "source": [
+ "### 2.7 State-Averaged Orbital-Optimized VQE \n",
+ "\n",
+ "This performs the equivalent of a CASSCF calculation using a quantum computer. This approach runs multiple iterations comprised of the two following steps:\n",
+ "\n",
+ "- SA-VQE calculation\n",
+ "- orbital optimization\n",
+ "\n",
+ "These iterations are called by using the `iterate()` call. The `simulate()` method from `SA_OO_Solver` only performs a State-Averated VQE simulation. The reference for this method is [arXiv:2009.11417](https://arxiv.org/pdf/2009.11417.pdf)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "N7W6Iv99xPwf",
+ "outputId": "e7839591-ce72-42d0-9231-4b5febaaf0d6"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "State 0 has energy -14.875599348504345\n",
+ "State 1 has energy -14.851789148206684\n"
+ ]
+ }
+ ],
+ "source": [
+ "from tangelo.algorithms.variational import SA_OO_Solver\n",
+ "\n",
+ "mol_Li2_nosym = SQMol(li2, q=0, spin=0, basis='6-31g(d,p)',\n",
+ " frozen_orbitals=fo, symmetry=False)\n",
+ "vqe_options = {\"molecule\": mol_Li2_nosym, \"ref_states\": [[1,1,0,0], [1,0,1,0]],\n",
+ " \"weights\": [1, 1],\n",
+ " \"qubit_mapping\": \"jw\", \"ansatz\": BuiltInAnsatze.UpCCGSD, \"ansatz_options\": {\"k\": 2}\n",
+ " }\n",
+ "vqe_solver = SA_OO_Solver(vqe_options)\n",
+ "vqe_solver.build()\n",
+ "enernew = vqe_solver.iterate()\n",
+ "for i, energy in enumerate(vqe_solver.state_energies):\n",
+ " print(f\"State {i} has energy {energy}\")\n",
+ "\n",
+ "algorithm_resources[\"sa_oo_vqe\"] = vqe_solver.get_resources()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PD3cQc1GL8ww"
+ },
+ "source": [
+ "Comparing the `SA_OO_VQE` solution to CASSCF calculations from a library such as pyscf shows similar results."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "6uwKJ2vJxPwf",
+ "outputId": "b864fe1b-0804-4a2b-eefd-d350f41afb8f"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CASSCF energy = -14.8636942982907\n",
+ "CASCI E = -14.8636942982907 E(CI) = -0.569133524430852 S^2 = 1.0000000\n",
+ "CASCI state-averaged energy = -14.8636942982907\n",
+ "CASCI energy for each state\n",
+ " State 0 weight 0.5 E = -14.8756048777217 S^2 = 0.0000000\n",
+ " State 1 weight 0.5 E = -14.8517837188597 S^2 = 2.0000000\n"
+ ]
+ }
+ ],
+ "source": [
+ "mol_Li2_no_sym_copy = SQMol(li2, q=0, spin=0, basis='6-31g(d,p)',\n",
+ " frozen_orbitals=fo, symmetry=False)\n",
+ "mc = mcscf.CASSCF(mol_Li2_no_sym_copy.mean_field, 2, 2).state_average([0.5, 0.5])\n",
+ "energy = mc.kernel()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "N7ZIjE-ML8ww"
+ },
+ "source": [
+ "`SA_OO_Solver` has optimized the orbitals in `mol_Li2_nosym` to minimize the average energy of the states above. We can then use the code below to output the optimized molecular orbitals as cube files and compare to the unoptimized orbitals from the top of the notebook.\n",
+ "\n",
+ "```python\n",
+ "from pyscf.tools import cubegen\n",
+ "# loop over active orbitals i.e. 2, 3\n",
+ "for i in [2, 3]:\n",
+ " cubegen.orbital(mol_Li2_nosym.to_pyscf(basis = mol_Li2_nosym.basis), f'li2_{i+1}_opt.cube', mol_Li2_nosym.mean_field.mo_coeff[:, i])\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_uXgf8A7L8ww"
+ },
+ "source": [
+ "Using [Avogadro](https://avogadro.cc/) to generate the two figures below with the .cube files outputted above, we see that the original fourth molecular orbital and the optimized fourth molecular orbital look very different:\n",
+ "\n",
+ "