From 7a8c3b1d0ee05bccf13f48c38be4d587432c0997 Mon Sep 17 00:00:00 2001 From: Auguste Hirth Date: Thu, 19 May 2022 21:40:01 -0700 Subject: [PATCH 1/4] Move OpenFermion tutorial from Cirq --- docs/tutorials/chemistry.ipynb | 2251 ++++++++++++++++++++++++++++++++ 1 file changed, 2251 insertions(+) create mode 100644 docs/tutorials/chemistry.ipynb diff --git a/docs/tutorials/chemistry.ipynb b/docs/tutorials/chemistry.ipynb new file mode 100644 index 000000000..1045db104 --- /dev/null +++ b/docs/tutorials/chemistry.ipynb @@ -0,0 +1,2251 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "cedf868076a2" + }, + "source": [ + "##### Copyright 2020 The Cirq Developers" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "cellView": "form", + "id": "906e07f6e562" + }, + "outputs": [], + "source": [ + "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bf6694967996" + }, + "source": [ + "# Quantum simulation of electronic structure" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d96dfab4145b" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " View on QuantumAI\n", + " \n", + " Run in Google Colab\n", + " \n", + " View source on GitHub\n", + " \n", + " Download notebook\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c3dd9da6211f" + }, + "source": [ + "The quantum simulation of electronic structure is one of the most promising applications of quantum computers. It has potential applications to materials and drug design. This tutorial provides an introduction to OpenFermion, a library for obtaining and manipulating representations of fermionic and qubit Hamiltonians as well as compiling quantum simulation circuits in Cirq." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "zeDOA0lc6YyI" + }, + "outputs": [], + "source": [ + "try:\n", + " import openfermion as of\n", + " import openfermionpyscf as ofpyscf\n", + "except ImportError:\n", + " print(\"Installing OpenFermion and OpenFermion-PySCF...\")\n", + " !pip install openfermion openfermionpyscf --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "d1ed5395e9f5" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "from scipy.sparse import linalg\n", + "\n", + "import cirq\n", + "import openfermion as of\n", + "import openfermionpyscf as ofpyscf" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GzfsOoPI5sHP" + }, + "source": [ + "## Background\n", + "\n", + "A system of $N$ fermionic modes is\n", + "described by a set of fermionic *annihilation operators*\n", + "$\\{a_p\\}_{p=0}^{N-1}$ satisfying the *canonical anticommutation relations*\n", + "$$\\begin{aligned}\n", + " \\{a_p, a_q\\} &= 0, \\\\\n", + " \\{a_p, a^\\dagger_q\\} &= \\delta_{pq},\n", + " \\end{aligned}$$ where $\\{A, B\\} := AB + BA$. The adjoint\n", + "$a^\\dagger_p$ of an annihilation operator $a_p$ is called a *creation\n", + "operator*, and we refer to creation and annihilation operators as\n", + "fermionic *ladder operators*.\n", + " \n", + "The canonical anticommutation relations impose a number of consequences on the structure of the vector space on which the ladder operators act; see [Michael Nielsen's notes](http://michaelnielsen.org/blog/archive/notes/fermions_and_jordan_wigner.pdf) for a good discussion.\n", + "\n", + "The electronic structure Hamiltonian is commonly written in the form\n", + "$$\n", + "\\sum_{pq} T_{pq} a_p^\\dagger a_q + \\sum_{pqrs} V_{pqrs} a_p^\\dagger a_q^\\dagger a_r a_s\n", + "$$\n", + "where the $T_{pq}$ and $V_{pqrs}$ are coefficients which depend on the physical system being described. We are interested in calculating the lowest eigenvalue of the Hamiltonian. This eigenvalue is also called the ground state energy.\n", + "\n", + "\n", + "## FermionOperator and QubitOperator\n", + "\n", + "### `openfermion.FermionOperator`\n", + "\n", + "- Stores a weighted sum (linear combination) of fermionic terms\n", + "- A fermionic term is a product of ladder operators\n", + "- Examples of things that can be represented by `FermionOperator`:\n", + "$$\n", + "\\begin{align}\n", + "& a_1 \\nonumber \\\\\n", + "& 1.7 a^\\dagger_3 \\nonumber \\\\\n", + "&-1.7 \\, a^\\dagger_3 a_1 \\nonumber \\\\\n", + "&(1 + 2i) \\, a^\\dagger_4 a^\\dagger_3 a_9 a_1 \\nonumber \\\\\n", + "&(1 + 2i) \\, a^\\dagger_4 a^\\dagger_3 a_9 a_1 - 1.7 \\, a^\\dagger_3 a_1 \\nonumber\n", + "\\end{align}\n", + "$$\n", + "\n", + "- A fermionic term is internally represented as a tuple of tuples\n", + "- Each inner tuple represents a single ladder operator as (index, action)\n", + "- Examples of fermionic terms:\n", + "$$\n", + "\\begin{align}\n", + "I & \\mapsto () \\nonumber \\\\\n", + "a_1 & \\mapsto ((1, 0),) \\nonumber \\\\\n", + "a^\\dagger_3 & \\mapsto ((3, 1),) \\nonumber \\\\\n", + "a^\\dagger_3 a_1 & \\mapsto ((3, 1), (1, 0)) \\nonumber \\\\\n", + "a^\\dagger_4 a^\\dagger_3 a_9 a_1 & \\mapsto ((4, 1), (3, 1), (9, 0), (1, 0)) \\nonumber\n", + "\\end{align}\n", + "$$\n", + "\n", + "- `FermionOperator` is a sum of terms, represented as a dictionary from term to coefficient" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "u1J3mO4r5sHR" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{((4, 1), (3, 1), (9, 0), (1, 0)): (1+2j), ((3, 1), (1, 0)): -1.7}\n" + ] + } + ], + "source": [ + "op = of.FermionOperator(((4, 1), (3, 1), (9, 0), (1, 0)), 1+2j) + of.FermionOperator(((3, 1), (1, 0)), -1.7)\n", + "\n", + "print(op.terms)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6gMYqNFi5sHV" + }, + "source": [ + "Alternative notation, useful when playing around:\n", + "\n", + "$$\n", + "\\begin{align}\n", + "I & \\mapsto \\textrm{\"\"} \\nonumber \\\\\n", + "a_1 & \\mapsto \\textrm{\"1\"} \\nonumber \\\\\n", + "a^\\dagger_3 & \\mapsto \\textrm{\"3^\"} \\nonumber \\\\\n", + "a^\\dagger_3 a_1 & \\mapsto \\textrm{\"3^}\\;\\textrm{1\"} \\nonumber \\\\\n", + "a^\\dagger_4 a^\\dagger_3 a_9 a_1 & \\mapsto \\textrm{\"4^}\\;\\textrm{3^}\\;\\textrm{9}\\;\\textrm{1\"} \\nonumber\n", + "\\end{align}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "w55QckU25sHW" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{((4, 1), (3, 1), (9, 0), (1, 0)): (1+2j), ((3, 1), (1, 0)): -1.7}\n" + ] + } + ], + "source": [ + "op = of.FermionOperator('4^ 3^ 9 1', 1+2j) + of.FermionOperator('3^ 1', -1.7)\n", + "\n", + "print(op.terms)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hRrwfjR55sHZ" + }, + "source": [ + "Just print the operator for a nice readable representation:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "VYnPilSU5sHa" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-1.7 [3^ 1] +\n", + "(1+2j) [4^ 3^ 9 1]\n" + ] + } + ], + "source": [ + "print(op)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vvZxYedI5sHw" + }, + "source": [ + "### `openfermion.QubitOperator`\n", + "\n", + "Same as `FermionOperator`, but the possible actions are 'X', 'Y', and 'Z' instead of 1 and 0." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "79UFeqFz5sHw" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.0 [X1 Y2 Z3] +\n", + "3.0 [X3 Z4]\n" + ] + } + ], + "source": [ + "op = of.QubitOperator(((1, 'X'), (2, 'Y'), (3, 'Z')))\n", + "op += of.QubitOperator('X3 Z4', 3.0)\n", + "\n", + "print(op)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v_PQSbeB5sH1" + }, + "source": [ + "`FermionOperator` and `QubitOperator` actually inherit from the same parent class: `openfermion.SymbolicOperator`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AE28NBCu5sH5" + }, + "source": [ + "## The Jordan-Wigner and Bravyi-Kitaev transforms\n", + "\n", + "A fermionic transform maps `FermionOperator`s to `QubitOperator`s in a way that preserves the canonical anticommutation relations. The most basic transforms are the Jordan-Wigner transform (JWT) and Bravyi-Kitaev transform (BKT). Note that the BKT requires the total number of qubits to be predetermined. Whenever a fermionic transform is being applied implicitly, it is the JWT." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "Cum2qpwA5sH6" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0.25+0j) [X2 Z3 Z4 Z5 Z6 Z7 Z8 Z9 Z10 Z11 Z12 Z13 Z14 X15] +\n", + "0.25j [X2 Z3 Z4 Z5 Z6 Z7 Z8 Z9 Z10 Z11 Z12 Z13 Z14 Y15] +\n", + "-0.25j [Y2 Z3 Z4 Z5 Z6 Z7 Z8 Z9 Z10 Z11 Z12 Z13 Z14 X15] +\n", + "(0.25+0j) [Y2 Z3 Z4 Z5 Z6 Z7 Z8 Z9 Z10 Z11 Z12 Z13 Z14 Y15]\n", + "\n", + "(-0.25+0j) [Z1 X2 X3 X7 Z15] +\n", + "-0.25j [Z1 X2 X3 Y7 Z11 Z13 Z14] +\n", + "0.25j [Z1 Y2 X3 X7 Z15] +\n", + "(-0.25+0j) [Z1 Y2 X3 Y7 Z11 Z13 Z14]\n" + ] + } + ], + "source": [ + "op = of.FermionOperator('2^ 15')\n", + "\n", + "print(of.jordan_wigner(op))\n", + "print()\n", + "print(of.bravyi_kitaev(op, n_qubits=16))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9T6yt_Nu5sH_" + }, + "source": [ + "### Exercise\n", + "\n", + "Below are some examples of how `FermionOperator`s are mapped to `QubitOperator`s by the Jordan-Wigner transform (the notation 'h.c.' stands for 'hermitian conjugate'):\n", + "$$\n", + "\\begin{align*}\n", + " a_p^\\dagger &\\mapsto \\frac12 (X_p - i Y_p) Z_0 \\cdots Z_{p-1}\\\\\n", + " a_p^\\dagger a_p &\\mapsto \\frac12 (I - Z_p)\\\\\n", + " (\\beta a_p^\\dagger a_q + \\text{h.c.}) &\\mapsto \\frac12 [\\text{Re}(\\beta) (X_p ZZ \\cdots ZZ X_q + Y_p ZZ \\cdots ZZ Y_q) + \\text{Im}(\\beta) (Y_p ZZ \\cdots ZZ X_q - X_p ZZ \\cdots ZZ Y_q)]\n", + "\\end{align*}\n", + "$$\n", + "Verify these mappings for $p=2$ and $q=7$. The `openfermion.hermitian_conjugated` function may be useful here." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "o1bOGrkvUHVq" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.5 [Z0 Z1 X2] +\n", + "0.5j [Z0 Z1 Y2]\n", + "\n", + "(0.5+0j) [] +\n", + "(-0.5+0j) [Z2]\n", + "\n", + "(0.5+0j) [X2 Z3 Z4 Z5 Z6 X7] +\n", + "(-1+0j) [X2 Z3 Z4 Z5 Z6 Y7] +\n", + "(1+0j) [Y2 Z3 Z4 Z5 Z6 X7] +\n", + "(0.5+0j) [Y2 Z3 Z4 Z5 Z6 Y7]\n" + ] + } + ], + "source": [ + "a2 = of.FermionOperator('2')\n", + "print(of.jordan_wigner(a2))\n", + "print()\n", + "\n", + "a2dag = of.FermionOperator('2^')\n", + "print(of.jordan_wigner(a2dag*a2))\n", + "print()\n", + "\n", + "a7 = of.FermionOperator('7')\n", + "a7dag = of.FermionOperator('7^')\n", + "print(of.jordan_wigner((1+2j)*(a2dag*a7) + (1-2j)*(a7dag*a2)))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gSwBGl9UUy1k" + }, + "source": [ + "### Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "id": "xwDvR6Ol5sIA" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.5 [Z0 Z1 X2] +\n", + "-0.5j [Z0 Z1 Y2]\n", + "\n", + "(0.5+0j) [] +\n", + "(-0.5+0j) [Z2]\n", + "\n", + "(1+0j) [X2 Z3 Z4 Z5 Z6 X7] +\n", + "(-1.5+0j) [X2 Z3 Z4 Z5 Z6 Y7] +\n", + "(1.5+0j) [Y2 Z3 Z4 Z5 Z6 X7] +\n", + "(1+0j) [Y2 Z3 Z4 Z5 Z6 Y7]\n" + ] + } + ], + "source": [ + "a2 = of.FermionOperator('2')\n", + "a2dag = of.FermionOperator('2^')\n", + "a7 = of.FermionOperator('7')\n", + "a7dag = of.FermionOperator('7^')\n", + "\n", + "print(of.jordan_wigner(a2dag))\n", + "print()\n", + "print(of.jordan_wigner(a2dag*a2))\n", + "print()\n", + "\n", + "op = (2+3j)*a2dag*a7\n", + "op += of.hermitian_conjugated(op)\n", + "print(of.jordan_wigner(op))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j2BmxWOu5sIC" + }, + "source": [ + "### Exercise\n", + "\n", + "Use the `+` and `*` operators to verify that after applying the JWT to ladder operators, the resulting `QubitOperator`s satisfy\n", + "$$\n", + "\\begin{align}\n", + " a_2 a_7 + a_7 a_2 &= 0 \\\\\n", + " a_2 a_7^\\dagger + a_7^\\dagger a_2 &= 0\\\\\n", + " a_2 a_2^\\dagger + a_2^\\dagger a_2 &= 1\n", + "\\end{align}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VsJlMb_GVU1Y" + }, + "source": [ + "### Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "id": "yzwsrS1O5sID" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "0\n", + "(1+0j) []\n" + ] + } + ], + "source": [ + "a2_jw = of.jordan_wigner(a2)\n", + "a2dag_jw = of.jordan_wigner(a2dag)\n", + "a7_jw = of.jordan_wigner(a7)\n", + "a7dag_jw = of.jordan_wigner(a7dag)\n", + "\n", + "print(a2_jw * a7_jw + a7_jw * a2_jw)\n", + "print(a2_jw * a7dag_jw + a7dag_jw * a2_jw)\n", + "print(a2_jw * a2dag_jw + a2dag_jw * a2_jw)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p1fQ3-DK5sIS" + }, + "source": [ + "## Array data structures\n", + "\n", + "- When `FermionOperator`s have specialized structure we can store coefficients in numpy arrays, enabling fast numerical manipulation.\n", + "- Array data structures can always be converted to `FermionOperator` using `openfermion.get_fermion_operator`.\n", + "\n", + "### InteractionOperator\n", + "\n", + "- Stores the one- and two-body tensors $T_{pq}$ and $V_{pqrs}$ of the molecular Hamiltonian\n", + "\n", + "$$\n", + "\\sum_{pq} T_{pq} a_p^\\dagger a_q + \\sum_{pqrs} V_{pqrs} a_p^\\dagger a_q^\\dagger a_r a_s\n", + "$$\n", + "\n", + "- Default data structure for molecular Hamiltonians\n", + "- Convert from `FermionOperator` using `openfermion.get_interaction_operator`\n", + "\n", + "### DiagonalCoulombHamiltonian\n", + "\n", + "- Stores the one- and two-body coefficient matrices $T_{pq}$ and $V_{pq}$ of a Hamiltonian with a diagonal Coulomb term:\n", + "\n", + "$$\n", + "\\sum_{pq} T_{pq} a_p^\\dagger a_q + \\sum_{pq} V_{pq} a_p^\\dagger a_p a_q^\\dagger a_q\n", + "$$\n", + "\n", + "- Leads to especially efficient algorithms for quantum simulation\n", + "- Convert from `FermionOperator` using `openfermion.get_diagonal_coulomb_hamiltonian`\n", + "\n", + "### QuadraticHamiltonian\n", + "\n", + "- Stores the Hermitian matrix $M_{pq}$ and antisymmetric matrix $\\Delta_{pq}$ describing a general quadratic Hamiltonian\n", + "\n", + "$$\n", + "\\sum_{p, q} M_{pq} a^\\dagger_p a_q + \\frac12 \\sum_{p, q} (\\Delta_{pq} a^\\dagger_p a^\\dagger_q + \\text{h.c.})\n", + "$$\n", + "\n", + "- Routines included for efficient diagonalization (can handle thousands of fermionic modes)\n", + "- Convert from `FermionOperator` using `openfermion.get_quadratic_hamiltonian`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fN6Bq0gbdK5G" + }, + "source": [ + "## Generating the Hamiltonian for a molecule" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l_UXxxqw5sIW" + }, + "source": [ + "The cell below demonstrates using one of our electronic structure package plugins, OpenFermion-PySCF, to generate a molecular Hamiltonian for a hydrogen molecule. Note that the Hamiltonian is returned as an `InteractionOperator`. We'll convert it to a `FermionOperator` and print the result." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "id": "r8mmL0aj5sIW" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.66147151365 [] +\n", + "-1.2178260299951058 [0^ 0] +\n", + "0.3316650744318082 [0^ 0^ 0 0] +\n", + "0.09231339177803066 [0^ 0^ 2 2] +\n", + "0.3316650744318082 [0^ 1^ 1 0] +\n", + "0.09231339177803066 [0^ 1^ 3 2] +\n", + "0.09231339177803066 [0^ 2^ 0 2] +\n", + "0.3267206861819477 [0^ 2^ 2 0] +\n", + "0.09231339177803066 [0^ 3^ 1 2] +\n", + "0.3267206861819477 [0^ 3^ 3 0] +\n", + "0.3316650744318082 [1^ 0^ 0 1] +\n", + "0.09231339177803066 [1^ 0^ 2 3] +\n", + "-1.2178260299951058 [1^ 1] +\n", + "0.3316650744318082 [1^ 1^ 1 1] +\n", + "0.09231339177803066 [1^ 1^ 3 3] +\n", + "0.09231339177803066 [1^ 2^ 0 3] +\n", + "0.3267206861819477 [1^ 2^ 2 1] +\n", + "0.09231339177803066 [1^ 3^ 1 3] +\n", + "0.3267206861819477 [1^ 3^ 3 1] +\n", + "0.32672068618194783 [2^ 0^ 0 2] +\n", + "0.09231339177803066 [2^ 0^ 2 0] +\n", + "0.32672068618194783 [2^ 1^ 1 2] +\n", + "0.09231339177803066 [2^ 1^ 3 0] +\n", + "-0.5096378744364826 [2^ 2] +\n", + "0.09231339177803066 [2^ 2^ 0 0] +\n", + "0.34339576784573445 [2^ 2^ 2 2] +\n", + "0.09231339177803066 [2^ 3^ 1 0] +\n", + "0.34339576784573445 [2^ 3^ 3 2] +\n", + "0.32672068618194783 [3^ 0^ 0 3] +\n", + "0.09231339177803066 [3^ 0^ 2 1] +\n", + "0.32672068618194783 [3^ 1^ 1 3] +\n", + "0.09231339177803066 [3^ 1^ 3 1] +\n", + "0.09231339177803066 [3^ 2^ 0 1] +\n", + "0.34339576784573445 [3^ 2^ 2 3] +\n", + "-0.5096378744364826 [3^ 3] +\n", + "0.09231339177803066 [3^ 3^ 1 1] +\n", + "0.34339576784573445 [3^ 3^ 3 3]\n" + ] + } + ], + "source": [ + "# Set molecule parameters\n", + "geometry = [('H', (0.0, 0.0, 0.0)), ('H', (0.0, 0.0, 0.8))]\n", + "basis = 'sto-3g'\n", + "multiplicity = 1\n", + "charge = 0\n", + "\n", + "# Perform electronic structure calculations and\n", + "# obtain Hamiltonian as an InteractionOperator\n", + "hamiltonian = ofpyscf.generate_molecular_hamiltonian(\n", + " geometry, basis, multiplicity, charge)\n", + "\n", + "# Convert to a FermionOperator\n", + "hamiltonian_ferm_op = of.get_fermion_operator(hamiltonian)\n", + "\n", + "print(hamiltonian_ferm_op)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jWxU4bG1oYfZ" + }, + "source": [ + "Let's calculate the ground energy (lowest eigenvalue) of the Hamiltonian. First, we'll map the `FermionOperator` to a `QubitOperator` using the JWT. Then, we'll convert the `QubitOperator` to a SciPy sparse matrix and get its lowest eigenvalue." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "id": "rIEH_5eLaxvG" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ground_energy: -1.134147666677095\n", + "JWT transformed Hamiltonian:\n", + "(-0.16733398905695201+0j) [] +\n", + "(-0.04615669588901533+0j) [X0 X1 Y2 Y3] +\n", + "(0.04615669588901533+0j) [X0 Y1 Y2 X3] +\n", + "(0.04615669588901533+0j) [Y0 X1 X2 Y3] +\n", + "(-0.04615669588901533+0j) [Y0 Y1 X2 X3] +\n", + "(0.16251648748871642+0j) [Z0] +\n", + "(0.1658325372159041+0j) [Z0 Z1] +\n", + "(0.11720364720195856+0j) [Z0 Z2] +\n", + "(0.1633603430909739+0j) [Z0 Z3] +\n", + "(0.16251648748871636+0j) [Z1] +\n", + "(0.1633603430909739+0j) [Z1 Z2] +\n", + "(0.11720364720195856+0j) [Z1 Z3] +\n", + "(-0.1974429369975584+0j) [Z2] +\n", + "(0.17169788392286722+0j) [Z2 Z3] +\n", + "(-0.19744293699755838+0j) [Z3]\n" + ] + } + ], + "source": [ + "# Map to QubitOperator using the JWT\n", + "hamiltonian_jw = of.jordan_wigner(hamiltonian_ferm_op)\n", + "\n", + "# Convert to Scipy sparse matrix\n", + "hamiltonian_jw_sparse = of.get_sparse_operator(hamiltonian_jw)\n", + "\n", + "# Compute ground energy\n", + "eigs, _ = linalg.eigsh(hamiltonian_jw_sparse, k=1, which='SA')\n", + "ground_energy = eigs[0]\n", + "\n", + "print('Ground_energy: {}'.format(ground_energy))\n", + "print('JWT transformed Hamiltonian:')\n", + "print(hamiltonian_jw)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gjUBgFx-axmm" + }, + "source": [ + "### Exercise\n", + "Compute the ground energy of the same Hamiltonian, but via the Bravyi-Kitaev transform. Verify that you get the same value." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "id": "ID2vls21XKj-" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ground_energy: -1.1341476666770918\n", + "BK transformed Hamiltonian:\n", + "(-0.16733398905695201+0j) [] +\n", + "(0.04615669588901533+0j) [X0 Z1 X2] +\n", + "(0.04615669588901533+0j) [X0 Z1 X2 Z3] +\n", + "(0.04615669588901533+0j) [Y0 Z1 Y2] +\n", + "(0.04615669588901533+0j) [Y0 Z1 Y2 Z3] +\n", + "(0.16251648748871642+0j) [Z0] +\n", + "(0.16251648748871636+0j) [Z0 Z1] +\n", + "(0.1633603430909739+0j) [Z0 Z1 Z2] +\n", + "(0.1633603430909739+0j) [Z0 Z1 Z2 Z3] +\n", + "(0.11720364720195856+0j) [Z0 Z2] +\n", + "(0.11720364720195856+0j) [Z0 Z2 Z3] +\n", + "(0.1658325372159041+0j) [Z1] +\n", + "(-0.19744293699755838+0j) [Z1 Z2 Z3] +\n", + "(0.17169788392286722+0j) [Z1 Z3] +\n", + "(-0.1974429369975584+0j) [Z2]\n" + ] + } + ], + "source": [ + "# Map to QubitOperator using the JWT\n", + "hamiltonian_bk = of.bravyi_kitaev(hamiltonian_ferm_op)\n", + "\n", + "# Convert to Scipy sparse matrix\n", + "hamiltonian_bk_sparse = of.get_sparse_operator(hamiltonian_bk)\n", + "\n", + "# Compute ground energy\n", + "eigs, _ = linalg.eigsh(hamiltonian_bk_sparse, k=1, which='SA')\n", + "ground_energy = eigs[0]\n", + "\n", + "print('Ground_energy: {}'.format(ground_energy))\n", + "print('BK transformed Hamiltonian:')\n", + "print(hamiltonian_bk)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dEqS3XV0eXx1" + }, + "source": [ + "### Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "id": "9Ss_OhXo5sIP" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ground_energy: -1.134147666677097\n", + "BKT transformed Hamiltonian:\n", + "(-0.16733398905695201+0j) [] +\n", + "(0.04615669588901533+0j) [X0 Z1 X2] +\n", + "(0.04615669588901533+0j) [X0 Z1 X2 Z3] +\n", + "(0.04615669588901533+0j) [Y0 Z1 Y2] +\n", + "(0.04615669588901533+0j) [Y0 Z1 Y2 Z3] +\n", + "(0.16251648748871642+0j) [Z0] +\n", + "(0.16251648748871636+0j) [Z0 Z1] +\n", + "(0.1633603430909739+0j) [Z0 Z1 Z2] +\n", + "(0.1633603430909739+0j) [Z0 Z1 Z2 Z3] +\n", + "(0.11720364720195856+0j) [Z0 Z2] +\n", + "(0.11720364720195856+0j) [Z0 Z2 Z3] +\n", + "(0.1658325372159041+0j) [Z1] +\n", + "(-0.19744293699755838+0j) [Z1 Z2 Z3] +\n", + "(0.17169788392286722+0j) [Z1 Z3] +\n", + "(-0.1974429369975584+0j) [Z2]\n" + ] + } + ], + "source": [ + "# Map to QubitOperator using the BKT\n", + "hamiltonian_bk = of.bravyi_kitaev(hamiltonian_ferm_op)\n", + "\n", + "# Convert to Scipy sparse matrix\n", + "hamiltonian_bk_sparse = of.get_sparse_operator(hamiltonian_bk)\n", + "\n", + "# Compute ground state energy\n", + "eigs, _ = linalg.eigsh(hamiltonian_bk_sparse, k=1, which='SA')\n", + "ground_energy = eigs[0]\n", + "\n", + "print('Ground_energy: {}'.format(ground_energy))\n", + "print('BKT transformed Hamiltonian:')\n", + "print(hamiltonian_bk)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H0DLpARr5sIb" + }, + "source": [ + "### Exercise\n", + "\n", + "- The BCS mean-field d-wave model of superconductivity has the Hamiltonian\n", + "\n", + "$$\n", + "H = - t \\sum_{\\langle i,j \\rangle} \\sum_\\sigma (a^\\dagger_{i, \\sigma} a_{j, \\sigma} + a^\\dagger_{j, \\sigma} a_{i, \\sigma}) - \\sum_{\\langle i,j \\rangle} \\Delta_{ij} (a^\\dagger_{i, \\uparrow} a^\\dagger_{j, \\downarrow} - a^\\dagger_{i, \\downarrow} a^\\dagger_{j, \\uparrow} + a_{j, \\downarrow} a_{i, \\uparrow} - a_{j, \\uparrow} a_{i, \\downarrow})\n", + "$$\n", + "\n", + "Use the `mean_field_dwave` function to generate an instance of this model with dimensions 10x10.\n", + " - Convert the Hamiltonian to a `QubitOperator` with the JWT. What is the length of the longest Pauli string that appears?\n", + " - Convert the Hamiltonian to a `QubitOperator` with the BKT. What is the length of the longest Pauli string that appears?\n", + " - Convert the Hamiltonian to a `QuadraticHamiltonian`. Get its ground energy using the `ground_energy` method of `QuadraticHamiltonian`. What would happen if you tried to compute the ground energy by converting to a sparse matrix?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zrnv4DLRuFJM" + }, + "source": [ + "## Hamiltonian simulation with Trotter formulas\n", + "\n", + "- Goal: apply $\\exp(-i H t)$ where $H = \\sum_j H_j$\n", + "- Use an approximation such as $\\exp(-i H t) \\approx (\\prod_{j=1} \\exp(-i H_j t/r))^r$\n", + "- Exposed via the `openfermion.simulate_trotter` function\n", + "- Currently implemented algorithms are from [arXiv:1706.00023](https://arxiv.org/pdf/1706.00023.pdf), [arXiv:1711.04789](https://arxiv.org/pdf/1711.04789.pdf), and [arXiv:1808.02625](https://arxiv.org/pdf/1808.02625.pdf), and are based on the JWT\n", + "- Currently supported Hamiltonian types: `DiagonalCoulombHamiltonian` and `InteractionOperator`\n", + "\n", + "As a demonstration, we'll simulate time evolution under the hydrogen molecule Hamiltonian we generated earlier.\n", + "\n", + "First, let's create a random initial state and apply the exact time evolution by matrix exponentiation:\n", + "\n", + "$$\n", + "\\lvert \\psi \\rangle \\mapsto \\exp(-i H t) \\lvert \\psi \\rangle\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "id": "_e5mbQI61fdT" + }, + "outputs": [], + "source": [ + "# Create a random initial state\n", + "n_qubits = of.count_qubits(hamiltonian)\n", + "initial_state = of.haar_random_vector(2**n_qubits, seed=7)\n", + "\n", + "# Set evolution time\n", + "time = 1.0\n", + "\n", + "# Apply exp(-i H t) to the state\n", + "exact_state = linalg.expm_multiply(-1j*hamiltonian_jw_sparse*time, initial_state)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_OZPjkN513zJ" + }, + "source": [ + "Now, let's create a circuit to perform the evolution and compare the fidelity of the resulting state with the one from exact evolution. The fidelity can be increased by increasing the number of Trotter steps. Note that the Hamiltonian input to `openfermion.simulate_trotter` should be an `InteractionOperator`, not a `FermionOperator`." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "id": "1DXSZ54u12Tt" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.9999820449924582\n" + ] + } + ], + "source": [ + "# Initialize qubits\n", + "qubits = cirq.LineQubit.range(n_qubits)\n", + "\n", + "# Create circuit\n", + "circuit = cirq.Circuit(\n", + " of.simulate_trotter(\n", + " qubits, hamiltonian, time,\n", + " n_steps=10,\n", + " order=0,\n", + " algorithm=of.LOW_RANK)\n", + ")\n", + "\n", + "# Apply the circuit to the initial state\n", + "result = circuit.final_state_vector(initial_state)\n", + "\n", + "# Compute the fidelity with the final state from exact evolution\n", + "fidelity = abs(np.dot(exact_state, result.conj()))**2\n", + "\n", + "print(fidelity)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "id": "tG4PCh4faFTL" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 1 2 3\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.052π) Rz(0.052π) Rz(0.03π) Rz(0.03π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.022 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.021\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.01π) @──────────────────@^-0.021 Rz(-0.011π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.01π) Rz(-0.011π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.006\n", + "│ │ │ │\n", + "@─────────────@^-0.006 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(π) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^0 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^0\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.03π) Rz(0) Rz(0) Rz(0.052π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.03π) Rz(0.052π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.022\n", + "│ │ │ │\n", + "@─────────────@^-0.021 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.011π) @──────────────────@^-0.021 Rz(-0.01π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.011π) Rz(-0.01π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.006 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.006\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(π) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^0\n", + "│ │ │ │\n", + "@─────────────@^0 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.052π) Rz(0) Rz(0) Rz(0.03π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.052π) Rz(0.03π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.022 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.021\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.01π) @──────────────────@^-0.021 Rz(-0.011π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.01π) Rz(-0.011π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.006\n", + "│ │ │ │\n", + "@─────────────@^-0.006 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(π) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^0 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^0\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.03π) Rz(0) Rz(0) Rz(0.052π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.03π) Rz(0.052π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.022\n", + "│ │ │ │\n", + "@─────────────@^-0.021 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.011π) @──────────────────@^-0.021 Rz(-0.01π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.011π) Rz(-0.01π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.006 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.006\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(π) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^0\n", + "│ │ │ │\n", + "@─────────────@^0 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.052π) Rz(0) Rz(0) Rz(0.03π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.052π) Rz(0.03π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.022 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.021\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.01π) @──────────────────@^-0.021 Rz(-0.011π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.01π) Rz(-0.011π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.006\n", + "│ │ │ │\n", + "@─────────────@^-0.006 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(π) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^0 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^0\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.03π) Rz(0) Rz(0) Rz(0.052π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.03π) Rz(0.052π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.022\n", + "│ │ │ │\n", + "@─────────────@^-0.021 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.011π) @──────────────────@^-0.021 Rz(-0.01π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.011π) Rz(-0.01π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.006 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.006\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(π) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^0\n", + "│ │ │ │\n", + "@─────────────@^0 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.052π) Rz(0) Rz(0) Rz(0.03π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.052π) Rz(0.03π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.022 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.021\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.01π) @──────────────────@^-0.021 Rz(-0.011π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.01π) Rz(-0.011π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.006\n", + "│ │ │ │\n", + "@─────────────@^-0.006 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(π) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^0 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^0\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.03π) Rz(0) Rz(0) Rz(0.052π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.03π) Rz(0.052π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.022\n", + "│ │ │ │\n", + "@─────────────@^-0.021 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.011π) @──────────────────@^-0.021 Rz(-0.01π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.011π) Rz(-0.01π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.006 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.006\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(π) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^0\n", + "│ │ │ │\n", + "@─────────────@^0 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.052π) Rz(0) Rz(0) Rz(0.03π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.052π) Rz(0.03π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.022 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.021\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.01π) @──────────────────@^-0.021 Rz(-0.011π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.01π) Rz(-0.011π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.006\n", + "│ │ │ │\n", + "@─────────────@^-0.006 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(π) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^0 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^0\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "Rz(0.03π) Rz(0) Rz(0) Rz(0.052π)\n", + "│ │ │ │\n", + "Rz(0) Rz(0) Rz(0) Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0.03π) Rz(0.052π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-1\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^-1 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^-0.022\n", + "│ │ │ │\n", + "@─────────────@^-0.021 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^-0.021 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^-0.021 @────────────────@^-0.021\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.011π) @──────────────────@^-0.021 Rz(-0.01π)\n", + "│ │ │ │\n", + "Rz(π) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.011π) Rz(-0.01π) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 Z^0\n", + "│ │ │ │\n", + "@─────────────@^-0.006 Z^0 │\n", + "│ │ │ │\n", + "×─────────────× @────────────────@^-0.006\n", + "│ │ │ │\n", + "│ │ ×────────────────×\n", + "│ │ │ │\n", + "│ @──────────────────@^0.006 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0.006 @────────────────@^0.006\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(-0.003π) @──────────────────@^0.006 Rz(-0.003π)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(π)\n", + "│ │ │ │\n", + "│ Rz(-0.003π) Rz(-0.003π) │\n", + "│ │ │ │\n", + "│ Rz(π) Rz(0) │\n", + "│ │ │ │\n", + "│ PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 PhISwap(0.25)────PhISwap(0.25)^-0.5\n", + "│ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.5 Z^0 │\n", + "│ │ │ │\n", + "Z^0 PhISwap(0.25)──────PhISwap(0.25)^-1 │\n", + "│ │ │ │\n", + "│ Z^0 @────────────────@^0\n", + "│ │ │ │\n", + "@─────────────@^0 ×────────────────×\n", + "│ │ │ │\n", + "×─────────────× │ │\n", + "│ │ │ │\n", + "│ @──────────────────@^0 │\n", + "│ │ │ │\n", + "│ ×──────────────────× │\n", + "│ │ │ │\n", + "@─────────────@^0 @────────────────@^0\n", + "│ │ │ │\n", + "×─────────────× ×────────────────×\n", + "│ │ │ │\n", + "Rz(0) @──────────────────@^0 Rz(0)\n", + "│ │ │ │\n", + "Rz(0) ×──────────────────× Rz(0)\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n", + "│ Rz(0) Rz(0) │\n", + "│ │ │ │\n" + ] + } + ], + "source": [ + "print(circuit.to_text_diagram(transpose=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vim-c2VhuGZO" + }, + "source": [ + "## Bogoliubov transformation\n", + "\n", + "- Single-particle orbital basis change\n", + "- In the particle-conserving case, takes the form\n", + "$$\n", + "U a_p^\\dagger U^\\dagger = b_p^\\dagger, \\quad b_p^\\dagger = \\sum_{q} u_{pq} a_q^\\dagger\n", + "$$\n", + "and $u$ is unitary.\n", + "- Can be used to diagonalize any quadratic Hamiltonian:\n", + "$$\n", + "\\sum_{p, q} T_{pq} a_p^\\dagger a_q \\mapsto \\sum_{j} \\varepsilon_j b_j^\\dagger b_j + \\text{constant}\n", + "$$\n", + "- Implementation from [arXiv:1711.05395](https://arxiv.org/pdf/1711.05395.pdf); uses linear depth and linear connectivity\n", + "\n", + "As an example, we'll prepare the ground state of a random particle-conserving quadratic Hamiltonian." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "id": "sOhY4QQtuGZP" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.690525703800356 [] +\n", + "(0.5315776978980016+0j) [0^ 0] +\n", + "(-1.347208023348913+2.7004721387490935j) [0^ 1] +\n", + "(-0.28362365442898696-1.8784499457335426j) [0^ 2] +\n", + "(0.12594647819298657-1.3106154125325498j) [0^ 3] +\n", + "(-0.3880303291443195-1.1751249212322041j) [0^ 4] +\n", + "(-1.347208023348913-2.7004721387490935j) [1^ 0] +\n", + "(2.5012533818678193+0j) [1^ 1] +\n", + "(0.3391421007279024-3.8305756810505094j) [1^ 2] +\n", + "(-0.3509690502067961+0.090677856754656j) [1^ 3] +\n", + "(1.8575239595653907-1.4736314761076197j) [1^ 4] +\n", + "(-0.28362365442898696+1.8784499457335426j) [2^ 0] +\n", + "(0.3391421007279024+3.8305756810505094j) [2^ 1] +\n", + "(-0.019560786804260433+0j) [2^ 2] +\n", + "(-2.979765944360631+2.5490724453105917j) [2^ 3] +\n", + "(0.5091942820312417+0.344618218148502j) [2^ 4] +\n", + "(0.12594647819298657+1.3106154125325498j) [3^ 0] +\n", + "(-0.3509690502067961-0.090677856754656j) [3^ 1] +\n", + "(-2.979765944360631-2.5490724453105917j) [3^ 2] +\n", + "(3.767336752913784+0j) [3^ 3] +\n", + "(-1.2963431636902167-1.5288970105744286j) [3^ 4] +\n", + "(-0.3880303291443195+1.1751249212322041j) [4^ 0] +\n", + "(1.8575239595653907+1.4736314761076197j) [4^ 1] +\n", + "(0.5091942820312417-0.344618218148502j) [4^ 2] +\n", + "(-1.2963431636902167+1.5288970105744286j) [4^ 3] +\n", + "(-0.3445183403145406+0j) [4^ 4]\n" + ] + } + ], + "source": [ + "n_qubits = 5\n", + "quad_ham = of.random_quadratic_hamiltonian(\n", + " n_qubits, conserves_particle_number=True, seed=7)\n", + "\n", + "print(of.get_fermion_operator(quad_ham))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HwObrpO5uGZS" + }, + "source": [ + "Now we construct a circuit which maps computational basis states to eigenstates of the Hamiltonian." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "id": "P1w7kKokuGZT" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 1 2 3 4\n", + "│ │ │ │ │\n", + "Rz(0) Rz(0) Rz(π) Rz(-π) Rz(0)\n", + "│ │ │ │ │\n", + "│ │ │ PhISwap(0.25)─────────PhISwap(0.25)^0.073\n", + "│ │ │ │ │\n", + "│ │ PhISwap(0.25)────────PhISwap(0.25)^(5/11) Z^(-7/9)\n", + "│ │ │ │ │\n", + "│ PhISwap(0.25)───────PhISwap(0.25)^0.814 Z^-0.508 │\n", + "│ │ │ │ │\n", + "PhISwap(0.25)─PhISwap(0.25)^0.703 Z^-0.304 PhISwap(0.25)─────────PhISwap(0.25)^0.381\n", + "│ │ │ │ │\n", + "│ Z^-0.767 PhISwap(0.25)────────PhISwap(0.25)^(13/16) Z^0.401\n", + "│ │ │ │ │\n", + "│ PhISwap(0.25)───────PhISwap(0.25)^(7/11) Z^(-13/14) │\n", + "│ │ │ │ │\n", + "│ │ Z^0.393 PhISwap(0.25)─────────PhISwap(0.25)^0.481\n", + "│ │ │ │ │\n", + "│ │ PhISwap(0.25)────────PhISwap(0.25)^0.422 Z^-0.738\n", + "│ │ │ │ │\n", + "│ │ │ Z^-0.824 │\n", + "│ │ │ │ │\n", + "│ │ │ PhISwap(0.25)─────────PhISwap(0.25)^0.506\n", + "│ │ │ │ │\n", + "│ │ │ │ Z^(5/7)\n", + "│ │ │ │ │\n" + ] + } + ], + "source": [ + "_, basis_change_matrix, _ = quad_ham.diagonalizing_bogoliubov_transform()\n", + "\n", + "qubits = cirq.LineQubit.range(n_qubits)\n", + "circuit = cirq.Circuit(\n", + " of.bogoliubov_transform(\n", + " qubits,\n", + " basis_change_matrix))\n", + "\n", + "print(circuit.to_text_diagram(transpose=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-jDHy5izuGZV" + }, + "source": [ + "In the rotated basis, the quadratic Hamiltonian takes the form\n", + "$$\n", + "H = \\sum_j \\varepsilon_j b_j^\\dagger b_j + \\text{constant}\n", + "$$\n", + "We can get the $\\varepsilon_j$ and the constant using the `orbital_energies` method of `QuadraticHamiltonian`." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "id": "Q0aZhjc0uGZW" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-6.25377614 -1.2291963 0.71202361 5.0062515 8.20078604]\n", + "1.690525703800356\n" + ] + } + ], + "source": [ + "orbital_energies, constant = quad_ham.orbital_energies()\n", + "\n", + "print(orbital_energies)\n", + "print(constant)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YCsxdHRpuGZZ" + }, + "source": [ + "The ground state of the Hamiltonian is prepared by filling in the orbitals with negative energy." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "id": "ggOZq0DXuGZZ" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(-5.792446738060052+1.1102230246251565e-16j)\n", + "-5.792446738060049\n" + ] + } + ], + "source": [ + "# Apply the circuit with initial state having the first two modes occupied.\n", + "result = circuit.final_state_vector(initial_state=0b11000)\n", + "\n", + "# Compute the expectation value of the final state with the Hamiltonian\n", + "quad_ham_sparse = of.get_sparse_operator(quad_ham)\n", + "print(of.expectation(quad_ham_sparse, result))\n", + "\n", + "# Print out the ground state energy; it should match\n", + "print(quad_ham.ground_energy())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6WXdbSBmuGZc" + }, + "source": [ + "Recall that the Jordan-Wigner transform of $b_j^\\dagger b_j$ is $\\frac12(I-Z)$. Therefore, $\\exp(-i \\varepsilon_j b_j^\\dagger b_j)$ is equivalent to a single-qubit Z rotation under the JWT. Since the operators $b_j^\\dagger b_j$ commute, we have\n", + "$$\n", + "\\exp(-i H t) = \\exp(-i \\sum_j \\varepsilon_j b_j^\\dagger b_j t)\n", + "= \\prod_j \\exp(-i \\varepsilon_j b_j^\\dagger b_j t)\n", + "$$\n", + "This gives a method for simulating time evolution under a quadratic Hamiltonian:\n", + "- Use a Bogoliubov transformation to change to the basis in which the Hamiltonian is diagonal (Note: this transformation might be the inverse of what you expect. In that case, use `cirq.inverse`)\n", + "- Apply single-qubit Z-rotations with angles proportional to the orbital energies\n", + "- Undo the basis change\n", + "\n", + "The code cell below creates a random initial state and applies time evolution by direct matrix exponentiation." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "id": "pqELuMY8uGZd" + }, + "outputs": [], + "source": [ + "# Create a random initial state\n", + "initial_state = of.haar_random_vector(2**n_qubits)\n", + "\n", + "# Set evolution time\n", + "time = 1.0\n", + "\n", + "# Apply exp(-i H t) to the state\n", + "final_state = linalg.expm_multiply(-1j*quad_ham_sparse*time, initial_state)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dFzXiKp0uGZf" + }, + "source": [ + "### Exercise\n", + "\n", + "Fill in the code cell below to construct a circuit which applies $\\exp(-i H t)$ using the method described above" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "id": "f0y43UhbuGZh" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.08926042490120051\n" + ] + } + ], + "source": [ + "# Initialize qubits\n", + "qubits = cirq.LineQubit.range(n_qubits)\n", + "\n", + "# Write code below to create the circuit\n", + "# You should define the `circuit` variable here\n", + "# ---------------------------------------------\n", + "\n", + "\n", + "# ---------------------------------------------\n", + "\n", + "# Apply the circuit to the initial state\n", + "result = circuit.final_state_vector(initial_state)\n", + "\n", + "# Compute the fidelity with the correct final state\n", + "fidelity = abs(np.dot(final_state, result.conj()))**2\n", + "\n", + "# Print fidelity; it should be 1\n", + "print(fidelity)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wp1a_Zf8EUen" + }, + "source": [ + "### Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "id": "QHQvLlf1uGZt" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.999999999999994\n" + ] + } + ], + "source": [ + "# Initialize qubits\n", + "qubits = cirq.LineQubit.range(n_qubits)\n", + "\n", + "# Write code below to create the circuit\n", + "# You should define the `circuit` variable here\n", + "# ---------------------------------------------\n", + "def exponentiate_quad_ham(qubits, quad_ham):\n", + " _, basis_change_matrix, _ = quad_ham.diagonalizing_bogoliubov_transform()\n", + " orbital_energies, _ = quad_ham.orbital_energies()\n", + " \n", + " yield cirq.inverse(\n", + " of.bogoliubov_transform(qubits, basis_change_matrix))\n", + " for i in range(len(qubits)):\n", + " yield cirq.rz(rads=-orbital_energies[i]).on(qubits[i])\n", + " yield of.bogoliubov_transform(qubits, basis_change_matrix)\n", + "\n", + "circuit = cirq.Circuit(exponentiate_quad_ham(qubits, quad_ham))\n", + "# ---------------------------------------------\n", + "\n", + "# Apply the circuit to the initial state\n", + "result = circuit.final_state_vector(initial_state)\n", + "\n", + "# Compute the fidelity with the correct final state\n", + "fidelity = abs(np.dot(final_state, result.conj()))**2\n", + "\n", + "# Print fidelity; it should be 1\n", + "print(fidelity)" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [ + "Wp1a_Zf8EUen" + ], + "name": "chemistry.ipynb", + "toc_visible": true + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From 0c18aecdbb9f850a1a55e0551211fae5ae5bd432 Mon Sep 17 00:00:00 2001 From: Auguste Hirth Date: Thu, 19 May 2022 21:45:23 -0700 Subject: [PATCH 2/4] Rename and add to TOC --- docs/_book.yaml | 2 ++ .../{chemistry.ipynb => intro_workshop_exercises.ipynb} | 0 2 files changed, 2 insertions(+) rename docs/tutorials/{chemistry.ipynb => intro_workshop_exercises.ipynb} (100%) diff --git a/docs/_book.yaml b/docs/_book.yaml index 56e376c79..10a44148c 100644 --- a/docs/_book.yaml +++ b/docs/_book.yaml @@ -32,6 +32,8 @@ upper_tabs: path: /openfermion/tutorials/circuits_2_diagonal_coulomb_trotter - title: "Constructing Trotter Steps With Low-Rank Decomposition" path: /openfermion/tutorials/circuits_3_arbitrary_basis_trotter + - title: "Intro Workshop with Exercises" + path: /openfermion/tutorials/intro_workshop_exercises - heading: "OpenFermion-FQE Guide & Tutorials" - title: "Overview" diff --git a/docs/tutorials/chemistry.ipynb b/docs/tutorials/intro_workshop_exercises.ipynb similarity index 100% rename from docs/tutorials/chemistry.ipynb rename to docs/tutorials/intro_workshop_exercises.ipynb From 6500abe2f082d20bf7a1d029e2e2a43371a1c1ab Mon Sep 17 00:00:00 2001 From: Auguste Hirth Date: Thu, 19 May 2022 21:45:55 -0700 Subject: [PATCH 3/4] Run Formatter --- docs/tutorials/intro_workshop_exercises.ipynb | 93 +++++++++---------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/docs/tutorials/intro_workshop_exercises.ipynb b/docs/tutorials/intro_workshop_exercises.ipynb index 1045db104..5ac1df5a7 100644 --- a/docs/tutorials/intro_workshop_exercises.ipynb +++ b/docs/tutorials/intro_workshop_exercises.ipynb @@ -18,7 +18,7 @@ }, "outputs": [], "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", @@ -180,7 +180,9 @@ } ], "source": [ - "op = of.FermionOperator(((4, 1), (3, 1), (9, 0), (1, 0)), 1+2j) + of.FermionOperator(((3, 1), (1, 0)), -1.7)\n", + "op = of.FermionOperator(((4, 1), (3, 1), (9, 0), (1, 0)), 1 + 2j) + of.FermionOperator(\n", + " ((3, 1), (1, 0)), -1.7\n", + ")\n", "\n", "print(op.terms)" ] @@ -220,7 +222,7 @@ } ], "source": [ - "op = of.FermionOperator('4^ 3^ 9 1', 1+2j) + of.FermionOperator('3^ 1', -1.7)\n", + "op = of.FermionOperator(\"4^ 3^ 9 1\", 1 + 2j) + of.FermionOperator(\"3^ 1\", -1.7)\n", "\n", "print(op.terms)" ] @@ -282,8 +284,8 @@ } ], "source": [ - "op = of.QubitOperator(((1, 'X'), (2, 'Y'), (3, 'Z')))\n", - "op += of.QubitOperator('X3 Z4', 3.0)\n", + "op = of.QubitOperator(((1, \"X\"), (2, \"Y\"), (3, \"Z\")))\n", + "op += of.QubitOperator(\"X3 Z4\", 3.0)\n", "\n", "print(op)" ] @@ -332,7 +334,7 @@ } ], "source": [ - "op = of.FermionOperator('2^ 15')\n", + "op = of.FermionOperator(\"2^ 15\")\n", "\n", "print(of.jordan_wigner(op))\n", "print()\n", @@ -383,17 +385,17 @@ } ], "source": [ - "a2 = of.FermionOperator('2')\n", + "a2 = of.FermionOperator(\"2\")\n", "print(of.jordan_wigner(a2))\n", "print()\n", "\n", - "a2dag = of.FermionOperator('2^')\n", - "print(of.jordan_wigner(a2dag*a2))\n", + "a2dag = of.FermionOperator(\"2^\")\n", + "print(of.jordan_wigner(a2dag * a2))\n", "print()\n", "\n", - "a7 = of.FermionOperator('7')\n", - "a7dag = of.FermionOperator('7^')\n", - "print(of.jordan_wigner((1+2j)*(a2dag*a7) + (1-2j)*(a7dag*a2)))" + "a7 = of.FermionOperator(\"7\")\n", + "a7dag = of.FermionOperator(\"7^\")\n", + "print(of.jordan_wigner((1 + 2j) * (a2dag * a7) + (1 - 2j) * (a7dag * a2)))" ] }, { @@ -430,17 +432,17 @@ } ], "source": [ - "a2 = of.FermionOperator('2')\n", - "a2dag = of.FermionOperator('2^')\n", - "a7 = of.FermionOperator('7')\n", - "a7dag = of.FermionOperator('7^')\n", + "a2 = of.FermionOperator(\"2\")\n", + "a2dag = of.FermionOperator(\"2^\")\n", + "a7 = of.FermionOperator(\"7\")\n", + "a7dag = of.FermionOperator(\"7^\")\n", "\n", "print(of.jordan_wigner(a2dag))\n", "print()\n", - "print(of.jordan_wigner(a2dag*a2))\n", + "print(of.jordan_wigner(a2dag * a2))\n", "print()\n", "\n", - "op = (2+3j)*a2dag*a7\n", + "op = (2 + 3j) * a2dag * a7\n", "op += of.hermitian_conjugated(op)\n", "print(of.jordan_wigner(op))" ] @@ -616,15 +618,16 @@ ], "source": [ "# Set molecule parameters\n", - "geometry = [('H', (0.0, 0.0, 0.0)), ('H', (0.0, 0.0, 0.8))]\n", - "basis = 'sto-3g'\n", + "geometry = [(\"H\", (0.0, 0.0, 0.0)), (\"H\", (0.0, 0.0, 0.8))]\n", + "basis = \"sto-3g\"\n", "multiplicity = 1\n", "charge = 0\n", "\n", "# Perform electronic structure calculations and\n", "# obtain Hamiltonian as an InteractionOperator\n", "hamiltonian = ofpyscf.generate_molecular_hamiltonian(\n", - " geometry, basis, multiplicity, charge)\n", + " geometry, basis, multiplicity, charge\n", + ")\n", "\n", "# Convert to a FermionOperator\n", "hamiltonian_ferm_op = of.get_fermion_operator(hamiltonian)\n", @@ -680,11 +683,11 @@ "hamiltonian_jw_sparse = of.get_sparse_operator(hamiltonian_jw)\n", "\n", "# Compute ground energy\n", - "eigs, _ = linalg.eigsh(hamiltonian_jw_sparse, k=1, which='SA')\n", + "eigs, _ = linalg.eigsh(hamiltonian_jw_sparse, k=1, which=\"SA\")\n", "ground_energy = eigs[0]\n", "\n", - "print('Ground_energy: {}'.format(ground_energy))\n", - "print('JWT transformed Hamiltonian:')\n", + "print(\"Ground_energy: {}\".format(ground_energy))\n", + "print(\"JWT transformed Hamiltonian:\")\n", "print(hamiltonian_jw)" ] }, @@ -737,11 +740,11 @@ "hamiltonian_bk_sparse = of.get_sparse_operator(hamiltonian_bk)\n", "\n", "# Compute ground energy\n", - "eigs, _ = linalg.eigsh(hamiltonian_bk_sparse, k=1, which='SA')\n", + "eigs, _ = linalg.eigsh(hamiltonian_bk_sparse, k=1, which=\"SA\")\n", "ground_energy = eigs[0]\n", "\n", - "print('Ground_energy: {}'.format(ground_energy))\n", - "print('BK transformed Hamiltonian:')\n", + "print(\"Ground_energy: {}\".format(ground_energy))\n", + "print(\"BK transformed Hamiltonian:\")\n", "print(hamiltonian_bk)" ] }, @@ -793,11 +796,11 @@ "hamiltonian_bk_sparse = of.get_sparse_operator(hamiltonian_bk)\n", "\n", "# Compute ground state energy\n", - "eigs, _ = linalg.eigsh(hamiltonian_bk_sparse, k=1, which='SA')\n", + "eigs, _ = linalg.eigsh(hamiltonian_bk_sparse, k=1, which=\"SA\")\n", "ground_energy = eigs[0]\n", "\n", - "print('Ground_energy: {}'.format(ground_energy))\n", - "print('BKT transformed Hamiltonian:')\n", + "print(\"Ground_energy: {}\".format(ground_energy))\n", + "print(\"BKT transformed Hamiltonian:\")\n", "print(hamiltonian_bk)" ] }, @@ -860,7 +863,7 @@ "time = 1.0\n", "\n", "# Apply exp(-i H t) to the state\n", - "exact_state = linalg.expm_multiply(-1j*hamiltonian_jw_sparse*time, initial_state)" + "exact_state = linalg.expm_multiply(-1j * hamiltonian_jw_sparse * time, initial_state)" ] }, { @@ -894,17 +897,15 @@ "# Create circuit\n", "circuit = cirq.Circuit(\n", " of.simulate_trotter(\n", - " qubits, hamiltonian, time,\n", - " n_steps=10,\n", - " order=0,\n", - " algorithm=of.LOW_RANK)\n", + " qubits, hamiltonian, time, n_steps=10, order=0, algorithm=of.LOW_RANK\n", + " )\n", ")\n", "\n", "# Apply the circuit to the initial state\n", "result = circuit.final_state_vector(initial_state)\n", "\n", "# Compute the fidelity with the final state from exact evolution\n", - "fidelity = abs(np.dot(exact_state, result.conj()))**2\n", + "fidelity = abs(np.dot(exact_state, result.conj())) ** 2\n", "\n", "print(fidelity)" ] @@ -1955,7 +1956,8 @@ "source": [ "n_qubits = 5\n", "quad_ham = of.random_quadratic_hamiltonian(\n", - " n_qubits, conserves_particle_number=True, seed=7)\n", + " n_qubits, conserves_particle_number=True, seed=7\n", + ")\n", "\n", "print(of.get_fermion_operator(quad_ham))" ] @@ -2013,10 +2015,7 @@ "_, basis_change_matrix, _ = quad_ham.diagonalizing_bogoliubov_transform()\n", "\n", "qubits = cirq.LineQubit.range(n_qubits)\n", - "circuit = cirq.Circuit(\n", - " of.bogoliubov_transform(\n", - " qubits,\n", - " basis_change_matrix))\n", + "circuit = cirq.Circuit(of.bogoliubov_transform(qubits, basis_change_matrix))\n", "\n", "print(circuit.to_text_diagram(transpose=True))" ] @@ -2128,7 +2127,7 @@ "time = 1.0\n", "\n", "# Apply exp(-i H t) to the state\n", - "final_state = linalg.expm_multiply(-1j*quad_ham_sparse*time, initial_state)" + "final_state = linalg.expm_multiply(-1j * quad_ham_sparse * time, initial_state)" ] }, { @@ -2172,7 +2171,7 @@ "result = circuit.final_state_vector(initial_state)\n", "\n", "# Compute the fidelity with the correct final state\n", - "fidelity = abs(np.dot(final_state, result.conj()))**2\n", + "fidelity = abs(np.dot(final_state, result.conj())) ** 2\n", "\n", "# Print fidelity; it should be 1\n", "print(fidelity)" @@ -2212,13 +2211,13 @@ "def exponentiate_quad_ham(qubits, quad_ham):\n", " _, basis_change_matrix, _ = quad_ham.diagonalizing_bogoliubov_transform()\n", " orbital_energies, _ = quad_ham.orbital_energies()\n", - " \n", - " yield cirq.inverse(\n", - " of.bogoliubov_transform(qubits, basis_change_matrix))\n", + "\n", + " yield cirq.inverse(of.bogoliubov_transform(qubits, basis_change_matrix))\n", " for i in range(len(qubits)):\n", " yield cirq.rz(rads=-orbital_energies[i]).on(qubits[i])\n", " yield of.bogoliubov_transform(qubits, basis_change_matrix)\n", "\n", + "\n", "circuit = cirq.Circuit(exponentiate_quad_ham(qubits, quad_ham))\n", "# ---------------------------------------------\n", "\n", @@ -2226,7 +2225,7 @@ "result = circuit.final_state_vector(initial_state)\n", "\n", "# Compute the fidelity with the correct final state\n", - "fidelity = abs(np.dot(final_state, result.conj()))**2\n", + "fidelity = abs(np.dot(final_state, result.conj())) ** 2\n", "\n", "# Print fidelity; it should be 1\n", "print(fidelity)" From 787752ab77629085b521bd608bc820f6905fc431 Mon Sep 17 00:00:00 2001 From: Auguste Hirth Date: Thu, 19 May 2022 21:50:40 -0700 Subject: [PATCH 4/4] Fix Buttons --- docs/tutorials/intro_workshop_exercises.ipynb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/intro_workshop_exercises.ipynb b/docs/tutorials/intro_workshop_exercises.ipynb index 5ac1df5a7..7fe54fa36 100644 --- a/docs/tutorials/intro_workshop_exercises.ipynb +++ b/docs/tutorials/intro_workshop_exercises.ipynb @@ -48,16 +48,16 @@ "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", - " View on QuantumAI\n", + " View on QuantumAI\n", " \n", - " Run in Google Colab\n", + " Run in Google Colab\n", " \n", - " View source on GitHub\n", + " View source on GitHub\n", " \n", - " Download notebook\n", + " Download notebook\n", "
" ]