From 194b1c4d8bcf86e9c307db3c04fd41c54932b32b Mon Sep 17 00:00:00 2001 From: James Wootton Date: Tue, 7 Nov 2023 10:27:41 +0100 Subject: [PATCH] ex2 --- exercises/Exercise2.ipynb | 146 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 exercises/Exercise2.ipynb diff --git a/exercises/Exercise2.ipynb b/exercises/Exercise2.ipynb new file mode 100644 index 0000000..37d7624 --- /dev/null +++ b/exercises/Exercise2.ipynb @@ -0,0 +1,146 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise Sheet 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1 - Trotter-Suzuki Simulations\n", + "\n", + "Consider the following Hamiltonian defined on four qubits.\n", + "\n", + "$$\n", + "\\tilde H = - J_x (X_0 X_1 + X_2 X_3) - J_z (Z_0 Z_2 + Z_1 Z_3) - h\\sum_j X_j + Z_j\n", + "$$\n", + "\n", + "Here $X_1 = I \\otimes \\sigma^x \\otimes I \\otimes I$, etc. The Hamiltonian is denoted $\\tilde H$ here to distingush it from the Hadamard, $H$.\n", + "\n", + "The time evolution of this Hamiltonian can be approximated by\n", + "\n", + "$$\n", + "e^{i \\tilde H t} \\approx \\left( e^{-i X_0 X_1 \\, J_x t/n} e^{-i X_2 X_3 \\, J_x t/n} e^{-i Z_0 Z_2 \\, J_z t/n} e^{-i Z_1 Z_3 J_z \\, t/n}\\prod_j e^{-i(X_j +Z_j)\\, ht/n} \\right)^n\n", + "$$\n", + "\n", + "where the approximation becomes increasing accurate as $n$ is increased.\n", + "\n", + "To complete the following questions, first write a Qiskit circuit to implement such a simulation of the time evolution.\n", + "\n", + "(a) For $J_x=1$ and $J_z=h=0$,$e^{i\\tilde H t} \\sim X_1 X_2 X_3 X_4$ for a suitable value of $t$. Determine the required value of $t$, and show that your simulation has this effect by appling to an initial $|0\\rangle^{\\otimes 4}$ state.\n", + "\n", + "(b) For $J_z=1$ and $J_x=h=0$, $e^{i\\tilde H t} \\sim Z_1 Z_2 Z_3 Z_4$ for a suitable value of $t$. Determine the required value of $t$, and show that your simulation has this effect by appling to an initial $|+\\rangle^{\\otimes 4}$ state.\n", + "\n", + "(c) For $J_x=J_z=0$ and $h=1$, $e^{i\\tilde H t} \\sim H_1 H_2 H_3 H_4$ for a suitable value of $t$. Determine the required value of $t$, and show that your simulation has this effect by appling to an initial $|0\\rangle^{\\otimes 4}$ state.\n", + "\n", + "(d) Find $W$, a four-qubit Pauli observable (non-trivial on all qubits) that commutes with all the two-qubit terms in the Hamiltonian.\n", + "\n", + "(e) For what value of $n$ (approximately) does the error in the simulation for the next question become on the same order as sampling error for $10^3$ shots? Assume that $n=1000$ yields a perfect approximation and use $J_x=J_z=1$, $h=2$.\n", + "\n", + "(f) For $J_x=J_z=1$ and starting in an eigenstate of $W$, calculate $\\langle W \\rangle$ for various times in the interval $0 < t \\leq 2 \\pi$, and for a sufficiently large $n$. Plot the results for $h=0.1$, $h=1$ and $h=2$.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# 2 - Inverse QFT\n", + "Using Qiskit, implement an inverse Quantum Fourier transform for any general number of qubits.\n", + "* Unlike the QFT in the lecture notes, your inverse QFT should not reverse qubit\n", + "order.\n", + "* You must implement the $R_n$ rotations using only single qubit gates and\n", + "controlled-NOT gates.\n", + "\n", + "To demonstrate that your circuit does what it is supposed to, you can use the following function. This prepares the state that is QFT of the binary representation of a given integer $j$ on a\n", + "given quantum register `qr``. Applying your inverse QFT, you should be able to rotate\n", + "back to the binary representation of $j$.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "# this function creates the state prep circuit\n", + "def state_prep(j,qr):\n", + " n = qr.size\n", + " N = 2**n\n", + " state = [0]*N\n", + " for k in range(N):\n", + " state[k] = np.exp( 1j * 2*np.pi*j*k/N ) / np.sqrt(N)\n", + " qc_prep = QuantumCircuit(qr)\n", + " qc_prep.initialize(state,qr)\n", + " return qc_prep\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's an example of using this function to show that an inverse QFT circuit works. Here I use the inverse QFT from Qiskit (which of course you cannot submit as your solution)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import transpile\n", + "from qiskit.circuit.library import QFT\n", + "from qiskit_aer import AerSimulator\n", + "\n", + "# set an integer\n", + "j = 8\n", + "# and a number of qubits\n", + "n = 5\n", + "\n", + "# create an inverse qft circuit\n", + "qc_qft = QFT(n, inverse=True)\n", + "# prepare the QFT of the integer on the same quanntum register\n", + "qc_prep = state_prep(j, qc_qft.qregs[0])\n", + "# create the combined circuit: first the prep, then the inverse qft\n", + "qc = qc_prep.compose(qc_qft)\n", + "# measure all qubits\n", + "qc.measure_all()\n", + "\n", + "# run it, and see what integer comes out for 10 samples\n", + "# (hopefully, it's the one you put in)\n", + "backend = AerSimulator()\n", + "for string in backend.run(transpile(qc,backend), shots=10, memory=True).result().get_memory():\n", + " print(int(string, 2))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "arc-decoder", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}