{ "cells": [ { "cell_type": "markdown", "id": "290fa254", "metadata": {}, "source": [ "# The Cross Resonance (CR) Gate" ] }, { "cell_type": "markdown", "id": "776a5a9c", "metadata": {}, "source": [ "> 💡 **Using this tutorial without the Qt GUI**\n", "> \n", "> This tutorial uses the desktop `MetalGUI`. To follow along on Colab, Binder, JupyterHub, or any environment where Qt isn't available, **replace any `gui.rebuild()` / `gui.screenshot()` call with `qm.view(design)`** — it renders the design to a matplotlib `Figure` you can display inline or save with `fig.savefig(...)`.\n", "> \n", "> See [1.4 Headless quick view](../1-Overview/1.4-Headless-quick-view-%28no-Qt-GUI%29.ipynb) for a complete runnable walkthrough and [`docs/headless-usage.rst`](../../../docs/headless-usage.rst) for the full reference." ] }, { "cell_type": "markdown", "id": "c806b8fd", "metadata": {}, "source": [ "Here's what we'll work through in this tutorial notebook:\n", "\n", "* Introduce and describe the basic operation of the cross-resonance (CR) gate \n", "* Construct the time-dependent Hamiltonian of a representative CR gate consisting of two qubits coupled via a CPW resonator. \n", "* Look at the time-evolution of the two qubits in a CR gate \n", "* Show how to build a representative physical design of a CR gate using qiskit metal. " ] }, { "cell_type": "markdown", "id": "59b2896a", "metadata": {}, "source": [ "### What is the CR Gate?" ] }, { "cell_type": "markdown", "id": "ee31f028", "metadata": {}, "source": [ "The cross-resonance (CR) gate consists of two fixed-frequency qubits connected via a resonator. One of the qubits (the \"control\" qubit) is driven at the transition frequency of the second qubit (the \"target\" qubit) which results in Rabi oscillations in the target qubit. \n", "\n", "Some helpful background papers on the CR gate: \n", "\n", "* C. Rigetti and M. Devoret, Phys. Rev. B 81, 134507 (2010)\n", "* M. Malekakhlagh et al., Phys. Rev. A 102, 042605 (2020)\n", "* E. Magesan and J.M. Gambetta, Phys. Rev. A 101, 052308 (2020)\n" ] }, { "cell_type": "markdown", "id": "b6481708", "metadata": {}, "source": [ "### What does the Hamiltonian of the CR gate look like? \n", "\n", "We can composite Hamiltonian of the CR gate consists of the non-interacting Hamiltonians of the two qubits, a coupling term between the two qubits and the drive term applied to the control qubit:\n", "\n", "$H = H_{Q1} + H_{Q2} + H_{Coupling} + H_{Drive} $ \n", "\n", "where $H_{Coupling}$ is the coupling between qubit 1 and qubit 2, and $H_{Drive}$ is the driving microwave signal applies to qubit 1 (at the frequency of qubit 2). The first three terms are time-independent while the drive term has time-dependence in the form a cosine wave. \n", "\n", "In a simplistic approach using Pauli matrices ($\\sigma_z = a^{+}a $ , $\\sigma_x = a + a^{+} $) for each qubit, we can write the individual components as follows:\n", "\n", "$H_{Q1} = 0.5 \\omega_1 \\sigma_1^{z} $\n", "\n", "$H_{Q2} = 0.5 \\omega_2 \\sigma_2^{z} $\n", "\n", "$H_{Coupling} = 0.5 \\omega_{xx} \\sigma_1^{x} \\sigma_2^{x}$\n", "\n", "$H_{Drive} = \\Omega cos(\\omega_1^{RF} t + \\phi) \\sigma_1^{x} $\n", "\n", "By setting $\\omega_1^{RF} = \\omega_2$, we are driving qubit 1 at the frequency of qubit 2. \n", "\n", "The full Hamiltonian can thus be written as: \n", "\n", "$H = 0.5 \\omega_1 \\sigma_1^{z} + 0.5 \\omega_2 \\sigma_2^{z} + 0.5 \\omega_{xx} \\sigma_1^{x} \\sigma_2^{x} + \\Omega cos(\\omega_1^{RF} t + \\phi) \\sigma_1^{x} $" ] }, { "cell_type": "markdown", "id": "19e8997d", "metadata": {}, "source": [ "### Constructing the CR Gate Hamiltonian Using QuTiP & Qiskit Metal " ] }, { "cell_type": "markdown", "id": "dba55f35", "metadata": {}, "source": [ "Let's start by loading the required modules:" ] }, { "cell_type": "code", "execution_count": null, "id": "36d53fe9", "metadata": {}, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "%config IPCompleter.greedy = True\n", "%matplotlib inline\n", "%config Completer.use_jedi = False\n", "%config InlineBackend.figure_format = 'svg'\n", "\n", "from qiskit_metal.analyses.hamiltonian.transmon_charge_basis import Hcpb\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from qutip import *\n", "from math import *" ] }, { "cell_type": "markdown", "id": "5e683d2e", "metadata": {}, "source": [ "The CR gate uses fixed-frequency qubits, so we'll define the two qubit frequencies as well as the coupling strength between them. We'll use similar values to those published in the original CR gate paper from Rigetti & Devoret: " ] }, { "cell_type": "code", "execution_count": null, "id": "de72a384", "metadata": {}, "outputs": [], "source": [ "w1 = 12.8\n", "w2 = 16.1\n", "g = 0.13" ] }, { "cell_type": "markdown", "id": "c5e283e1", "metadata": {}, "source": [ "Now, let's define the initial states of the two qubits and then construct the tensor product for the composite wavefunction of the initial state. We'll consider two states for each qubit, hence we'll use \"basis(2,N)\" where N represents the index of the state. " ] }, { "cell_type": "code", "execution_count": null, "id": "3d119051", "metadata": {}, "outputs": [], "source": [ "# Initial States of Qubit1 and Qubit2\n", "Psi1_initial = basis(2, 0) # ground state of qubit 1\n", "Psi2_initial = basis(2, 1) # excited state of qubit 2\n", "\n", "# Tensor Product of Composite Initial Wavefunction\n", "Psi0 = tensor(Psi1_initial, Psi2_initial)" ] }, { "cell_type": "markdown", "id": "fc0940f4", "metadata": {}, "source": [ "### Time-independent Hamiltonian" ] }, { "cell_type": "markdown", "id": "8f5c9900", "metadata": {}, "source": [ "Now let's build the operators that will go into the Hamiltonian. Notice that the two tensor products below have the location of the identity matrix (\"qeye\") swapped, since in the first case we're writing the operator for qubit 1 in the basis of qubit 2, and the second case we're writing the operator for qubit 2 in the basis of qubit 1. " ] }, { "cell_type": "code", "execution_count": null, "id": "fcf64ba9", "metadata": {}, "outputs": [], "source": [ "# ladder operator for qubit 1 (\"a\")\n", "a = tensor(destroy(2), qeye(2))\n", "\n", "# ladder operator for qubit 2 (\"b\")\n", "b = tensor(qeye(2), destroy(2))" ] }, { "cell_type": "markdown", "id": "0b7525f1", "metadata": {}, "source": [ "Now let's construct the tensor products for occupation probability operators (for n=0 and n=1) for each qubit. " ] }, { "cell_type": "code", "execution_count": null, "id": "1176b351", "metadata": {}, "outputs": [], "source": [ "# QUBIT 1\n", "\n", "# this defines the ground state |n=0>\n", "c0 = basis(2, 0)\n", "# now take the product |n=0>\n", "c1 = basis(2, 1)\n", "# take the product |n=1>