├── .github └── workflows │ └── pytests.yml ├── .gitignore ├── LICENSE ├── README.md ├── environment.yml ├── examples ├── data │ └── spectrum_vs_ng.hdf5 ├── demo-jaynes-cummings.ipynb ├── demo_cos2phi_qubit.ipynb ├── demo_customcircuit.ipynb ├── demo_explorer.ipynb ├── demo_flux_qubit.ipynb ├── demo_fluxonium.ipynb ├── demo_gui.ipynb ├── demo_hilbertspace.ipynb ├── demo_noise.ipynb ├── demo_parametersweep.ipynb ├── demo_qutip_fluxoniumcz.ipynb ├── demo_qutip_fluxoniumreset.ipynb ├── demo_transmon.ipynb ├── demo_zeropi.ipynb ├── read-h5-file.nb └── scqubits_paper_source_code.ipynb └── workflow-requirements.info /.github/workflows/pytests.yml: -------------------------------------------------------------------------------- 1 | name: scqubits-examples testing via pytest nbval 2 | 3 | on: [push, workflow_dispatch, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | timeout-minutes: 100 10 | strategy: 11 | matrix: 12 | python-version: ['3.9', '3.10', '3.11', '3.12'] 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Set up Python ${{ matrix.python-version }} 16 | uses: actions/setup-python@v5 17 | with: 18 | python-version: ${{ matrix.python-version }} 19 | - name: Install dependencies 20 | run: | 21 | python -m pip install --upgrade pip 22 | python -m pip install git+https://github.com/scqubits/scqubits.git 23 | python -m pip install -r workflow-requirements.info 24 | - name: Test notebooks with py.test --nbval-lax 25 | run: | 26 | pip install pytest nbval 27 | py.test --nbval-lax 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /examples/.ipynb_checkpoints/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2019, Jens Koch and Peter Groszkowski 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | scqubits: superconducting qubits in Python 2 | =========================================== 3 | 4 | [J. Koch](https://github.com/jkochNU), [P. Groszkowski](https://github.com/petergthatsme) 5 | 6 | 7 | **This repository contains Jupyter notebooks showing examples of how to use the scqubits library.** 8 | 9 | 10 | > **You can access a live jupyter notebook version of the examples here:** [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/scqubits/scqubits-examples/released) 11 | 12 | scqubits is an open-source Python library for simulating superconducting qubits. It is meant to give the user 13 | a convenient way to obtain energy spectra of common superconducting qubits, plot energy levels as a function of 14 | external parameters, calculate matrix elements etc. The library further provides an interface to QuTiP, making it 15 | easy to work with composite Hilbert spaces consisting of coupled superconducting qubits and harmonic modes. 16 | Internally, numerics within scqubits is carried out with the help of Numpy and Scipy; plotting capabilities rely on 17 | Matplotlib. 18 | 19 | 20 | Documentation 21 | ------------- 22 | 23 | The documentation for scqubits is available at: https://scqubits.readthedocs.io 24 | 25 | 26 | 27 | License 28 | ------- 29 | [![license](https://img.shields.io/badge/license-New%20BSD-blue.svg)](http://en.wikipedia.org/wiki/BSD_licenses#3-clause_license_.28.22Revised_BSD_License.22.2C_.22New_BSD_License.22.2C_or_.22Modified_BSD_License.22.29) 30 | 31 | You are free to use this software, with or without modification, provided that the conditions listed in the LICENSE file are satisfied. 32 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: example-environment 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - cython 6 | - scipy 7 | - numpy 8 | - qutip 9 | - matplotlib 10 | - h5py>=2.7.1 11 | - tqdm 12 | - cycler 13 | - pathos 14 | - dill 15 | - scqubits==2.0 16 | - ipywidgets 17 | - sympy 18 | -------------------------------------------------------------------------------- /examples/data/spectrum_vs_ng.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scqubits/scqubits-examples/b6d3ea7d6e3b002178d3d10fc506d2be21d88f2f/examples/data/spectrum_vs_ng.hdf5 -------------------------------------------------------------------------------- /examples/demo-jaynes-cummings.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "pycharm": { 7 | "name": "#%% md\n" 8 | } 9 | }, 10 | "source": [ 11 | "# scqubits example: Jaynes-Cummings model\n", 12 | "J. Koch and P. Groszkowski\n", 13 | "\n", 14 | "For further documentation of scqubits see https://scqubits.readthedocs.io/en/latest/.\n", 15 | "\n", 16 | "---" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": { 23 | "ExecuteTime": { 24 | "end_time": "2020-03-31T11:43:53.057632Z", 25 | "start_time": "2020-03-31T11:43:53.000813Z" 26 | }, 27 | "init_cell": true, 28 | "pycharm": { 29 | "name": "#%%\n" 30 | }, 31 | "scrolled": true 32 | }, 33 | "outputs": [], 34 | "source": [ 35 | "import numpy as np\n", 36 | "\n", 37 | "import scqubits as scq\n", 38 | "from scqubits import HilbertSpace, InteractionTerm, ParameterSweep" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": { 44 | "pycharm": { 45 | "name": "#%% md\n" 46 | } 47 | }, 48 | "source": [ 49 | "## The Jaynes-Cummings model\n", 50 | "\n", 51 | "The Jaynes-Cummings mode describes a system composed of a qubit (two-level system) coupled to a harmonic oscillator. The coupling is such that a qubit excitation can be \"converted\" into a photon and vice versa,\n", 52 | "\n", 53 | "$\\displaystyle H=-\\frac{\\omega_q}{2}\\sigma_z + \\omega_r a^\\dagger a + g (a\\sigma_+ + a^\\dagger \\sigma_-)$\n", 54 | "\n", 55 | "This model can be solved exactly, resulting in the following eigenenergies:\n", 56 | "\n", 57 | "$\\displaystyle E_0 = -\\frac{1}{2}\\omega_q$,\n", 58 | "\n", 59 | "$\\displaystyle E_{n\\pm} = \\bigg(n-\\frac{1}{2}\\bigg) \\omega_r \\pm \\sqrt{\\frac{\\Delta^2}{4}+n g^2}$,\n", 60 | "\n", 61 | "where $\\Delta=\\omega_r-\\omega_q$ and $n=1,2,\\ldots$.\n" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 2, 67 | "metadata": { 68 | "pycharm": { 69 | "name": "#%%\n" 70 | } 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "# exact eigenenergies for comparing with numerics\n", 75 | "\n", 76 | "def energies(frequency_r, frequency_q, g, n_cutoff):\n", 77 | " delta = frequency_r - frequency_q\n", 78 | " energies1 = (np.arange(1, n_cutoff) - 0.5) * frequency_r\n", 79 | " energies2 = np.sqrt(delta**2/4 + np.arange(1, n_cutoff) * g**2)\n", 80 | " energies_plus = energies1 + energies2\n", 81 | " energies_minus = energies1 - energies2\n", 82 | " energies_0 = np.asarray([[-0.5 * frequency_q]])\n", 83 | " all_energies = np.append(energies_0, energies_minus)\n", 84 | " all_energies = np.append(all_energies, energies_plus)\n", 85 | " return np.sort(all_energies)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": { 91 | "pycharm": { 92 | "name": "#%% md\n" 93 | } 94 | }, 95 | "source": [ 96 | "### Set up the subsystems" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 3, 102 | "metadata": { 103 | "ExecuteTime": { 104 | "end_time": "2020-03-31T11:43:54.037807Z", 105 | "start_time": "2020-03-31T11:43:54.024841Z" 106 | }, 107 | "pycharm": { 108 | "name": "#%%\n" 109 | } 110 | }, 111 | "outputs": [], 112 | "source": [ 113 | "frequency_q = 1.0\n", 114 | "frequency_r = 0.8\n", 115 | "g = 0.1\n", 116 | "\n", 117 | "\n", 118 | "qubit = scq.GenericQubit(E=frequency_q)\n", 119 | "\n", 120 | "osc = scq.Oscillator(\n", 121 | " E_osc=frequency_r,\n", 122 | " truncated_dim=10 # up to 9 photons\n", 123 | ")" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": { 129 | "pycharm": { 130 | "name": "#%% md\n" 131 | } 132 | }, 133 | "source": [ 134 | "### Set up Hilbert space" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 4, 140 | "metadata": { 141 | "ExecuteTime": { 142 | "end_time": "2020-03-31T11:44:00.099411Z", 143 | "start_time": "2020-03-31T11:44:00.092429Z" 144 | }, 145 | "pycharm": { 146 | "name": "#%%\n" 147 | } 148 | }, 149 | "outputs": [], 150 | "source": [ 151 | "# Form a list of all components making up the Hilbert space.\n", 152 | "hilbertspace = HilbertSpace([qubit, osc])\n", 153 | "\n", 154 | "hilbertspace.add_interaction(\n", 155 | " g_strength = g,\n", 156 | " op1 = qubit.sm_operator,\n", 157 | " op2 = osc.creation_operator,\n", 158 | " add_hc = True\n", 159 | ")" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 5, 165 | "metadata": { 166 | "ExecuteTime": { 167 | "end_time": "2020-03-31T11:43:54.772581Z", 168 | "start_time": "2020-03-31T11:43:54.765597Z" 169 | }, 170 | "pycharm": { 171 | "name": "#%%\n" 172 | } 173 | }, 174 | "outputs": [ 175 | { 176 | "name": "stdout", 177 | "output_type": "stream", 178 | "text": [ 179 | "HilbertSpace: subsystems\n", 180 | "-------------------------\n", 181 | "\n", 182 | "GenericQubit--------| [GenericQubit_1]\n", 183 | " | E: 1.0\n", 184 | " |\n", 185 | " | dim: 2\n", 186 | "\n", 187 | "\n", 188 | "Oscillator----------| [Oscillator_1]\n", 189 | " | E_osc: 0.8\n", 190 | " | l_osc: None\n", 191 | " | truncated_dim: 10\n", 192 | " |\n", 193 | " | dim: 10\n", 194 | "\n", 195 | "\n", 196 | "\n", 197 | "HilbertSpace: interaction terms\n", 198 | "--------------------------------\n", 199 | "InteractionTerm----------| [Interaction_1]\n", 200 | " | g_strength: 0.1\n", 201 | " | operator_list: [(0, \n", 65 | "\n", 67 | "\n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " 2024-03-01T15:37:37.139068\n", 73 | " image/svg+xml\n", 74 | " \n", 75 | " \n", 76 | " Matplotlib v3.8.2, https://matplotlib.org/\n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 144 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 397 | " \n", 414 | " \n", 448 | " \n", 461 | " \n", 491 | " \n", 518 | " \n", 519 | " \n", 544 | " \n", 565 | " \n", 597 | " \n", 618 | " \n", 641 | " \n", 679 | " \n", 680 | " \n", 681 | " \n", 682 | " \n", 683 | " \n", 684 | " \n", 685 | " \n", 686 | " \n", 687 | " \n", 688 | " \n", 689 | " \n", 690 | " \n", 691 | " \n", 692 | " \n", 693 | " \n", 694 | " \n", 695 | " \n", 696 | " \n", 697 | " \n", 698 | " \n", 699 | " \n", 700 | " \n", 701 | " \n", 702 | " \n", 703 | " \n", 706 | " \n", 707 | " \n", 708 | " \n", 709 | " \n", 710 | " \n", 711 | " \n", 712 | " \n", 713 | " \n", 714 | " \n", 715 | " \n", 716 | " \n", 717 | " \n", 718 | " \n", 719 | " \n", 720 | " \n", 721 | " \n", 722 | " \n", 723 | " \n", 724 | " \n", 725 | " \n", 726 | " \n", 727 | " \n", 728 | " \n", 753 | " \n", 754 | " \n", 755 | " \n", 756 | " \n", 757 | " \n", 758 | " \n", 759 | " \n", 760 | " \n", 761 | " \n", 762 | " \n", 763 | " \n", 764 | " \n", 765 | " \n", 766 | " \n", 767 | " \n", 768 | " \n", 769 | " \n", 770 | " \n", 771 | " \n", 772 | " \n", 773 | " \n", 774 | " \n", 775 | " \n", 776 | " \n", 777 | " \n", 778 | " \n", 779 | " \n", 780 | " \n", 781 | " \n", 782 | " \n", 783 | " \n", 784 | " \n", 785 | " \n", 786 | " \n", 787 | " \n", 788 | " \n", 789 | " \n", 790 | " \n", 791 | " \n", 792 | " \n", 793 | " \n", 794 | " \n", 795 | " \n", 796 | " \n", 797 | " \n", 798 | " \n", 799 | " \n", 800 | " \n", 801 | " \n", 802 | " \n", 803 | " \n", 804 | " \n", 821 | " \n", 838 | " \n", 849 | " \n", 876 | " \n", 891 | " \n", 904 | " \n", 915 | " \n", 916 | " \n", 917 | " \n", 918 | " \n", 919 | " \n", 920 | " \n", 921 | " \n", 922 | " \n", 923 | " \n", 924 | " \n", 925 | " \n", 926 | " \n", 927 | " \n", 928 | " \n", 929 | " \n", 930 | " \n", 931 | " \n", 932 | " \n", 936 | " \n", 937 | " \n", 938 | " \n", 942 | " \n", 943 | " \n", 944 | " \n", 948 | " \n", 949 | " \n", 950 | " \n", 954 | " \n", 955 | " \n", 956 | " \n", 966 | " \n", 967 | " \n", 968 | " \n", 971 | " \n", 972 | " \n", 973 | " \n", 976 | " \n", 977 | " \n", 978 | " \n", 979 | " \n", 980 | " \n", 981 | " \n", 982 | " \n", 983 | " \n", 984 | "\n" 985 | ], 986 | "text/plain": [ 987 | "
" 988 | ] 989 | }, 990 | "execution_count": 3, 991 | "metadata": {}, 992 | "output_type": "execute_result" 993 | } 994 | ], 995 | "source": [ 996 | "fig, ax = scq.GUI.fig_ax\n", 997 | "ax.set_xlabel(r\"charge offset $n_g$\")\n", 998 | "fig" 999 | ] 1000 | } 1001 | ], 1002 | "metadata": { 1003 | "kernelspec": { 1004 | "display_name": "Python 3 (ipykernel)", 1005 | "language": "python", 1006 | "name": "python3" 1007 | }, 1008 | "language_info": { 1009 | "codemirror_mode": { 1010 | "name": "ipython", 1011 | "version": 3 1012 | }, 1013 | "file_extension": ".py", 1014 | "mimetype": "text/x-python", 1015 | "name": "python", 1016 | "nbconvert_exporter": "python", 1017 | "pygments_lexer": "ipython3", 1018 | "version": "3.11.7" 1019 | } 1020 | }, 1021 | "nbformat": 4, 1022 | "nbformat_minor": 5 1023 | } 1024 | -------------------------------------------------------------------------------- /examples/demo_hilbertspace.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": {}, 7 | "source": [ 8 | "# scqubits example: composite Hilbert spaces\n", 9 | "J. Koch and P. Groszkowski
\n", 10 | "E. Blackwell\n", 11 | "\n", 12 | "For further documentation of scqubits see https://scqubits.readthedocs.io/en/latest/.\n", 13 | "\n", 14 | "---" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": { 21 | "ExecuteTime": { 22 | "end_time": "2020-03-31T11:43:53.057632Z", 23 | "start_time": "2020-03-31T11:43:53.000813Z" 24 | }, 25 | "init_cell": true, 26 | "pycharm": { 27 | "is_executing": false 28 | }, 29 | "scrolled": true 30 | }, 31 | "outputs": [ 32 | { 33 | "name": "stderr", 34 | "output_type": "stream", 35 | "text": [ 36 | "UserWarning: Runtime cython compilation does not work on Python 3.12.\n", 37 | " /home/pgroszko/anaconda3/envs/develscq5/lib/python3.12/site-packages/qutip/__init__.py: 71" 38 | ] 39 | } 40 | ], 41 | "source": [ 42 | "import scqubits as scq" 43 | ] 44 | }, 45 | { 46 | "attachments": {}, 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "# Working with composite Hilbert spaces and interfacing with QuTiP\n", 51 | "\n", 52 | "Systems of interest for quantum information processing will involve multiple qubits as well as oscillators with mutual coupling. The resulting Hilbert space is the tensor product of the individual constituent Hilbert spaces. The `HilbertSpace` class allows one to define such coupled systems, to define the interactions between them, and to contruct the overall Hamiltonian. From this, dressed eigenenergies and eigenstates can be extracted. The operator matrices and state vectors at the `HilbertSpace` level are given as QuTiP `Qobj` instances. This interface to QuTiP is particularly helpful if the task at hand is the simulation of time-dependent dynamics of the coupled system, perhaps including additional drive terms." 53 | ] 54 | }, 55 | { 56 | "attachments": {}, 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "## Example: two ocilllator qubits coupled by an rf SQUID\n", 61 | "\n", 62 | "As an interesting example of a coupled quantum system consider two harmonic modes coupled by an rf SQUID. The effective Hamiltonian describing this composite system, after integrating out the SQUID degrees of freedom, is given by [https://www.nature.com/articles/s41567-019-0703-5]\n", 63 | "\n", 64 | "$\\displaystyle H/\\hbar = \\omega_a a^\\dagger a + \\omega_b b^\\dagger b + g(a^\\dagger b + a b^\\dagger) + g_2(a^\\dagger a^\\dagger b + a a b^\\dagger) + \\chi_{ab} a^\\dagger ab^\\dagger b + \\frac{\\chi_{aa}}{2} a^\\dagger a^\\dagger a a + \\frac{\\chi_{bb}}{2} b^\\dagger b^\\dagger b b$,\n", 65 | "\n", 66 | "which can be rewritten as\n", 67 | "\n", 68 | "$\\displaystyle H = E_{\\text{osc}_a} a^\\dagger a + E_{\\text{osc}_b} b^\\dagger b + g(a^\\dagger b + a b^\\dagger) + g_2(a^\\dagger a^\\dagger b + a a b^\\dagger) + \\chi_{ab} a^\\dagger ab^\\dagger b - K_a a^\\dagger a^\\dagger a a - K_b b^\\dagger b^\\dagger b b$.\n", 69 | "\n", 70 | "### Define Hilbert space components, initialize `HilbertSpace` object\n", 71 | "\n", 72 | "To set up the Hilbert space, we define the separate components as Kerr oscillators and initialize a `HilbertSpace` object by submitting the list of all subsystems:" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 2, 78 | "metadata": { 79 | "ExecuteTime": { 80 | "end_time": "2020-03-31T11:43:54.037807Z", 81 | "start_time": "2020-03-31T11:43:54.024841Z" 82 | }, 83 | "pycharm": { 84 | "name": "#%%\n" 85 | } 86 | }, 87 | "outputs": [], 88 | "source": [ 89 | "# Set up the components / subspaces of our Hilbert space\n", 90 | "E_osc_a = 4.284\n", 91 | "K_a = 0.003\n", 92 | "\n", 93 | "E_osc_b = 7.073\n", 94 | "K_b = 0.015\n", 95 | "\n", 96 | "osc1 = scq.KerrOscillator(\n", 97 | " E_osc = E_osc_a,\n", 98 | " K = K_a,\n", 99 | " truncated_dim = 4,\n", 100 | ")\n", 101 | "\n", 102 | "osc2 = scq.KerrOscillator(\n", 103 | " E_osc = E_osc_b,\n", 104 | " K = K_b,\n", 105 | " truncated_dim = 4,\n", 106 | ")\n", 107 | "\n", 108 | "# Form a list of all components making up the Hilbert space.\n", 109 | "hilbertspace = scq.HilbertSpace([osc1, osc2])" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 3, 115 | "metadata": { 116 | "ExecuteTime": { 117 | "end_time": "2020-03-31T11:43:54.772581Z", 118 | "start_time": "2020-03-31T11:43:54.765597Z" 119 | } 120 | }, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "HilbertSpace: subsystems\n", 127 | "-------------------------\n", 128 | "\n", 129 | "KerrOscillator------| [KerrOscillator_1]\n", 130 | " | E_osc: 4.284\n", 131 | " | K: 0.003\n", 132 | " | l_osc: None\n", 133 | " | truncated_dim: 4\n", 134 | " |\n", 135 | " | dim: 4\n", 136 | "\n", 137 | "\n", 138 | "KerrOscillator------| [KerrOscillator_2]\n", 139 | " | E_osc: 7.073\n", 140 | " | K: 0.015\n", 141 | " | l_osc: None\n", 142 | " | truncated_dim: 4\n", 143 | " |\n", 144 | " | dim: 4\n", 145 | "\n", 146 | "\n" 147 | ] 148 | } 149 | ], 150 | "source": [ 151 | "print(hilbertspace)" 152 | ] 153 | }, 154 | { 155 | "attachments": {}, 156 | "cell_type": "markdown", 157 | "metadata": { 158 | "pycharm": { 159 | "name": "#%% md\n" 160 | } 161 | }, 162 | "source": [ 163 | "While we yet have to set up the interactions between the components, we can already obtain the bare Hamiltonian of the non-interacting subsystems, expressed as a matrix in the joint Hilbert space:" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 4, 169 | "metadata": { 170 | "ExecuteTime": { 171 | "end_time": "2020-03-31T11:43:56.149663Z", 172 | "start_time": "2020-03-31T11:43:56.110801Z" 173 | }, 174 | "pycharm": { 175 | "name": "#%%\n" 176 | } 177 | }, 178 | "outputs": [ 179 | { 180 | "data": { 181 | "text/latex": [ 182 | "Quantum object: dims = [[4, 4], [4, 4]], shape = (16, 16), type = oper, isherm = True $ \\\\ \\left(\\begin{matrix}0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 7.073 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 14.116 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 21.129 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 4.284 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\\\vdots & \\vdots & \\vdots & \\vdots & \\vdots & \\ddots & \\vdots & \\vdots & \\vdots & \\vdots & \\vdots\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 29.691 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 12.834 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 19.907 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 26.950 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 33.963\\\\\\end{matrix}\\right)$" 183 | ], 184 | "text/plain": [ 185 | "Quantum object: dims = [[4, 4], [4, 4]], shape = (16, 16), type = oper, isherm = True\n", 186 | "Qobj data =\n", 187 | "[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", 188 | " 0. 0. 0. 0. 0. 0. ]\n", 189 | " [ 0. 7.073 0. 0. 0. 0. 0. 0. 0. 0.\n", 190 | " 0. 0. 0. 0. 0. 0. ]\n", 191 | " [ 0. 0. 14.116 0. 0. 0. 0. 0. 0. 0.\n", 192 | " 0. 0. 0. 0. 0. 0. ]\n", 193 | " [ 0. 0. 0. 21.129 0. 0. 0. 0. 0. 0.\n", 194 | " 0. 0. 0. 0. 0. 0. ]\n", 195 | " [ 0. 0. 0. 0. 4.284 0. 0. 0. 0. 0.\n", 196 | " 0. 0. 0. 0. 0. 0. ]\n", 197 | " [ 0. 0. 0. 0. 0. 11.357 0. 0. 0. 0.\n", 198 | " 0. 0. 0. 0. 0. 0. ]\n", 199 | " [ 0. 0. 0. 0. 0. 0. 18.4 0. 0. 0.\n", 200 | " 0. 0. 0. 0. 0. 0. ]\n", 201 | " [ 0. 0. 0. 0. 0. 0. 0. 25.413 0. 0.\n", 202 | " 0. 0. 0. 0. 0. 0. ]\n", 203 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 8.562 0.\n", 204 | " 0. 0. 0. 0. 0. 0. ]\n", 205 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 15.635\n", 206 | " 0. 0. 0. 0. 0. 0. ]\n", 207 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", 208 | " 22.678 0. 0. 0. 0. 0. ]\n", 209 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", 210 | " 0. 29.691 0. 0. 0. 0. ]\n", 211 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", 212 | " 0. 0. 12.834 0. 0. 0. ]\n", 213 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", 214 | " 0. 0. 0. 19.907 0. 0. ]\n", 215 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", 216 | " 0. 0. 0. 0. 26.95 0. ]\n", 217 | " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", 218 | " 0. 0. 0. 0. 0. 33.963]]" 219 | ] 220 | }, 221 | "execution_count": 4, 222 | "metadata": {}, 223 | "output_type": "execute_result" 224 | } 225 | ], 226 | "source": [ 227 | "bare_hamiltonian = hilbertspace.bare_hamiltonian()\n", 228 | "bare_hamiltonian" 229 | ] 230 | }, 231 | { 232 | "attachments": {}, 233 | "cell_type": "markdown", 234 | "metadata": {}, 235 | "source": [ 236 | "As we have not added any interactions yet, there is no difference between the methods `bare_hamiltonian()` and `hamiltonian()` at the moment:" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": 5, 242 | "metadata": {}, 243 | "outputs": [ 244 | { 245 | "data": { 246 | "text/plain": [ 247 | "True" 248 | ] 249 | }, 250 | "execution_count": 5, 251 | "metadata": {}, 252 | "output_type": "execute_result" 253 | } 254 | ], 255 | "source": [ 256 | "bare_hamiltonian == hilbertspace.hamiltonian()" 257 | ] 258 | }, 259 | { 260 | "attachments": {}, 261 | "cell_type": "markdown", 262 | "metadata": { 263 | "pycharm": { 264 | "name": "#%% md\n" 265 | } 266 | }, 267 | "source": [ 268 | "The Hamiltonian matrix is given in the form of a QuTiP quantum object.\n", 269 | "This facilitates simple incorporation of Hamiltonians generated with `scqubits` into any of the solvers QuTiP offers for time evolution." 270 | ] 271 | }, 272 | { 273 | "attachments": {}, 274 | "cell_type": "markdown", 275 | "metadata": { 276 | "pycharm": { 277 | "name": "#%% md\n" 278 | } 279 | }, 280 | "source": [ 281 | "### Set up interaction terms between individual subsystems\n", 282 | "\n", 283 | "Interactions are added using the `add_interaction()` method. If the interaction is of the form $g \\cdot \\text{op1} \\cdot \\text{op2}$, it can be added by specifying the coefficient $g$ and the two operators $\\text{op1}$ and $\\text{op2}$. Otherwise, the interaction is given as a Python string that is later evaluated." 284 | ] 285 | }, 286 | { 287 | "attachments": {}, 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "1. $g(a^\\dagger b + a b^\\dagger)$\n", 292 | "2. $g_2(a^\\dagger a^\\dagger b + a a b^\\dagger)$\n", 293 | "3. $\\chi_{ab} a^\\dagger ab^\\dagger b$" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": 6, 299 | "metadata": { 300 | "ExecuteTime": { 301 | "end_time": "2020-03-31T11:44:00.099411Z", 302 | "start_time": "2020-03-31T11:44:00.092429Z" 303 | }, 304 | "pycharm": { 305 | "name": "#%%\n" 306 | } 307 | }, 308 | "outputs": [], 309 | "source": [ 310 | "# Option A: operator product specification via callables\n", 311 | "# Term 1\n", 312 | "g = 0.1\n", 313 | "\n", 314 | "hilbertspace.add_interaction(\n", 315 | " g_strength = g,\n", 316 | " op1 = osc1.creation_operator,\n", 317 | " op2 = osc2.annihilation_operator,\n", 318 | " add_hc = True\n", 319 | ")\n", 320 | "\n", 321 | "# Option B: string-based specification of interaction term\n", 322 | "# Term 2\n", 323 | "g2 = 0.035 \n", 324 | "\n", 325 | "hilbertspace.add_interaction(\n", 326 | " expr = \"g2 * a.dag() * a.dag() * b\",\n", 327 | " op1 = (\"a\", osc1.annihilation_operator),\n", 328 | " op2 = (\"b\", osc2.annihilation_operator),\n", 329 | " add_hc = True\n", 330 | ")\n", 331 | "\n", 332 | "# Term 3\n", 333 | "chi_ab = 0.01\n", 334 | "\n", 335 | "hilbertspace.add_interaction(\n", 336 | " expr = \"chi_ab * a.dag() * a * b.dag() * b\",\n", 337 | " op1 = (\"a\", osc1.annihilation_operator),\n", 338 | " op2 = (\"b\", osc2.annihilation_operator),\n", 339 | " add_hc = False\n", 340 | ")" 341 | ] 342 | }, 343 | { 344 | "attachments": {}, 345 | "cell_type": "markdown", 346 | "metadata": { 347 | "pycharm": { 348 | "name": "#%% md\n" 349 | } 350 | }, 351 | "source": [ 352 | "Now that the interactions are specified, the full Hamiltonian of the coupled system can be obtained with `hamiltonian()`:" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": 7, 358 | "metadata": { 359 | "ExecuteTime": { 360 | "end_time": "2020-03-31T11:44:03.627440Z", 361 | "start_time": "2020-03-31T11:44:03.599501Z" 362 | }, 363 | "pycharm": { 364 | "name": "#%%\n" 365 | } 366 | }, 367 | "outputs": [ 368 | { 369 | "data": { 370 | "text/latex": [ 371 | "Quantum object: dims = [[4, 4], [4, 4]], shape = (16, 16), type = oper, isherm = True $ \\\\ \\left(\\begin{matrix}0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 7.073 & 0.0 & 0.0 & 0.100 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 14.116 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 21.129 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.100 & 0.0 & 0.0 & 4.284 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\\\\\vdots & \\vdots & \\vdots & \\vdots & \\vdots & \\ddots & \\vdots & \\vdots & \\vdots & \\vdots & \\vdots\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 29.751 & 0.0 & 0.0 & 0.300 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 12.834 & 0.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 19.937 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.300 & 0.0 & 0.0 & 27.010 & 0.0\\\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & \\cdots & 0.0 & 0.0 & 0.0 & 0.0 & 34.053\\\\\\end{matrix}\\right)$" 372 | ], 373 | "text/plain": [ 374 | "Quantum object: dims = [[4, 4], [4, 4]], shape = (16, 16), type = oper, isherm = True\n", 375 | "Qobj data =\n", 376 | "[[ 0. 0. 0. 0. 0. 0.\n", 377 | " 0. 0. 0. 0. 0. 0.\n", 378 | " 0. 0. 0. 0. ]\n", 379 | " [ 0. 7.073 0. 0. 0.1 0.\n", 380 | " 0. 0. 0.04949747 0. 0. 0.\n", 381 | " 0. 0. 0. 0. ]\n", 382 | " [ 0. 0. 14.116 0. 0. 0.14142136\n", 383 | " 0. 0. 0. 0.07 0. 0.\n", 384 | " 0. 0. 0. 0. ]\n", 385 | " [ 0. 0. 0. 21.129 0. 0.\n", 386 | " 0.17320508 0. 0. 0. 0.08573214 0.\n", 387 | " 0. 0. 0. 0. ]\n", 388 | " [ 0. 0.1 0. 0. 4.284 0.\n", 389 | " 0. 0. 0. 0. 0. 0.\n", 390 | " 0. 0. 0. 0. ]\n", 391 | " [ 0. 0. 0.14142136 0. 0. 11.367\n", 392 | " 0. 0. 0.14142136 0. 0. 0.\n", 393 | " 0.08573214 0. 0. 0. ]\n", 394 | " [ 0. 0. 0. 0.17320508 0. 0.\n", 395 | " 18.42 0. 0. 0.2 0. 0.\n", 396 | " 0. 0.12124356 0. 0. ]\n", 397 | " [ 0. 0. 0. 0. 0. 0.\n", 398 | " 0. 25.443 0. 0. 0.24494897 0.\n", 399 | " 0. 0. 0.14849242 0. ]\n", 400 | " [ 0. 0.04949747 0. 0. 0. 0.14142136\n", 401 | " 0. 0. 8.562 0. 0. 0.\n", 402 | " 0. 0. 0. 0. ]\n", 403 | " [ 0. 0. 0.07 0. 0. 0.\n", 404 | " 0.2 0. 0. 15.655 0. 0.\n", 405 | " 0.17320508 0. 0. 0. ]\n", 406 | " [ 0. 0. 0. 0.08573214 0. 0.\n", 407 | " 0. 0.24494897 0. 0. 22.718 0.\n", 408 | " 0. 0.24494897 0. 0. ]\n", 409 | " [ 0. 0. 0. 0. 0. 0.\n", 410 | " 0. 0. 0. 0. 0. 29.751\n", 411 | " 0. 0. 0.3 0. ]\n", 412 | " [ 0. 0. 0. 0. 0. 0.08573214\n", 413 | " 0. 0. 0. 0.17320508 0. 0.\n", 414 | " 12.834 0. 0. 0. ]\n", 415 | " [ 0. 0. 0. 0. 0. 0.\n", 416 | " 0.12124356 0. 0. 0. 0.24494897 0.\n", 417 | " 0. 19.937 0. 0. ]\n", 418 | " [ 0. 0. 0. 0. 0. 0.\n", 419 | " 0. 0.14849242 0. 0. 0. 0.3\n", 420 | " 0. 0. 27.01 0. ]\n", 421 | " [ 0. 0. 0. 0. 0. 0.\n", 422 | " 0. 0. 0. 0. 0. 0.\n", 423 | " 0. 0. 0. 34.053 ]]" 424 | ] 425 | }, 426 | "execution_count": 7, 427 | "metadata": {}, 428 | "output_type": "execute_result" 429 | } 430 | ], 431 | "source": [ 432 | "dressed_hamiltonian = hilbertspace.hamiltonian()\n", 433 | "dressed_hamiltonian" 434 | ] 435 | }, 436 | { 437 | "attachments": {}, 438 | "cell_type": "markdown", 439 | "metadata": {}, 440 | "source": [ 441 | "Since the composite Hamiltonian is a `qutip.Qobj`, the eigenvalues and eigenvectors can be now be obtained via the usual QuTiP routine:" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 8, 447 | "metadata": { 448 | "ExecuteTime": { 449 | "end_time": "2020-03-31T11:44:06.327709Z", 450 | "start_time": "2020-03-31T11:44:06.314743Z" 451 | } 452 | }, 453 | "outputs": [ 454 | { 455 | "name": "stdout", 456 | "output_type": "stream", 457 | "text": [ 458 | "[0. 4.28041835 7.07493032 8.55652435]\n" 459 | ] 460 | } 461 | ], 462 | "source": [ 463 | "evals, evecs = dressed_hamiltonian.eigenstates(eigvals=4)\n", 464 | "print(evals)" 465 | ] 466 | }, 467 | { 468 | "attachments": {}, 469 | "cell_type": "markdown", 470 | "metadata": {}, 471 | "source": [ 472 | "### GUI use for `HilbertSpace` object creation\n", 473 | "\n", 474 | "As an alternative to the programmatic generation of a new `HilbertSpace` object, the following GUI-based creation process is supported:\n" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": 9, 480 | "metadata": {}, 481 | "outputs": [ 482 | { 483 | "data": { 484 | "application/vnd.jupyter.widget-view+json": { 485 | "model_id": "837dc29a244c4bbc9e89a8461ea2f6de", 486 | "version_major": 2, 487 | "version_minor": 0 488 | }, 489 | "text/plain": [ 490 | "Container(children=[Card(children=[CardTitle(children=['Create Hilbert Space'], layout=None), Container(childr…" 491 | ] 492 | }, 493 | "metadata": {}, 494 | "output_type": "display_data" 495 | } 496 | ], 497 | "source": [ 498 | "hilbertspace_gui = scq.HilbertSpace.create()" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": 10, 504 | "metadata": {}, 505 | "outputs": [ 506 | { 507 | "name": "stdout", 508 | "output_type": "stream", 509 | "text": [ 510 | "HilbertSpace: subsystems\n", 511 | "-------------------------\n", 512 | "\n" 513 | ] 514 | } 515 | ], 516 | "source": [ 517 | "print(hilbertspace_gui)" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": 11, 523 | "metadata": {}, 524 | "outputs": [ 525 | { 526 | "data": { 527 | "text/latex": [ 528 | "Quantum object: dims = [[1], [1]], shape = (1, 1), type = bra $ \\\\ \\left(\\begin{matrix}0.0\\\\\\end{matrix}\\right)$" 529 | ], 530 | "text/plain": [ 531 | "Quantum object: dims = [[1], [1]], shape = (1, 1), type = bra\n", 532 | "Qobj data =\n", 533 | "[[0.]]" 534 | ] 535 | }, 536 | "execution_count": 11, 537 | "metadata": {}, 538 | "output_type": "execute_result" 539 | } 540 | ], 541 | "source": [ 542 | "hilbertspace_gui.hamiltonian()" 543 | ] 544 | }, 545 | { 546 | "attachments": {}, 547 | "cell_type": "markdown", 548 | "metadata": {}, 549 | "source": [ 550 | "We can see that it indeed corresponds to the Hamiltonian created programatically:" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": 12, 556 | "metadata": {}, 557 | "outputs": [ 558 | { 559 | "data": { 560 | "text/plain": [ 561 | "False" 562 | ] 563 | }, 564 | "execution_count": 12, 565 | "metadata": {}, 566 | "output_type": "execute_result" 567 | } 568 | ], 569 | "source": [ 570 | "hilbertspace_gui.hamiltonian() == dressed_hamiltonian" 571 | ] 572 | }, 573 | { 574 | "attachments": {}, 575 | "cell_type": "markdown", 576 | "metadata": {}, 577 | "source": [ 578 | "### Spectrum lookup and converting between bare and dressed indices\n", 579 | "\n", 580 | "In the dispersive regime where bare states don't hybridize too much, it may be useful to convert between dressed states and their closest product bare states as physical interpretation may be easier. To use lookup functions for state indices, energies and states, first generate the lookup table via `generate_lookup()`:" 581 | ] 582 | }, 583 | { 584 | "cell_type": "code", 585 | "execution_count": 13, 586 | "metadata": { 587 | "ExecuteTime": { 588 | "end_time": "2020-03-31T11:44:10.103117Z", 589 | "start_time": "2020-03-31T11:44:10.030938Z" 590 | } 591 | }, 592 | "outputs": [], 593 | "source": [ 594 | "hilbertspace.generate_lookup()" 595 | ] 596 | }, 597 | { 598 | "attachments": {}, 599 | "cell_type": "markdown", 600 | "metadata": {}, 601 | "source": [ 602 | "We can first print the bare energies of the two Kerr oscillators:" 603 | ] 604 | }, 605 | { 606 | "cell_type": "code", 607 | "execution_count": 14, 608 | "metadata": { 609 | "ExecuteTime": { 610 | "end_time": "2020-03-31T11:44:13.722890Z", 611 | "start_time": "2020-03-31T11:44:13.715941Z" 612 | } 613 | }, 614 | "outputs": [ 615 | { 616 | "name": "stdout", 617 | "output_type": "stream", 618 | "text": [ 619 | "[ 0. 4.284 8.562 12.834]\n", 620 | "[ 0. 7.073 14.116 21.129]\n" 621 | ] 622 | } 623 | ], 624 | "source": [ 625 | "print(hilbertspace.bare_eigenvals(osc1))\n", 626 | "print(hilbertspace.bare_eigenvals(osc2))" 627 | ] 628 | }, 629 | { 630 | "attachments": {}, 631 | "cell_type": "markdown", 632 | "metadata": {}, 633 | "source": [ 634 | "Next, we can lookup the closest bare product state to the dressed state with index `8` with `bare_index()`, which corresponds to 1 excitation in the first Kerr oscillator and 2 excitations in the second." 635 | ] 636 | }, 637 | { 638 | "cell_type": "code", 639 | "execution_count": 15, 640 | "metadata": { 641 | "ExecuteTime": { 642 | "end_time": "2020-03-31T11:44:16.331869Z", 643 | "start_time": "2020-03-31T11:44:16.324918Z" 644 | } 645 | }, 646 | "outputs": [ 647 | { 648 | "data": { 649 | "text/plain": [ 650 | "(1, 2)" 651 | ] 652 | }, 653 | "execution_count": 15, 654 | "metadata": {}, 655 | "output_type": "execute_result" 656 | } 657 | ], 658 | "source": [ 659 | "hilbertspace.bare_index(8)" 660 | ] 661 | }, 662 | { 663 | "attachments": {}, 664 | "cell_type": "markdown", 665 | "metadata": {}, 666 | "source": [ 667 | "Conversely, we can verify that the bare product state (1,2) most closely matches the dressed state with index `8`" 668 | ] 669 | }, 670 | { 671 | "cell_type": "code", 672 | "execution_count": 16, 673 | "metadata": { 674 | "ExecuteTime": { 675 | "end_time": "2020-03-31T11:44:19.844481Z", 676 | "start_time": "2020-03-31T11:44:19.837499Z" 677 | } 678 | }, 679 | "outputs": [ 680 | { 681 | "data": { 682 | "text/plain": [ 683 | "8" 684 | ] 685 | }, 686 | "execution_count": 16, 687 | "metadata": {}, 688 | "output_type": "execute_result" 689 | } 690 | ], 691 | "source": [ 692 | "hilbertspace.dressed_index((1,2))" 693 | ] 694 | }, 695 | { 696 | "attachments": {}, 697 | "cell_type": "markdown", 698 | "metadata": {}, 699 | "source": [ 700 | "Finally, we can get the eigenenergy for dressed index `8` using `energy_by_dressed_index()`:" 701 | ] 702 | }, 703 | { 704 | "cell_type": "code", 705 | "execution_count": 17, 706 | "metadata": { 707 | "ExecuteTime": { 708 | "end_time": "2020-03-31T11:44:52.454767Z", 709 | "start_time": "2020-03-31T11:44:52.446792Z" 710 | } 711 | }, 712 | "outputs": [ 713 | { 714 | "data": { 715 | "text/plain": [ 716 | "18.413688985491923" 717 | ] 718 | }, 719 | "execution_count": 17, 720 | "metadata": {}, 721 | "output_type": "execute_result" 722 | } 723 | ], 724 | "source": [ 725 | "hilbertspace.energy_by_dressed_index(8)" 726 | ] 727 | }, 728 | { 729 | "attachments": {}, 730 | "cell_type": "markdown", 731 | "metadata": {}, 732 | "source": [ 733 | "## Sweeping over an external parameter\n", 734 | "\n", 735 | "Equipped with a programmatic interface to explore interactions between subsystems, scqubits provides the class `ParameterSweep` to facilitate computation of spectra as function of an external parameter. See the [example notebook](./demo_parametersweep.ipynb) for `ParameterSweep` to explore sweeps and visualizing sweep data." 736 | ] 737 | }, 738 | { 739 | "cell_type": "code", 740 | "execution_count": null, 741 | "metadata": {}, 742 | "outputs": [], 743 | "source": [] 744 | }, 745 | { 746 | "cell_type": "code", 747 | "execution_count": null, 748 | "metadata": {}, 749 | "outputs": [], 750 | "source": [] 751 | } 752 | ], 753 | "metadata": { 754 | "celltoolbar": "Initialisation Cell", 755 | "kernelspec": { 756 | "display_name": "Python 3 (ipykernel)", 757 | "language": "python", 758 | "name": "python3" 759 | }, 760 | "language_info": { 761 | "codemirror_mode": { 762 | "name": "ipython", 763 | "version": 3 764 | }, 765 | "file_extension": ".py", 766 | "mimetype": "text/x-python", 767 | "name": "python", 768 | "nbconvert_exporter": "python", 769 | "pygments_lexer": "ipython3", 770 | "version": "3.12.3" 771 | }, 772 | "toc": { 773 | "base_numbering": 1, 774 | "nav_menu": {}, 775 | "number_sections": false, 776 | "sideBar": true, 777 | "skip_h1_title": true, 778 | "title_cell": "Table of Contents", 779 | "title_sidebar": "Contents", 780 | "toc_cell": false, 781 | "toc_position": {}, 782 | "toc_section_display": true, 783 | "toc_window_display": true 784 | }, 785 | "varInspector": { 786 | "cols": { 787 | "lenName": 16, 788 | "lenType": 16, 789 | "lenVar": 40 790 | }, 791 | "kernels_config": { 792 | "python": { 793 | "delete_cmd_postfix": "", 794 | "delete_cmd_prefix": "del ", 795 | "library": "var_list.py", 796 | "varRefreshCmd": "print(var_dic_list())" 797 | }, 798 | "r": { 799 | "delete_cmd_postfix": ") ", 800 | "delete_cmd_prefix": "rm(", 801 | "library": "var_list.r", 802 | "varRefreshCmd": "cat(var_dic_list()) " 803 | } 804 | }, 805 | "types_to_exclude": [ 806 | "module", 807 | "function", 808 | "builtin_function_or_method", 809 | "instance", 810 | "_Feature" 811 | ], 812 | "window_display": false 813 | }, 814 | "widgets": { 815 | "application/vnd.jupyter.widget-state+json": { 816 | "state": {}, 817 | "version_major": 2, 818 | "version_minor": 0 819 | } 820 | } 821 | }, 822 | "nbformat": 4, 823 | "nbformat_minor": 4 824 | } 825 | -------------------------------------------------------------------------------- /examples/demo_qutip_fluxoniumcz.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Fluxonium CZ gate tutorial\n", 8 | "\n", 9 | "B. McDonough\n", 10 | "\n", 11 | "This notebook provides a tutorial on using scQubits to simulate the CZ-gate on a coupled pair of fluxonium qubits described by Nesterov et al. in [Microwave-Activated Controlled-Z Gate for Fixed-Frequency Fluxonium Qubits.](https://arxiv.org/abs/1802.03095)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "** NOTE: With version 5 of `qutip` the qip submodule has to be installed separately, e.g. with `pip install qutip-qip`" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "Capacitive coupling of two fluxonium qubits $A$ and $B$ results in the addition of the term $g \\hat n_A \\hat n_B$ ($\\hat n$ is the charge operator) to the Hamiltonian. This coupling shifts the energy levels so that the dressed (coupled) $\\omega_{01 \\to 02}$ transition frequency is detuned from the dressed (coupled) $\\omega_{11 \\to 12}$ transition frequency. Without the capacitive coupling between two qubits, the bare (uncoupled) $\\omega_{01 \\to 02}$ transition frequency is the same as the bare (uncoupled) $\\omega_{11 \\to 12}$ transition frequency. This allows the $|11\\rangle \\to |12\\rangle$ transition to be Rabi driven without causing leakage from other states in the computational space. Following Nesterov et al., we consider a case of selective drive on only qubit $B$, which is expressed as the term $H_d = f(t)\\cos(\\omega_d t)\\hat n_B$ added to the Hamiltonian.\n", 26 | "\n", 27 | "Driving the $|11\\rangle\\to|12\\rangle$ transition for a full period of Rabi oscillation causes the $|11\\rangle$ state to acquire a phase of $e^{i\\pi}=-1$, without affecting the other states in the computational subspace. This results in the application of $CZ = \\operatorname{diag}(1,1,1,-1)$ up to single-qubit $Z$ gates.\n", 28 | "\n", 29 | "The Hamiltonian of the two coupled fluxonia and the drive is\n", 30 | "$$\n", 31 | "H = 4E_{CA}\\hat n_A - E_{JA}\\cos(\\hat \\phi_A-\\pi) + \\frac{1}{2} E_{LA}\\hat \\phi_A^2 + g\\hat n_A\\hat n_B + 4E_{CB}\\hat n_B - E_{JB}\\cos(\\hat \\phi_B-\\pi) + \\frac{1}{2}E_{LB}\\hat \\phi_B^2 + f(t)\\cos(w_dt)\\hat n_B\n", 32 | "$$\n", 33 | "\n", 34 | "where all of the notations follow closely the cited paper." 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 16, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "import scqubits as scq\n", 44 | "import qutip as qt\n", 45 | "import numpy as np\n", 46 | "from matplotlib import pyplot as plt\n", 47 | "from qutip.qip.operations import rz, cz_gate\n", 48 | "import cmath\n", 49 | "\n", 50 | "# experimental values borrowed from\n", 51 | "# [https://arxiv.org/abs/1802.03095]\n", 52 | "# define fluxonium A\n", 53 | "qbta = scq.Fluxonium(\n", 54 | " EC=1.5,\n", 55 | " EJ=5.5,\n", 56 | " EL=1.0,\n", 57 | " flux=0.5, # flux frustration point\n", 58 | " cutoff=110,\n", 59 | " truncated_dim=10,\n", 60 | ")\n", 61 | "\n", 62 | "# define fluxonium B\n", 63 | "qbtb = scq.Fluxonium(\n", 64 | " EC=1.2,\n", 65 | " EJ=5.7,\n", 66 | " EL=1.0,\n", 67 | " flux=0.5,\n", 68 | " cutoff=110,\n", 69 | " truncated_dim=10,\n", 70 | ")\n", 71 | "\n", 72 | "# define the common Hilbert space\n", 73 | "hilbertspace = scq.HilbertSpace([qbta, qbtb])\n", 74 | "\n", 75 | "# add interaction between two qubits\n", 76 | "hilbertspace.add_interaction(\n", 77 | " g_strength=0.15,\n", 78 | " op1=qbta.n_operator,\n", 79 | " op2=qbtb.n_operator,\n", 80 | ")\n", 81 | "\n", 82 | "# generate spectrum lookup table\n", 83 | "hilbertspace.generate_lookup()" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "## Drive simulation functions" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 5, 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "# get the transition frequency between two states specified by dressed indices\n", 100 | "def transition_frequency(s0: int, s1: int) -> float:\n", 101 | " return (\n", 102 | " (\n", 103 | " hilbertspace.energy_by_dressed_index(s1)\n", 104 | " - hilbertspace.energy_by_dressed_index(s0)\n", 105 | " )\n", 106 | " * 2\n", 107 | " * np.pi\n", 108 | " )" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "## Truncation\n", 116 | "The efficiency of the simulation is greatly improved by truncating the operators. The truncation happens in two steps:\n", 117 | "1) The first truncation is controlled by setting the `truncated_dim` parameter in the subsystem initialization, which determines the dimension used in diagonalizing the Hamiltonian. Setting these too low can result in an unphysical simulation. Even if energy levels above the truncation are not explicitly involved, they can still drastically affect the matrix elements of the operators. \n", 118 | "\n", 119 | "2) Once the matrix elements and eigenvalues have been obtained, the operators can be truncated further. This truncation can greatly improve the runtime of the simulation. " 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 6, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "# The matrix representations can be truncated further for the simulation\n", 129 | "total_truncation = 20\n", 130 | "\n", 131 | "# truncate operators to desired dimension\n", 132 | "def truncate(operator: qt.Qobj, dimension: int) -> qt.Qobj:\n", 133 | " return qt.Qobj(operator[:dimension, :dimension])" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "## States and operators " 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 7, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "# get the representation of the n_b operator in the dressed eigenbasis of the composite system\n", 150 | "n_b = hilbertspace.op_in_dressed_eigenbasis((qbtb.n_operator, qbtb))\n", 151 | "# truncate the operator after expressing in the dressed basis to speed up the simulation\n", 152 | "n_b = truncate(n_b, total_truncation)" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 8, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "# convert the product states to the closes eigenstates of the dressed system\n", 162 | "product_states = [(0, 0), (1, 0), (0,1), (1, 1), (2, 1)]\n", 163 | "idxs = [hilbertspace.dressed_index((s1, s2)) for (s1, s2) in product_states]\n", 164 | "states = [qt.basis(total_truncation, idx) for idx in idxs]\n", 165 | "\n", 166 | "# The computational subspace is spanned by the first 4 states\n", 167 | "computational_subspace = states[:4]" 168 | ] 169 | }, 170 | { 171 | "cell_type": "markdown", 172 | "metadata": {}, 173 | "source": [ 174 | "## Units\n", 175 | "scQubits natively reports energy in GHz, units of frequency. The frequency $f$ and the radial frequency $\\omega$ are related via\n", 176 | "$$\n", 177 | "\\hbar \\omega = h f\n", 178 | "$$\n", 179 | "The constants $h$ and $\\hbar$ are related by $h = 2\\pi \\hbar$, so the angular frequency in units of radians per nanosecond is given by $\\omega = 2\\pi f$. For this reason, the energies obtained from diagonalization and the matrix elements need to be multiplied by $2\\pi$ for simulating in QuTiP." 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 9, 185 | "metadata": {}, 186 | "outputs": [], 187 | "source": [ 188 | "# get dressed state 11 to 12 transition frequency\n", 189 | "omega_1112 = transition_frequency(idxs[3], idxs[4])\n", 190 | "\n", 191 | "# Gaussian pulse parameters optimized by hand\n", 192 | "A = 0.022 # GHz\n", 193 | "tg = 100 # ns\n", 194 | "\n", 195 | "#Gaussian pulse envelope\n", 196 | "def drive_coeff(t: float, args: dict) -> float:\n", 197 | " return A * np.exp(-8 * t * (t - tg) / tg**2) * np.cos(omega_1112 * t)\n", 198 | "\n", 199 | "# Hamiltonian in dressed eigenbasis\n", 200 | "(evals,) = hilbertspace[\"evals\"]\n", 201 | "# The factor of 2pi converts the energy to GHz so that the time is in units of ns\n", 202 | "diag_dressed_hamiltonian = (\n", 203 | " 2 * np.pi * qt.Qobj(np.diag(evals),\n", 204 | " dims=[hilbertspace.subsystem_dims] * 2)\n", 205 | ")\n", 206 | "diag_dressed_hamiltonian_trunc = truncate(diag_dressed_hamiltonian, total_truncation)\n", 207 | "\n", 208 | "# time-dependent drive Hamiltonian\n", 209 | "H_qbt_drive = [\n", 210 | " diag_dressed_hamiltonian_trunc,\n", 211 | " [2 * np.pi * n_b, drive_coeff], # driving through the resonator\n", 212 | "]" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "## Drive Visualization" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 10, 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "data": { 229 | "text/plain": [ 230 | "Text(0.5, 0, 't (ns)')" 231 | ] 232 | }, 233 | "execution_count": 10, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | }, 237 | { 238 | "data": { 239 | "application/pdf": "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MjMzIF0gL0ZvbnRNYXRyaXggWyAwLjAwMSAwIDAgMC4wMDEgMCAwIF0KL0NoYXJQcm9jcyAxNiAwIFIKL0VuY29kaW5nIDw8IC9UeXBlIC9FbmNvZGluZwovRGlmZmVyZW5jZXMgWyAzMiAvc3BhY2UgNDAgL3BhcmVubGVmdCAvcGFyZW5yaWdodCA0NiAvcGVyaW9kIDQ4IC96ZXJvIC9vbmUgL3R3byAvdGhyZWUKL2ZvdXIgNTQgL3NpeCAvc2V2ZW4gL2VpZ2h0IDk3IC9hIDEwNSAvaSAxMDggL2wgMTEwIC9uIC9vIC9wIDExNSAvcyAvdCAvdQoxMjQgL2JhciBdCj4+Ci9XaWR0aHMgMTMgMCBSID4+CmVuZG9iagoxNCAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0ZvbnROYW1lIC9CTVFRRFYrRGVqYVZ1U2FucyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFsgLTEwMjEgLTQ2MyAxNzk0IDEyMzMgXSAvQXNjZW50IDkyOSAvRGVzY2VudCAtMjM2IC9DYXBIZWlnaHQgMAovWEhlaWdodCAwIC9JdGFsaWNBbmdsZSAwIC9TdGVtViAwIC9NYXhXaWR0aCAxMzQyID4+CmVuZG9iagoxMyAwIG9iagpbIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwCjYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgMzE4IDQwMSA0NjAgODM4IDYzNgo5NTAgNzgwIDI3NSAzOTAgMzkwIDUwMCA4MzggMzE4IDM2MSAzMTggMzM3IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYKNjM2IDYzNiAzMzcgMzM3IDgzOCA4MzggODM4IDUzMSAxMDAwIDY4NCA2ODYgNjk4IDc3MCA2MzIgNTc1IDc3NSA3NTIgMjk1CjI5NSA2NTYgNTU3IDg2MyA3NDggNzg3IDYwMyA3ODcgNjk1IDYzNSA2MTEgNzMyIDY4NCA5ODkgNjg1IDYxMSA2ODUgMzkwIDMzNwozOTAgODM4IDUwMCA1MDAgNjEzIDYzNSA1NTAgNjM1IDYxNSAzNTIgNjM1IDYzNCAyNzggMjc4IDU3OSAyNzggOTc0IDYzNCA2MTIKNjM1IDYzNSA0MTEgNTIxIDM5MiA2MzQgNTkyIDgxOCA1OTIgNTkyIDUyNSA2MzYgMzM3IDYzNiA4MzggNjAwIDYzNiA2MDAgMzE4CjM1MiA1MTggMTAwMCA1MDAgNTAwIDUwMCAxMzQyIDYzNSA0MDAgMTA3MCA2MDAgNjg1IDYwMCA2MDAgMzE4IDMxOCA1MTggNTE4CjU5MCA1MDAgMTAwMCA1MDAgMTAwMCA1MjEgNDAwIDEwMjMgNjAwIDUyNSA2MTEgMzE4IDQwMSA2MzYgNjM2IDYzNiA2MzYgMzM3CjUwMCA1MDAgMTAwMCA0NzEgNjEyIDgzOCAzNjEgMTAwMCA1MDAgNTAwIDgzOCA0MDEgNDAxIDUwMCA2MzYgNjM2IDMxOCA1MDAKNDAxIDQ3MSA2MTIgOTY5IDk2OSA5NjkgNTMxIDY4NCA2ODQgNjg0IDY4NCA2ODQgNjg0IDk3NCA2OTggNjMyIDYzMiA2MzIgNjMyCjI5NSAyOTUgMjk1IDI5NSA3NzUgNzQ4IDc4NyA3ODcgNzg3IDc4NyA3ODcgODM4IDc4NyA3MzIgNzMyIDczMiA3MzIgNjExIDYwNQo2MzAgNjEzIDYxMyA2MTMgNjEzIDYxMyA2MTMgOTgyIDU1MCA2MTUgNjE1IDYxNSA2MTUgMjc4IDI3OCAyNzggMjc4IDYxMiA2MzQKNjEyIDYxMiA2MTIgNjEyIDYxMiA4MzggNjEyIDYzNCA2MzQgNjM0IDYzNCA1OTIgNjM1IDU5MiBdCmVuZG9iagoxNiAwIG9iago8PCAvYSAxNyAwIFIgL2JhciAxOCAwIFIgL2VpZ2h0IDE5IDAgUiAvZm91ciAyMCAwIFIgL2kgMjEgMCBSIC9sIDIyIDAgUgovbiAyMyAwIFIgL28gMjQgMCBSIC9vbmUgMjUgMCBSIC9wIDI2IDAgUiAvcGFyZW5sZWZ0IDI3IDAgUgovcGFyZW5yaWdodCAyOCAwIFIgL3BlcmlvZCAyOSAwIFIgL3MgMzAgMCBSIC9zZXZlbiAzMSAwIFIgL3NpeCAzMiAwIFIKL3NwYWNlIDMzIDAgUiAvdCAzNCAwIFIgL3RocmVlIDM1IDAgUiAvdHdvIDM2IDAgUiAvdSAzNyAwIFIgL3plcm8gMzkgMCBSID4+CmVuZG9iagozIDAgb2JqCjw8IC9GMSAxNSAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0ExIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDAgL2NhIDEgPj4KL0EyIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDEgL2NhIDEgPj4KL0EzIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDAuOCAvY2EgMC44ID4+ID4+CmVuZG9iago1IDAgb2JqCjw8ID4+CmVuZG9iago2IDAgb2JqCjw8ID4+CmVuZG9iago3IDAgb2JqCjw8IC9GMS1EZWphVnVTYW5zLXVuaTI3RTkgMzggMCBSID4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlcyAvS2lkcyBbIDExIDAgUiBdIC9Db3VudCAxID4+CmVuZG9iago0MCAwIG9iago8PCAvQ3JlYXRvciAoTWF0cGxvdGxpYiB2My44LjQsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcpCi9Qcm9kdWNlciAoTWF0cGxvdGxpYiBwZGYgYmFja2VuZCB2My44LjQpCi9DcmVhdGlvbkRhdGUgKEQ6MjAyNDA1MTYxODQ4NTctMDQnMDAnKSA+PgplbmRvYmoKeHJlZgowIDQxCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNiAwMDAwMCBuIAowMDAwMDEyMDExIDAwMDAwIG4gCjAwMDAwMTE3NDQgMDAwMDAgbiAKMDAwMDAxMTc3NiAwMDAwMCBuIAowMDAwMDExOTE4IDAwMDAwIG4gCjAwMDAwMTE5MzkgMDAwMDAgbiAKMDAwMDAxMTk2MCAwMDAwMCBuIAowMDAwMDAwMDY1IDAwMDAwIG4gCjAwMDAwMDAzNDMgMDAwMDAgbiAKMDAwMDAwNDAzOSAwMDAwMCBuIAowMDAwMDAwMjA4IDAwMDAwIG4gCjAwMDAwMDQwMTggMDAwMDAgbiAKMDAwMDAxMDM5NyAwMDAwMCBuIAowMDAwMDEwMTkwIDAwMDAwIG4gCjAwMDAwMDk3MjcgMDAwMDAgbiAKMDAwMDAxMTQ1MCAwMDAwMCBuIAowMDAwMDA0MDU5IDAwMDAwIG4gCjAwMDAwMDQ0MzkgMDAwMDAgbiAKMDAwMDAwNDU2NyAwMDAwMCBuIAowMDAwMDA1MDM1IDAwMDAwIG4gCjAwMDAwMDUyMDEgMDAwMDAgbiAKMDAwMDAwNTM0NSAwMDAwMCBuIAowMDAwMDA1NDY0IDAwMDAwIG4gCjAwMDAwMDU3MDAgMDAwMDAgbiAKMDAwMDAwNTk5MSAwMDAwMCBuIAowMDAwMDA2MTQ2IDAwMDAwIG4gCjAwMDAwMDY0NTggMDAwMDAgbiAKMDAwMDAwNjY4MSAwMDAwMCBuIAowMDAwMDA2OTA1IDAwMDAwIG4gCjAwMDAwMDcwMjggMDAwMDAgbiAKMDAwMDAwNzQzNSAwMDAwMCBuIAowMDAwMDA3NTc3IDAwMDAwIG4gCjAwMDAwMDc5NzAgMDAwMDAgbiAKMDAwMDAwODA2MCAwMDAwMCBuIAowMDAwMDA4MjY2IDAwMDAwIG4gCjAwMDAwMDg2NzkgMDAwMDAgbiAKMDAwMDAwOTAwMyAwMDAwMCBuIAowMDAwMDA5MjUwIDAwMDAwIG4gCjAwMDAwMDk0MzkgMDAwMDAgbiAKMDAwMDAxMjA3MSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQxIC9Sb290IDEgMCBSIC9JbmZvIDQwIDAgUiA+PgpzdGFydHhyZWYKMTIyMjgKJSVFT0YK", 240 | "image/svg+xml": [ 241 | "\n", 242 | "\n", 244 | "\n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " 2024-05-16T18:48:57.505146\n", 250 | " image/svg+xml\n", 251 | " \n", 252 | " \n", 253 | " Matplotlib v3.8.4, https://matplotlib.org/\n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 569 | " \n", 570 | " \n", 583 | " \n", 602 | " \n", 633 | " \n", 646 | " \n", 647 | " \n", 648 | " \n", 649 | " \n", 650 | " \n", 651 | " \n", 652 | " \n", 653 | " \n", 654 | " \n", 655 | " \n", 656 | " \n", 657 | " \n", 658 | " \n", 659 | " \n", 660 | " \n", 663 | " \n", 664 | " \n", 665 | " \n", 666 | " \n", 667 | " \n", 668 | " \n", 669 | " \n", 670 | " \n", 671 | " \n", 672 | " \n", 679 | " \n", 680 | " \n", 681 | " \n", 682 | " \n", 683 | " \n", 684 | " \n", 685 | " \n", 686 | " \n", 687 | " \n", 688 | " \n", 689 | " \n", 690 | " \n", 691 | " \n", 692 | " \n", 693 | " \n", 694 | " \n", 695 | " \n", 696 | " \n", 697 | " \n", 698 | " \n", 699 | " \n", 700 | " \n", 701 | " \n", 702 | " \n", 703 | " \n", 704 | " \n", 705 | " \n", 706 | " \n", 707 | " \n", 708 | " \n", 709 | " \n", 710 | " \n", 711 | " \n", 712 | " \n", 713 | " \n", 714 | " \n", 715 | " \n", 716 | " \n", 717 | " \n", 718 | " \n", 719 | " \n", 720 | " \n", 721 | " \n", 722 | " \n", 723 | " \n", 724 | " \n", 725 | " \n", 726 | " \n", 727 | " \n", 728 | " \n", 729 | " \n", 730 | " \n", 731 | " \n", 732 | " \n", 733 | " \n", 734 | " \n", 735 | " \n", 736 | " \n", 737 | " \n", 738 | " \n", 739 | " \n", 740 | " \n", 741 | " \n", 742 | " \n", 743 | " \n", 744 | " \n", 745 | " \n", 746 | " \n", 747 | " \n", 748 | " \n", 749 | " \n", 750 | " \n", 751 | " \n", 752 | " \n", 753 | " \n", 754 | " \n", 755 | " \n", 756 | " \n", 757 | " \n", 758 | " \n", 759 | " \n", 760 | " \n", 761 | " \n", 762 | " \n", 763 | " \n", 764 | " \n", 765 | " \n", 791 | " \n", 812 | " \n", 834 | " \n", 841 | " \n", 874 | " \n", 887 | " \n", 888 | " \n", 889 | " \n", 890 | " \n", 891 | " \n", 892 | " \n", 893 | " \n", 894 | " \n", 895 | " \n", 896 | " \n", 897 | " \n", 898 | " \n", 899 | " \n", 900 | " \n", 901 | " \n", 902 | " \n", 906 | " \n", 907 | " \n", 908 | " \n", 912 | " \n", 913 | " \n", 914 | " \n", 918 | " \n", 919 | " \n", 920 | " \n", 1057 | " \n", 1058 | " \n", 1059 | " \n", 1161 | " \n", 1162 | " \n", 1163 | " \n", 1166 | " \n", 1167 | " \n", 1168 | " \n", 1171 | " \n", 1172 | " \n", 1173 | " \n", 1176 | " \n", 1177 | " \n", 1178 | " \n", 1181 | " \n", 1182 | " \n", 1183 | " \n", 1184 | " \n", 1195 | " \n", 1196 | " \n", 1197 | " \n", 1201 | " \n", 1202 | " \n", 1203 | " \n", 1204 | " \n", 1205 | " \n", 1206 | " \n", 1213 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | " \n", 1251 | " \n", 1252 | " \n", 1253 | " \n", 1254 | " \n", 1255 | " \n", 1256 | " \n", 1257 | " \n", 1261 | " \n", 1262 | " \n", 1263 | " \n", 1264 | " \n", 1265 | " \n", 1266 | " \n", 1298 | " \n", 1299 | " \n", 1300 | " \n", 1301 | " \n", 1302 | " \n", 1303 | " \n", 1304 | " \n", 1305 | " \n", 1309 | " \n", 1310 | " \n", 1311 | " \n", 1312 | " \n", 1313 | " \n", 1314 | " \n", 1324 | " \n", 1325 | " \n", 1326 | " \n", 1327 | " \n", 1328 | " \n", 1329 | " \n", 1330 | " \n", 1331 | " \n", 1332 | " \n", 1333 | " \n", 1334 | " \n", 1335 | " \n", 1336 | " \n", 1337 | " \n", 1338 | "\n" 1339 | ], 1340 | "text/plain": [ 1341 | "
" 1342 | ] 1343 | }, 1344 | "metadata": {}, 1345 | "output_type": "display_data" 1346 | } 1347 | ], 1348 | "source": [ 1349 | "# array of time list\n", 1350 | "tlist = np.linspace(0, 120, 200) # total time\n", 1351 | "\n", 1352 | "# This simulation is just for viewing the affect of the pulse\n", 1353 | "result = qt.sesolve(\n", 1354 | " H_qbt_drive,\n", 1355 | " qt.basis(20, hilbertspace.dressed_index(product_states[3])),\n", 1356 | " tlist,\n", 1357 | " e_ops=[state * state.dag() for state in states]\n", 1358 | ")\n", 1359 | "\n", 1360 | "for idx, res in zip(idxs, result.expect):\n", 1361 | " plt.plot(tlist, res, label=r\"$|%u\\rangle$\" % (idx))\n", 1362 | "\n", 1363 | "plt.legend()\n", 1364 | "plt.ylabel(\"population\")\n", 1365 | "plt.xlabel(\"t (ns)\")" 1366 | ] 1367 | }, 1368 | { 1369 | "cell_type": "markdown", 1370 | "metadata": {}, 1371 | "source": [ 1372 | "## Propagator calculation" 1373 | ] 1374 | }, 1375 | { 1376 | "cell_type": "code", 1377 | "execution_count": 11, 1378 | "metadata": {}, 1379 | "outputs": [], 1380 | "source": [ 1381 | "# get the propagator at the final time step\n", 1382 | "prop = qt.propagator(H_qbt_drive, tlist)[-1] \n", 1383 | "\n", 1384 | "# truncate the propagator to the computational subspace\n", 1385 | "Uc = qt.Qobj(\n", 1386 | " [\n", 1387 | " [prop.matrix_element(s1, s2) for s1 in computational_subspace]\n", 1388 | " for s2 in computational_subspace\n", 1389 | " ]\n", 1390 | ")" 1391 | ] 1392 | }, 1393 | { 1394 | "cell_type": "code", 1395 | "execution_count": 12, 1396 | "metadata": {}, 1397 | "outputs": [], 1398 | "source": [ 1399 | "# Factor global phase so that upper-left corner of matrix is real\n", 1400 | "def remove_global_phase(op):\n", 1401 | " return op * np.exp(-1j * cmath.phase(op[0, 0]))\n", 1402 | "\n", 1403 | "# The process for obtaining the Z rotations is taken from page 3 of Nesterov et al., at the\n", 1404 | "# bottom of the paragraph beginning, \"To model gate operation...\"\n", 1405 | "def dphi(state):\n", 1406 | " return -np.angle(prop.matrix_element(state, state)) + np.angle(\n", 1407 | " prop.matrix_element(states[0], states[0])\n", 1408 | " )" 1409 | ] 1410 | }, 1411 | { 1412 | "cell_type": "code", 1413 | "execution_count": 13, 1414 | "metadata": {}, 1415 | "outputs": [ 1416 | { 1417 | "data": { 1418 | "text/latex": [ 1419 | "Quantum object: dims=[[2, 2], [2, 2]], shape=(4, 4), type='oper', dtype=Dense, isherm=False$$\\left(\\begin{array}{cc}1.000 & -7.352\\times10^{ -8 } & -3.995\\times10^{ -5 } & -8.539\\times10^{ -7 }\\\\7.019\\times10^{ -8 } & 0.996 & 2.175\\times10^{ -6 } & 7.574\\times10^{ -5 }\\\\3.997\\times10^{ -5 } & -9.747\\times10^{ -7 } & 1.000 & 3.475\\times10^{ -6 }\\\\2.420\\times10^{ -7 } & 7.022\\times10^{ -5 } & 3.536\\times10^{ -6 } & (-0.978-0.200j)\\end{array}\\right)$$" 1420 | ], 1421 | "text/plain": [ 1422 | "Quantum object: dims=[[2, 2], [2, 2]], shape=(4, 4), type='oper', dtype=Dense, isherm=False\n", 1423 | "Qobj data =\n", 1424 | "[[ 9.99994455e-01+0.00000000e+00j -7.35238808e-08+9.49722580e-08j\n", 1425 | " -3.99462272e-05-2.18320016e-05j -8.53945610e-07+2.82838393e-08j]\n", 1426 | " [ 7.01936751e-08+9.48654372e-08j 9.95509035e-01+5.55111512e-17j\n", 1427 | " 2.17467831e-06-6.46723817e-06j 7.57435192e-05-2.00621542e-05j]\n", 1428 | " [ 3.99717809e-05-2.17849309e-05j -9.74653805e-07-3.01232462e-06j\n", 1429 | " 9.99609922e-01+1.66533454e-16j 3.47474459e-06+6.59966344e-07j]\n", 1430 | " [ 2.42005956e-07+1.48874649e-07j 7.02170941e-05+3.47803599e-05j\n", 1431 | " 3.53628225e-06+4.98055978e-08j -9.77712124e-01-2.00052682e-01j]]" 1432 | ] 1433 | }, 1434 | "execution_count": 13, 1435 | "metadata": {}, 1436 | "output_type": "execute_result" 1437 | } 1438 | ], 1439 | "source": [ 1440 | "# product of single-qubit Z-gates\n", 1441 | "Uz = remove_global_phase(qt.tensor(rz(dphi(states[2])), rz(dphi(states[1]))))\n", 1442 | "Uc_reshaped = qt.Qobj(Uc.data, dims=[[2, 2], [2, 2]])\n", 1443 | "Ucprime = remove_global_phase(Uz * Uc_reshaped)\n", 1444 | "Ucprime # result should be close to diag(1,1,1,-1)" 1445 | ] 1446 | }, 1447 | { 1448 | "cell_type": "code", 1449 | "execution_count": 14, 1450 | "metadata": {}, 1451 | "outputs": [ 1452 | { 1453 | "data": { 1454 | "text/plain": [ 1455 | "0.99047765240123" 1456 | ] 1457 | }, 1458 | "execution_count": 14, 1459 | "metadata": {}, 1460 | "output_type": "execute_result" 1461 | } 1462 | ], 1463 | "source": [ 1464 | "#fidelity measure given on page 3 of Nesterov et al.\n", 1465 | "((Ucprime.dag() * Ucprime).tr() + np.abs((Ucprime.dag() * cz_gate()).tr()) ** 2) / 20" 1466 | ] 1467 | }, 1468 | { 1469 | "cell_type": "code", 1470 | "execution_count": null, 1471 | "metadata": {}, 1472 | "outputs": [], 1473 | "source": [] 1474 | } 1475 | ], 1476 | "metadata": { 1477 | "kernelspec": { 1478 | "display_name": "Python 3 (ipykernel)", 1479 | "language": "python", 1480 | "name": "python3" 1481 | }, 1482 | "language_info": { 1483 | "codemirror_mode": { 1484 | "name": "ipython", 1485 | "version": 3 1486 | }, 1487 | "file_extension": ".py", 1488 | "mimetype": "text/x-python", 1489 | "name": "python", 1490 | "nbconvert_exporter": "python", 1491 | "pygments_lexer": "ipython3", 1492 | "version": "3.12.3" 1493 | }, 1494 | "vscode": { 1495 | "interpreter": { 1496 | "hash": "f7e1e6ad09d196a93f40716548eb447094128ac28363ee78c20c7751b30b0cbc" 1497 | } 1498 | } 1499 | }, 1500 | "nbformat": 4, 1501 | "nbformat_minor": 4 1502 | } 1503 | -------------------------------------------------------------------------------- /examples/demo_qutip_fluxoniumreset.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Driven composite systems and interface with QuTiP in scQubits\n", 8 | "\n", 9 | "Systems of interest in quantum computing generally involve mutual coupling between multiple quantum systems.\n", 10 | "By driving these individual subsystems, we can perform single- or multi-qubit gates.\n", 11 | "\n", 12 | "In the context of superconducting circuits, a common method of driving a circuit is to capacitively couple a voltage bias to one or multiple nodes of the circuit. \n", 13 | "By a proper choice of drive frequency, amplitude and envelope, logical operations can be achieved.\n", 14 | "\n", 15 | "The popular Python package QuTiP can be used to simulate the time dynamics of quantum systems. \n", 16 | "For the simulation of superconducting circuits, scQubits provides a transparent interface to QuTiP through the `HilbertSpace` class.\n", 17 | "\n", 18 | "These notebooks showcase how scQubits can be easily used to simulate dynamics of driven superconducting circuits through examples from the literature. The notebook\n", 19 | "`FluxoniumRestTutorial.ipynb` provides a tutorial for using scQubits to simulate the heavy-fluxonium initialization procedure described in [Universal fast flux control of a coherent, low-frequency qubit](https://journals.aps.org/prx/pdf/10.1103/PhysRevX.11.011010) by Zhang et al. The notebook `FluxoniumCZTutorial.ipynb` contains a tutorial for using scQubits to simulate the procedure for effecting a CZ-gate on a coupled pair of fluxonium qubits described by Nesterov et al. in [Microwave-Activated Controlled-Z Gate for Fixed-Frequency Fluxonium Qubits.](https://arxiv.org/abs/1802.03095)" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "# Heavy-fluxonium initialization tutorial\n", 27 | "\n", 28 | "B. McDonough\n", 29 | "\n", 30 | "This notebook provides a tutorial for using scQubits to simulate the heavy-fluxonium initialization procedure described in [Universal fast flux control of a coherent, low-frequency qubit](https://journals.aps.org/prx/pdf/10.1103/PhysRevX.11.011010) by Zhang et al." 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "For a typical heavy-fluxonium qubit, the frequency of the transition between the first two energy levels is small in comparison to the temperature of the bath. Thus the qubit relaxes to a mixed state, in contrast to higher-frequency transmon qubits which typically relax to the ground state. The coupling to a low-Q resonator provides the non-unitary process needed to remove entropy from this state.\n", 38 | "\n", 39 | "To summarize this procedure, the qubit begins in a nearly completely mixed state between the first two energy levels, $\\rho \\approx \\frac{1}{2}(|g\\rangle \\langle g| +|e\\rangle \\langle e|)\\otimes |0\\rangle \\langle 0 |$. The first four levels of the fluxonium are labeled with $g,e,f,h$ respectively, and the resonator Fock states are labeled with numbers. The transitions $|g0\\rangle$ to $|h0\\rangle$ and $|h0\\rangle$ to $|e1\\rangle$ are driven simulataneously for a period of 15 $\\mu$ s. Throughout this process, photon loss in the resonator causes the population of $|e1\\rangle$ to transition to $|e0\\rangle$. The system eventually reaches a steady state, preparing $|e0\\rangle$ with high fidelity.\n", 40 | "\n", 41 | "The Hamiltonian of the coupled fluxonium-resonator system with a drive at frequency $\\omega_d$ capacitively coupled to the resonator is\n", 42 | "$$\n", 43 | "H = 4E_C\\hat n - E_J \\cos(\\hat \\phi-\\pi) + \\frac{1}{2}E_L \\hat \\phi^2 + g \\hat n (a+a^\\dagger) + E_{osc}a^\\dagger a + f(t)\\cos(\\omega_d t)(a+a^\\dagger)\n", 44 | "$$" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "metadata": {}, 51 | "outputs": [], 52 | "source": [ 53 | "import qutip as qt\n", 54 | "import numpy as np\n", 55 | "from matplotlib import pyplot as plt\n", 56 | "import scqubits as scq\n", 57 | "\n", 58 | "# experimental values borrowed from\n", 59 | "# https://journals.aps.org/prx/pdf/10.1103/PhysRevX.11.011010\n", 60 | "qbt = scq.Fluxonium(\n", 61 | " EJ=3.395,\n", 62 | " EC=0.479,\n", 63 | " EL=0.132,\n", 64 | " flux=0.5, # flux frustration point\n", 65 | " cutoff=110,\n", 66 | " truncated_dim=10,\n", 67 | " id_str=\"qubit\"\n", 68 | ")\n", 69 | "\n", 70 | "osc = scq.Oscillator(E_osc=5.7, truncated_dim=8, id_str=\"resonator\")\n", 71 | "\n", 72 | "hilbertspace = scq.HilbertSpace([qbt, osc])\n", 73 | "\n", 74 | "hilbertspace.add_interaction(\n", 75 | " g_strength=.4, op1=qbt.n_operator, op2=osc.creation_operator, add_hc=True\n", 76 | ")\n", 77 | "\n", 78 | "# Precompute eigensystem to save later computation\n", 79 | "hilbertspace.generate_lookup()" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "## Drive simulation methods" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "# get the transition frequency between two states specified by dressed indices\n", 96 | "def transition_frequency(s0: int, s1: int) -> float:\n", 97 | " return (\n", 98 | " (\n", 99 | " hilbertspace.energy_by_dressed_index(s1)\n", 100 | " - hilbertspace.energy_by_dressed_index(s0)\n", 101 | " )\n", 102 | " * 2\n", 103 | " * np.pi\n", 104 | " )\n", 105 | "# Get the period of one Rabi cycle as a function of operator matrix element and drive strength\n", 106 | "def drive_strength(s0: int, s1: int, period: float, drive_operator: qt.Qobj):\n", 107 | " # divide by 2pi for drive strength in units of GHz\n", 108 | " return abs(1 / (period * drive_operator.full()[s0][s1]))\n", 109 | " \n", 110 | "\n", 111 | " return result\n", 112 | "\n", 113 | "def rabi_period(s0: int, s1: int, Omega: float, drive_operator: qt.Qobj):\n", 114 | " # divide by 2pi for period in units of ns\n", 115 | " return abs(1 / (Omega * drive_operator.full()[s0][s1]))" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "## Truncating operators\n", 123 | "The efficiency of the simulation is greatly improved by truncating the operators. The truncation happens in two steps:\n", 124 | "1) The first truncation is controlled by setting the `truncated_dim` parameter in the subsystem initialization, which determines the dimension used in diagonalizing the Hamiltonian. Setting these too low can result in an unphysical simulation. Even if energy levels above the truncation are not explicitly involved, they can still drastically affect the matrix elements of the operators. \n", 125 | "\n", 126 | "2) Once the matrix elements and eigenvalues have been obtained, the operators can be truncated further. This truncation can greatly improve the runtime of the simulation. \n", 127 | "\n", 128 | "Here, a coupled system with dimensions $10$ by $8$ is simulated. These truncation levels are reasonable to obtain the operators for each individual system. However, this results in a full Hamiltonian represented by an $80 \\times 80$ matrix. After diagonalization, the Hamiltonian and subsystem operators can be safely truncated to a lower dimension, specified here by the variable `total_truncation`." 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "# The matrix representations can be truncated further for the simulation\n", 138 | "total_truncation = 20\n", 139 | "\n", 140 | "# truncate operators to desired dimension\n", 141 | "def truncate(operator: qt.Qobj, dimension: int) -> qt.Qobj:\n", 142 | " return qt.Qobj(operator[:dimension, :dimension])" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "## Drive operators" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": null, 155 | "metadata": {}, 156 | "outputs": [], 157 | "source": [ 158 | "# express the resonator drive operator in the dressed eigenbasis of the system\n", 159 | "phi_r = hilbertspace.op_in_dressed_eigenbasis((osc.annihilation_operator, osc)) \\\n", 160 | " + hilbertspace.op_in_dressed_eigenbasis((osc.creation_operator, osc))\n", 161 | "\n", 162 | "#truncate operator for more efficient simulation\n", 163 | "phi_r_trunc = truncate(phi_r, total_truncation)\n", 164 | "\n", 165 | "# do the same for the qubit charge operator\n", 166 | "n_qbt = hilbertspace.op_in_dressed_eigenbasis((qbt.n_operator, qbt))\n", 167 | "\n", 168 | "#truncate operator\n", 169 | "n_qbt_trunc = truncate(n_qbt, total_truncation)" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "The dressed eigenstates correspond closely to the bare product states when the coupling is weak. The `dressed_index` function matches a product state to the corresponding dressed eigenstate." 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": null, 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [ 185 | "#Get energy indices most closely matching product state indices\n", 186 | "g0 = hilbertspace.dressed_index((0,0))\n", 187 | "e0 = hilbertspace.dressed_index((1,0))\n", 188 | "h0 = hilbertspace.dressed_index((3,0))\n", 189 | "e1 = hilbertspace.dressed_index((1,1))\n", 190 | "\n", 191 | "# Get eigenstates matching product state dressed indices\n", 192 | "states = [qt.basis(total_truncation, i) for i in [g0, e0, h0, e1]]\n", 193 | "period = 500\n", 194 | "Omega1 = drive_strength(g0, h0, period, phi_r)\n", 195 | "Omega2 = drive_strength(h0, e1, period, phi_r)\n", 196 | "\n", 197 | "# g0 -> h0 transition\n", 198 | "omega_1 = transition_frequency(h0, g0)\n", 199 | "# h0 -> e1 transition\n", 200 | "omega_2 = transition_frequency(e1, h0)\n", 201 | "\n", 202 | "# drive amplitude as a function of time\n", 203 | "def drive_coeff(t : float, args : dict) -> float:\n", 204 | " return Omega1 * np.cos(omega_1 * t) + Omega2 * np.cos(omega_2 * t)\n", 205 | "\n", 206 | "# get the diagonal Hamiltonian in the dressed basis\n", 207 | "(evals,) = hilbertspace[\"evals\"]" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "## Units\n", 215 | "scQubits natively reports energy in GHz, units of frequency. The frequency $f$ and the radial frequency $\\omega$ are related via\n", 216 | "$$\n", 217 | "\\hbar \\omega = h f\n", 218 | "$$\n", 219 | "The constants $h$ and $\\hbar$ are related by $h = 2\\pi \\hbar$, so the angular frequency in units of radians per nanosecond is given by $\\omega = 2\\pi f$. For this reason, the energies obtained from diagonalization and the matrix elements need to be multiplied by $2\\pi$ for simulating in QuTiP." 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "metadata": {}, 226 | "outputs": [], 227 | "source": [ 228 | "# The factor of 2pi converts the energy to GHz so that the time is in units of ns\n", 229 | "diag_dressed_hamiltonian = qt.Qobj(\n", 230 | " 2 * np.pi * np.diag(evals), dims=[hilbertspace.subsystem_dims] * 2\n", 231 | ")\n", 232 | "diag_dressed_hamiltonian_trunc = truncate(diag_dressed_hamiltonian, total_truncation)\n", 233 | "\n", 234 | "# The time-dependent driven Hamiltonian\n", 235 | "H_qbt_drive = [\n", 236 | " diag_dressed_hamiltonian_trunc,\n", 237 | " #Another factor of 2pi is needed to convert energy to units where time is in ns\n", 238 | " [2 * np.pi * phi_r_trunc, drive_coeff], # driving through the resonator\n", 239 | "]" 240 | ] 241 | }, 242 | { 243 | "cell_type": "markdown", 244 | "metadata": {}, 245 | "source": [ 246 | "## Resonator photon loss\n", 247 | "The resonator photon loss is modeled through the quantum channel $\\mathcal{E}(\\rho) = \\kappa a\\rho a^\\dagger$, defined by the collapse operator $\\sqrt{\\kappa } a$." 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": null, 253 | "metadata": {}, 254 | "outputs": [], 255 | "source": [ 256 | "# resonator decay constant\n", 257 | "kappa = 0.003\n", 258 | "# annihilation operator\n", 259 | "a_osc = truncate(\n", 260 | " #basis_change(osc.annihilation_operator(), osc, hilbertspace), total_truncation\n", 261 | " hilbertspace.op_in_dressed_eigenbasis((osc.annihilation_operator, osc)),\n", 262 | " total_truncation\n", 263 | ")" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "## Simulation\n", 271 | "\n", 272 | "\n", 273 | "Note: evaluating the following cell will likely require several minutes of computation time." 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": null, 279 | "metadata": {}, 280 | "outputs": [], 281 | "source": [ 282 | "# initial mixed state\n", 283 | "thermal_state = 0.5 * (states[0] * states[0].dag() + states[1] * states[1].dag())\n", 284 | "\n", 285 | "dt = 2 \n", 286 | "total_time = 6000\n", 287 | "tlist = np.linspace(0, 6000, int(total_time/dt)) # total time\n", 288 | "\n", 289 | "\n", 290 | "result = qt.mesolve(\n", 291 | " H_qbt_drive, # hamiltonian\n", 292 | " thermal_state, # initial density matrix\n", 293 | " tlist,\n", 294 | " e_ops=[state * state.dag() for state in states], # expectation values\n", 295 | " c_ops=[np.sqrt(kappa) * a_osc], # photon loss\n", 296 | ")" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": null, 302 | "metadata": {}, 303 | "outputs": [], 304 | "source": [ 305 | "for i in range(4):\n", 306 | " plt.plot(tlist, result.expect[i], label=r\"$|%u\\rangle$\" % (i))\n", 307 | "plt.legend()\n", 308 | "plt.xlabel(\"t (ns)\")\n", 309 | "plt.ylabel(\"population\")" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": {}, 316 | "outputs": [], 317 | "source": [ 318 | "print(\"Fidelity:\", result.expect[1][-1])" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "metadata": {}, 332 | "outputs": [], 333 | "source": [] 334 | } 335 | ], 336 | "metadata": { 337 | "kernelspec": { 338 | "display_name": "Python 3 (ipykernel)", 339 | "language": "python", 340 | "name": "python3" 341 | }, 342 | "language_info": { 343 | "codemirror_mode": { 344 | "name": "ipython", 345 | "version": 3 346 | }, 347 | "file_extension": ".py", 348 | "mimetype": "text/x-python", 349 | "name": "python", 350 | "nbconvert_exporter": "python", 351 | "pygments_lexer": "ipython3", 352 | "version": "3.12.3" 353 | }, 354 | "vscode": { 355 | "interpreter": { 356 | "hash": "9164de953f07298d5425f06b7f44c8ff0307d8bc321681348712c726632dc63f" 357 | } 358 | } 359 | }, 360 | "nbformat": 4, 361 | "nbformat_minor": 4 362 | } 363 | -------------------------------------------------------------------------------- /workflow-requirements.info: -------------------------------------------------------------------------------- 1 | h5py>=2.10 2 | pytest 3 | ipywidgets 4 | ipyvuetify 5 | pathos>=0.3.0 6 | traitlets 7 | typing_extensions 8 | qutip-qip; python_version >= "3.9" 9 | --------------------------------------------------------------------------------