├── Quimb_tutorial1.ipynb ├── Quimb_tutorial2.ipynb ├── Quimb_tutorial3.ipynb └── README.md /Quimb_tutorial1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tutorial 1: Bras, Kets, and Operators" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "pip install quimb" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "pip install numba" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "pip install scipy" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "pip install numpy" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "pip install cytoolz" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "pip install tqdm" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "pip install psutil" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "pip install opt_einsum" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": {}, 86 | "outputs": [], 87 | "source": [ 88 | "pip install autoray" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "pip install matplotlib" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": null, 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "pip install networkx" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [ 115 | "import quimb as qu\n", 116 | "from quimb import *\n", 117 | "import quimb.tensor as qtn\n", 118 | "import numpy as np" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "## Basic Representation\n", 126 | "States and operators in quimb are simply dense numpy arrays or sparse scipy matrices. All functions should directly work with these but the class qarray is also provided as a very thin subclass of numpy.ndarray with a few helpful methods and attributes. The quimbify() function (aliased to qu()) can convert between the various representations." 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "# Define a 1-dimensional array\n", 136 | "array = [1-5j, 2j, -3]" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": {}, 142 | "source": [ 143 | "Kets are column vectors, i.e. they have shape (d, 1):" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": null, 149 | "metadata": {}, 150 | "outputs": [], 151 | "source": [ 152 | "# Use the 'qu' function to turn it into a ket-vector, i.e. a column vector\n", 153 | "ket_vec = qu(array, qtype='ket')\n", 154 | "print(ket_vec)" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "This is the column vector:\n", 162 | "\n", 163 | "$| \\psi \\rangle = \\begin{pmatrix} 1-5j \\\\ 2j \\\\ -3 \\end{pmatrix}$" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "The normalized=True option can be used to ensure a normalized output." 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": null, 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "v = qu(array, qtype='ket', normalized=True)\n", 180 | "print(v)" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "This prints the ket-vector:\n", 188 | "\n", 189 | "$v = \\begin{pmatrix} 0.160128-0.800641j \\\\ 0.+0.320256j \\\\ -0.480384 \\end{pmatrix}$\n", 190 | "\n", 191 | "We can check that the norm of the vector is indeed equal to 1:\n", 192 | "\n", 193 | "$ ||v|| = \\big|\\langle v^*, v \\rangle \\big| \\sqrt{ \\sum_{i=0}^2 \\overline{v_i} v_i } = 1$" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "# Compute the norm of the complex vector 'v'\n", 203 | "np.linalg.norm(v)" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "Bras are row vectors, i.e. they have shape (1, d):" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": null, 216 | "metadata": {}, 217 | "outputs": [], 218 | "source": [ 219 | "bra_vec = qu(array, qtype='bra') # also conjugates the ket-vector 'v' to a row vector\n", 220 | "print(bra_vec)" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "This is the row vector:\n", 228 | "\n", 229 | "$\\langle \\psi | = \\begin{pmatrix} 1+5j,\\ -2j,\\ -3 \\end{pmatrix}$" 230 | ] 231 | }, 232 | { 233 | "cell_type": "markdown", 234 | "metadata": {}, 235 | "source": [ 236 | "We can also normalize the bra-vectors:" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": null, 242 | "metadata": {}, 243 | "outputs": [], 244 | "source": [ 245 | "v_dual = qu(array, qtype='bra', normalized=True)\n", 246 | "print(v_dual)" 247 | ] 248 | }, 249 | { 250 | "cell_type": "markdown", 251 | "metadata": {}, 252 | "source": [ 253 | "So we get:\n", 254 | "\n", 255 | "$v^* = \\begin{pmatrix} 0.160128+0.800641j,\\ -0.320256j,\\ -0.480384 \\end{pmatrix}$\n", 256 | "\n", 257 | "Computing the norm of the dual vector $v^*$ we get:\n", 258 | "\n", 259 | "$||v^*|| = \\big|\\langle v^*, v \\rangle \\big| = \\sqrt{ \\sum_{i=0}^2 \\overline{v_i}v_i } = 1$" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": null, 265 | "metadata": {}, 266 | "outputs": [], 267 | "source": [ 268 | "# Compute the norm of the complex bra-vector 'dual_v'\n", 269 | "np.linalg.norm(v)" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "metadata": {}, 275 | "source": [ 276 | "Operators are square matrices, i.e. have shape (d, d):" 277 | ] 278 | }, 279 | { 280 | "cell_type": "code", 281 | "execution_count": null, 282 | "metadata": {}, 283 | "outputs": [], 284 | "source": [ 285 | "operator = qu(array, qtype='dop')\n", 286 | "print(operator)" 287 | ] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": {}, 292 | "source": [ 293 | "This is actualy given by the outer product:\n", 294 | "\n", 295 | "$| \\psi \\rangle \\langle \\psi | = \\begin{pmatrix} 1+5j\\\\ -2j\\\\ -3 \\end{pmatrix} \\begin{pmatrix} 1+5j,\\ -2j,\\ -3 \\end{pmatrix} = \\begin{pmatrix} 26 & -10 -2j & -3+15j \\\\ -10+2j & 4 & -6j \\\\ -3-15j & 6j & 9 \\end{pmatrix}$" 296 | ] 297 | }, 298 | { 299 | "cell_type": "markdown", 300 | "metadata": {}, 301 | "source": [ 302 | "We can obtain a unitary operator by using the normalized vector $v$ and computing $v \\otimes v^*$, or we can simple set normalized=True" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": null, 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "U = qu(array, qtype='dop', normalized=True) #creates a unitary operator\n", 312 | "print(U)" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": null, 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [ 321 | "V = np.kron(v_dual,v) #This computes the tensor (a.k.a Kronecker) product of v and v_dual\n", 322 | "print(V)" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "As we can see, both yield the same unitary matrix. To check the matrix $U = V$ is indeed unitary we compute the matrix (operator) norm:" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": null, 335 | "metadata": {}, 336 | "outputs": [], 337 | "source": [ 338 | "np.linalg.norm(V)" 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "metadata": {}, 344 | "source": [ 345 | "Note, due to the floating point computation, $-0. \\neq 0.$ and $-0.j \\neq 0.j$, so python \"believes\" that $U \\neq V$ and that $U$ is not in fact unitary. " 346 | ] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": null, 351 | "metadata": {}, 352 | "outputs": [], 353 | "source": [ 354 | "np.array_equal(U,V)" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": null, 360 | "metadata": {}, 361 | "outputs": [], 362 | "source": [ 363 | "np.linalg.norm(U)" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "metadata": {}, 369 | "source": [ 370 | "We can also make an array a bra, ket, or an operator using the functions\n", 371 | "```\n", 372 | "bra(), ket(), dop()\n", 373 | "```" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "metadata": {}, 380 | "outputs": [], 381 | "source": [ 382 | "bra(array)" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": null, 388 | "metadata": {}, 389 | "outputs": [], 390 | "source": [ 391 | "ket(array)" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": null, 397 | "metadata": {}, 398 | "outputs": [], 399 | "source": [ 400 | "dop(array)" 401 | ] 402 | } 403 | ], 404 | "metadata": { 405 | "kernelspec": { 406 | "display_name": "Python 3", 407 | "language": "python", 408 | "name": "python3" 409 | }, 410 | "language_info": { 411 | "codemirror_mode": { 412 | "name": "ipython", 413 | "version": 3 414 | }, 415 | "file_extension": ".py", 416 | "mimetype": "text/x-python", 417 | "name": "python", 418 | "nbconvert_exporter": "python", 419 | "pygments_lexer": "ipython3", 420 | "version": "3.7.3" 421 | } 422 | }, 423 | "nbformat": 4, 424 | "nbformat_minor": 4 425 | } 426 | -------------------------------------------------------------------------------- /Quimb_tutorial2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tutorial 2" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "Requirement already satisfied: quimb in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (1.2.0)\n", 20 | "Requirement already satisfied: autoray>=0.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (0.1.1)\n", 21 | "Requirement already satisfied: opt-einsum>=2 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (3.1.0)\n", 22 | "Requirement already satisfied: cytoolz>=0.8.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (0.10.0)\n", 23 | "Requirement already satisfied: tqdm>=4 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (4.32.1)\n", 24 | "Requirement already satisfied: numba>=0.39 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (0.44.1)\n", 25 | "Requirement already satisfied: psutil>=4.3.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (5.6.3)\n", 26 | "Requirement already satisfied: scipy>=1.0.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (1.3.0)\n", 27 | "Requirement already satisfied: numpy>=1.12 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (1.16.4)\n", 28 | "Requirement already satisfied: toolz>=0.8.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cytoolz>=0.8.0->quimb) (0.10.0)\n", 29 | "Requirement already satisfied: llvmlite>=0.29.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from numba>=0.39->quimb) (0.29.0)\n", 30 | "Note: you may need to restart the kernel to use updated packages.\n" 31 | ] 32 | } 33 | ], 34 | "source": [ 35 | "pip install quimb" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 2, 41 | "metadata": {}, 42 | "outputs": [ 43 | { 44 | "name": "stdout", 45 | "output_type": "stream", 46 | "text": [ 47 | "Requirement already satisfied: numba in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (0.44.1)\n", 48 | "Requirement already satisfied: llvmlite>=0.29.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from numba) (0.29.0)\n", 49 | "Requirement already satisfied: numpy in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from numba) (1.16.4)\n", 50 | "Note: you may need to restart the kernel to use updated packages.\n" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "pip install numba" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 3, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "Requirement already satisfied: scipy in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (1.3.0)\n", 68 | "Note: you may need to restart the kernel to use updated packages.\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "pip install scipy" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 4, 79 | "metadata": {}, 80 | "outputs": [ 81 | { 82 | "name": "stdout", 83 | "output_type": "stream", 84 | "text": [ 85 | "Requirement already satisfied: numpy in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (1.16.4)\n", 86 | "Note: you may need to restart the kernel to use updated packages.\n" 87 | ] 88 | } 89 | ], 90 | "source": [ 91 | "pip install numpy" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 5, 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "Requirement already satisfied: cytoolz in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (0.10.0)\n", 104 | "Requirement already satisfied: toolz>=0.8.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cytoolz) (0.10.0)\n", 105 | "Note: you may need to restart the kernel to use updated packages.\n" 106 | ] 107 | } 108 | ], 109 | "source": [ 110 | "pip install cytoolz" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 6, 116 | "metadata": {}, 117 | "outputs": [ 118 | { 119 | "name": "stdout", 120 | "output_type": "stream", 121 | "text": [ 122 | "Requirement already satisfied: tqdm in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (4.32.1)\n", 123 | "Note: you may need to restart the kernel to use updated packages.\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "pip install tqdm" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 7, 134 | "metadata": {}, 135 | "outputs": [ 136 | { 137 | "name": "stdout", 138 | "output_type": "stream", 139 | "text": [ 140 | "Requirement already satisfied: psutil in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (5.6.3)\n", 141 | "Note: you may need to restart the kernel to use updated packages.\n" 142 | ] 143 | } 144 | ], 145 | "source": [ 146 | "pip install psutil" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 8, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "Requirement already satisfied: opt_einsum in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (3.1.0)\n", 159 | "Requirement already satisfied: numpy>=1.7 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from opt_einsum) (1.16.4)\n", 160 | "Note: you may need to restart the kernel to use updated packages.\n" 161 | ] 162 | } 163 | ], 164 | "source": [ 165 | "pip install opt_einsum" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 9, 171 | "metadata": {}, 172 | "outputs": [ 173 | { 174 | "name": "stdout", 175 | "output_type": "stream", 176 | "text": [ 177 | "Requirement already satisfied: autoray in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (0.1.1)\n", 178 | "Requirement already satisfied: numpy in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from autoray) (1.16.4)\n", 179 | "Note: you may need to restart the kernel to use updated packages.\n" 180 | ] 181 | } 182 | ], 183 | "source": [ 184 | "pip install autoray" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 10, 190 | "metadata": {}, 191 | "outputs": [ 192 | { 193 | "name": "stdout", 194 | "output_type": "stream", 195 | "text": [ 196 | "Requirement already satisfied: matplotlib in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (3.1.0)\n", 197 | "Requirement already satisfied: cycler>=0.10 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from matplotlib) (0.10.0)\n", 198 | "Requirement already satisfied: kiwisolver>=1.0.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from matplotlib) (1.1.0)\n", 199 | "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from matplotlib) (2.4.0)\n", 200 | "Requirement already satisfied: python-dateutil>=2.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from matplotlib) (2.8.0)\n", 201 | "Requirement already satisfied: numpy>=1.11 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from matplotlib) (1.16.4)\n", 202 | "Requirement already satisfied: six in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cycler>=0.10->matplotlib) (1.12.0)\n", 203 | "Requirement already satisfied: setuptools in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from kiwisolver>=1.0.1->matplotlib) (41.0.1)\n", 204 | "Note: you may need to restart the kernel to use updated packages.\n" 205 | ] 206 | } 207 | ], 208 | "source": [ 209 | "pip install matplotlib" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 11, 215 | "metadata": {}, 216 | "outputs": [ 217 | { 218 | "name": "stdout", 219 | "output_type": "stream", 220 | "text": [ 221 | "Requirement already satisfied: networkx in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (2.3)\n", 222 | "Requirement already satisfied: decorator>=4.3.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from networkx) (4.4.0)\n", 223 | "Note: you may need to restart the kernel to use updated packages.\n" 224 | ] 225 | } 226 | ], 227 | "source": [ 228 | "pip install networkx" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 12, 234 | "metadata": {}, 235 | "outputs": [], 236 | "source": [ 237 | "import quimb as qu\n", 238 | "from quimb import *\n", 239 | "import quimb.tensor as qtn\n", 240 | "import numpy as np" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "## Basic Operations\n", 248 | "The $\\dagger$ (‘dagger’), or hermitian conjugate, operation is performed with the .H attribute:" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": 13, 254 | "metadata": {}, 255 | "outputs": [ 256 | { 257 | "name": "stdout", 258 | "output_type": "stream", 259 | "text": [ 260 | "[[ 0.+0.j ]\n", 261 | " [ 0.+0.707107j]\n", 262 | " [-0.-0.707107j]\n", 263 | " [ 0.+0.j ]]\n" 264 | ] 265 | } 266 | ], 267 | "source": [ 268 | "psi = 1.0j * bell_state('psi-')\n", 269 | "print(psi)" 270 | ] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": 14, 275 | "metadata": {}, 276 | "outputs": [ 277 | { 278 | "data": { 279 | "text/plain": [ 280 | "[[ 0.-0.j 0.-0.707107j -0.+0.707107j 0.-0.j ]]" 281 | ] 282 | }, 283 | "execution_count": 14, 284 | "metadata": {}, 285 | "output_type": "execute_result" 286 | } 287 | ], 288 | "source": [ 289 | "psi.H" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "metadata": {}, 295 | "source": [ 296 | "This takes the ket-vector to a bra-vector:\n", 297 | "\n", 298 | "$ | \\psi \\rangle \\mapsto \\langle \\psi | $\n", 299 | "\n", 300 | "Numerically, this is just the complex conjugate of the column vector $| \\psi \\rangle$:\n", 301 | "\n", 302 | "$\\begin{pmatrix}0\\\\ 0.707107j\\\\ -0.707107j\\\\ 0 \\end{pmatrix} \\mapsto \\begin{pmatrix}0,\\ -0.707107j,\\ 0.707107j,\\ 0 \\end{pmatrix}$" 303 | ] 304 | }, 305 | { 306 | "cell_type": "markdown", 307 | "metadata": {}, 308 | "source": [ 309 | "This can also be performed on operators of course, where it is typically referred to as the Hermitian conjugate (denoted by $\\dagger$), and is given by the complex conjugate of the transpose of the matrix representing the operator:" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": 15, 315 | "metadata": {}, 316 | "outputs": [ 317 | { 318 | "name": "stdout", 319 | "output_type": "stream", 320 | "text": [ 321 | "[[ 0. +0.j 0. +0.j -0. +0.j 0. +0.j]\n", 322 | " [ 0. +0.j 0.5+0.j -0.5+0.j 0. +0.j]\n", 323 | " [ 0. -0.j -0.5-0.j 0.5+0.j 0. -0.j]\n", 324 | " [ 0. +0.j 0. +0.j -0. +0.j 0. +0.j]]\n" 325 | ] 326 | } 327 | ], 328 | "source": [ 329 | "psi_op = qu(psi, qtype='dop')\n", 330 | "print(psi_op)" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": 16, 336 | "metadata": {}, 337 | "outputs": [ 338 | { 339 | "data": { 340 | "text/plain": [ 341 | "[[ 0. -0.j 0. -0.j 0. +0.j 0. -0.j]\n", 342 | " [ 0. -0.j 0.5-0.j -0.5+0.j 0. -0.j]\n", 343 | " [-0. -0.j -0.5-0.j 0.5-0.j -0. -0.j]\n", 344 | " [ 0. -0.j 0. -0.j 0. +0.j 0. -0.j]]" 345 | ] 346 | }, 347 | "execution_count": 16, 348 | "metadata": {}, 349 | "output_type": "execute_result" 350 | } 351 | ], 352 | "source": [ 353 | "psi_op.H" 354 | ] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": {}, 359 | "source": [ 360 | "This takes the operator $ U = |\\psi \\rangle \\langle \\psi |$ to the operator $U^{\\dagger}$\n", 361 | "\n", 362 | "This is just the combination of ```.conj()``` and ```.T```, but only available for ```scipy.sparse``` matrices and ```qarray```s (not ```numpy.ndarray```s).\n", 363 | "\n", 364 | "The product of two quantum objects is the dot or matrix product, which, since python 3.5, has been overloaded with the ```@``` symbol. Using it is recommended:" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 17, 370 | "metadata": {}, 371 | "outputs": [ 372 | { 373 | "data": { 374 | "text/plain": [ 375 | "[[1.+0.j]\n", 376 | " [0.+0.j]]" 377 | ] 378 | }, 379 | "execution_count": 17, 380 | "metadata": {}, 381 | "output_type": "execute_result" 382 | } 383 | ], 384 | "source": [ 385 | "psi = up() #spin-up single qubit\n", 386 | "psi" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": 18, 392 | "metadata": {}, 393 | "outputs": [ 394 | { 395 | "data": { 396 | "text/plain": [ 397 | "[[1.+0.j]]" 398 | ] 399 | }, 400 | "execution_count": 18, 401 | "metadata": {}, 402 | "output_type": "execute_result" 403 | } 404 | ], 405 | "source": [ 406 | "psi.H @ psi # inner product" 407 | ] 408 | }, 409 | { 410 | "cell_type": "code", 411 | "execution_count": 19, 412 | "metadata": {}, 413 | "outputs": [ 414 | { 415 | "data": { 416 | "text/plain": [ 417 | "[[0.+0.j]\n", 418 | " [1.+0.j]]" 419 | ] 420 | }, 421 | "execution_count": 19, 422 | "metadata": {}, 423 | "output_type": "execute_result" 424 | } 425 | ], 426 | "source": [ 427 | "X = pauli('X')\n", 428 | "X @ psi # act as gate" 429 | ] 430 | }, 431 | { 432 | "cell_type": "code", 433 | "execution_count": 20, 434 | "metadata": {}, 435 | "outputs": [ 436 | { 437 | "data": { 438 | "text/plain": [ 439 | "[[0.+0.j]]" 440 | ] 441 | }, 442 | "execution_count": 20, 443 | "metadata": {}, 444 | "output_type": "execute_result" 445 | } 446 | ], 447 | "source": [ 448 | "psi.H @ X @ psi # operator expectation" 449 | ] 450 | }, 451 | { 452 | "cell_type": "markdown", 453 | "metadata": {}, 454 | "source": [ 455 | "Scalar expectation values might best be computed using the ```expectation()``` function (aliased to ```expec()```) which dispatches to accelerated methods:" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": 21, 461 | "metadata": {}, 462 | "outputs": [ 463 | { 464 | "data": { 465 | "text/plain": [ 466 | "1.0" 467 | ] 468 | }, 469 | "execution_count": 21, 470 | "metadata": {}, 471 | "output_type": "execute_result" 472 | } 473 | ], 474 | "source": [ 475 | "expec(psi, psi)" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": 22, 481 | "metadata": {}, 482 | "outputs": [ 483 | { 484 | "data": { 485 | "text/plain": [ 486 | "0j" 487 | ] 488 | }, 489 | "execution_count": 22, 490 | "metadata": {}, 491 | "output_type": "execute_result" 492 | } 493 | ], 494 | "source": [ 495 | "expec(psi, X)" 496 | ] 497 | }, 498 | { 499 | "cell_type": "markdown", 500 | "metadata": {}, 501 | "source": [ 502 | "Here’s an example for a much larger (20 qubit), sparse operator expecation, which will be **automatically parallelized**:" 503 | ] 504 | }, 505 | { 506 | "cell_type": "code", 507 | "execution_count": 23, 508 | "metadata": {}, 509 | "outputs": [ 510 | { 511 | "data": { 512 | "text/plain": [ 513 | "<1048576x1048576 sparse matrix of type ''\n", 514 | "\twith 11534278 stored elements in Compressed Sparse Row format>" 515 | ] 516 | }, 517 | "execution_count": 23, 518 | "metadata": {}, 519 | "output_type": "execute_result" 520 | } 521 | ], 522 | "source": [ 523 | "psi = rand_ket(2**20)\n", 524 | "A = rand_herm(2**20, sparse=True) + speye(2**20)\n", 525 | "A" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": 24, 531 | "metadata": {}, 532 | "outputs": [ 533 | { 534 | "name": "stderr", 535 | "output_type": "stream", 536 | "text": [ 537 | "/Users/amelieschreiber/anaconda3/lib/python3.7/site-packages/quimb/core.py:508: NumbaWarning: \u001b[1mCannot cache compiled function \"_dot_csr_matvec_prange\" as it uses dynamic globals (such as ctypes pointers and large global arrays)\u001b[0m\n", 538 | " @njit(parallel=True) # pragma: no cover\n" 539 | ] 540 | }, 541 | { 542 | "data": { 543 | "text/plain": [ 544 | "0.9993532985313052" 545 | ] 546 | }, 547 | "execution_count": 24, 548 | "metadata": {}, 549 | "output_type": "execute_result" 550 | } 551 | ], 552 | "source": [ 553 | "expec(A, psi) # should be ~ 1" 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": 25, 559 | "metadata": {}, 560 | "outputs": [ 561 | { 562 | "name": "stdout", 563 | "output_type": "stream", 564 | "text": [ 565 | "165 ms ± 14.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" 566 | ] 567 | } 568 | ], 569 | "source": [ 570 | "%%timeit\n", 571 | "expec(A, psi)" 572 | ] 573 | }, 574 | { 575 | "cell_type": "markdown", 576 | "metadata": {}, 577 | "source": [ 578 | "## Combining Objects - Tensoring\n", 579 | "\n", 580 | "There are a number of ways to combine states and operators, i.e. tensoring them together.\n", 581 | "\n", 582 | "Functional form using kron():\n", 583 | "\n", 584 | "```\n", 585 | "kron(psi1, psi2, psi3, ...)\n", 586 | "```\n", 587 | "\n", 588 | "This can also be done using the & overload on qarray and scipy matrices:\n", 589 | "\n", 590 | "```\n", 591 | "psi1 & psi2 & psi3\n", 592 | "```\n", 593 | "\n", 594 | "### Warning\n", 595 | "\n", 596 | "When quimb is imported, it monkey patches the otherwise unused method of ```&/__and__``` of scipy sparse matrices to ```kron()```.\n", 597 | "\n", 598 | "Often one wants to sandwich an operator with many identities, ```ikron()``` can be used for this:" 599 | ] 600 | }, 601 | { 602 | "cell_type": "code", 603 | "execution_count": 26, 604 | "metadata": {}, 605 | "outputs": [ 606 | { 607 | "name": "stderr", 608 | "output_type": "stream", 609 | "text": [ 610 | "/Users/amelieschreiber/anaconda3/lib/python3.7/site-packages/quimb/core.py:739: NumbaWarning: \u001b[1mCannot cache compiled function \"_nb_kron_exp_par\" as it uses dynamic globals (such as ctypes pointers and large global arrays)\u001b[0m\n", 611 | " @njit(parallel=True)\n" 612 | ] 613 | }, 614 | { 615 | "data": { 616 | "text/plain": [ 617 | "(1024, 1024)" 618 | ] 619 | }, 620 | "execution_count": 26, 621 | "metadata": {}, 622 | "output_type": "execute_result" 623 | } 624 | ], 625 | "source": [ 626 | "dims = [2] * 10 # overall space of 10 qubits\n", 627 | "X = pauli('X')\n", 628 | "IIIXXIIIII = ikron(X, dims, inds=[3, 4]) # act on 4th and 5th spin only\n", 629 | "IIIXXIIIII.shape" 630 | ] 631 | }, 632 | { 633 | "cell_type": "markdown", 634 | "metadata": {}, 635 | "source": [ 636 | "For more advanced tensor constructions, such as reversing and interleaving identities within operators ```pkron()``` can be used:" 637 | ] 638 | }, 639 | { 640 | "cell_type": "code", 641 | "execution_count": 27, 642 | "metadata": {}, 643 | "outputs": [ 644 | { 645 | "data": { 646 | "text/plain": [ 647 | "[[ 0 1 0 0 0 0 0 0]\n", 648 | " [ 1 0 0 0 0 0 0 0]\n", 649 | " [ 0 0 0 1 0 0 0 0]\n", 650 | " [ 0 0 1 0 0 0 0 0]\n", 651 | " [ 0 0 0 0 0 -1 0 0]\n", 652 | " [ 0 0 0 0 -1 0 0 0]\n", 653 | " [ 0 0 0 0 0 0 0 -1]\n", 654 | " [ 0 0 0 0 0 0 -1 0]]" 655 | ] 656 | }, 657 | "execution_count": 27, 658 | "metadata": {}, 659 | "output_type": "execute_result" 660 | } 661 | ], 662 | "source": [ 663 | "dims = [2] * 3\n", 664 | "XZ = pauli('X') & pauli('Z')\n", 665 | "ZIX = pkron(XZ, dims, inds=[2, 0])\n", 666 | "ZIX.real.astype(int)" 667 | ] 668 | }, 669 | { 670 | "cell_type": "markdown", 671 | "metadata": {}, 672 | "source": [ 673 | "$ZIX = Z \\otimes I \\otimes X$ would then act with Z on first spin, and X on 3rd." 674 | ] 675 | }, 676 | { 677 | "cell_type": "markdown", 678 | "metadata": {}, 679 | "source": [ 680 | "## Removing Objects - Partial Trace\n", 681 | "To remove, or ignore, certain parts of a quantum state the partial trace function ```partial_trace()``` (aliased to ```ptr()```) is used. Here, the internal dimensions of a state must be supplied as well as the indicies of which of these subsystems to keep.\n", 682 | "\n", 683 | "For example, if we have a random system of 10 qubits (hilbert space of dimension $2^{10}$), and we want just the reduced density matrix describing the first and last spins:" 684 | ] 685 | }, 686 | { 687 | "cell_type": "code", 688 | "execution_count": 28, 689 | "metadata": {}, 690 | "outputs": [ 691 | { 692 | "data": { 693 | "text/plain": [ 694 | "[[ 0.241+0.j 0.002-0.009j -0.008-0.003j 0.002-0.01j ]\n", 695 | " [ 0.002+0.009j 0.234+0.j 0.01 +0.012j 0.003+0.001j]\n", 696 | " [-0.008+0.003j 0.01 -0.012j 0.265+0.j -0.002+0.007j]\n", 697 | " [ 0.002+0.01j 0.003-0.001j -0.002-0.007j 0.26 +0.j ]]" 698 | ] 699 | }, 700 | "execution_count": 28, 701 | "metadata": {}, 702 | "output_type": "execute_result" 703 | } 704 | ], 705 | "source": [ 706 | "dims = [2] * 10\n", 707 | "D = prod(dims)\n", 708 | "psi = rand_ket(D)\n", 709 | "rho_ab = ptr(psi, dims, [0, 9])\n", 710 | "rho_ab.round(3) # probably pretty close to identity" 711 | ] 712 | }, 713 | { 714 | "cell_type": "markdown", 715 | "metadata": {}, 716 | "source": [ 717 | "```partial_trace()``` accepts dense or sparse, operators or vectors." 718 | ] 719 | }, 720 | { 721 | "cell_type": "code", 722 | "execution_count": null, 723 | "metadata": {}, 724 | "outputs": [], 725 | "source": [] 726 | } 727 | ], 728 | "metadata": { 729 | "kernelspec": { 730 | "display_name": "Python 3", 731 | "language": "python", 732 | "name": "python3" 733 | }, 734 | "language_info": { 735 | "codemirror_mode": { 736 | "name": "ipython", 737 | "version": 3 738 | }, 739 | "file_extension": ".py", 740 | "mimetype": "text/x-python", 741 | "name": "python", 742 | "nbconvert_exporter": "python", 743 | "pygments_lexer": "ipython3", 744 | "version": "3.7.3" 745 | } 746 | }, 747 | "nbformat": 4, 748 | "nbformat_minor": 4 749 | } 750 | -------------------------------------------------------------------------------- /Quimb_tutorial3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Built-in & Random States & Operators" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "Requirement already satisfied: quimb in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (1.2.0)\n", 20 | "Requirement already satisfied: tqdm>=4 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (4.32.1)\n", 21 | "Requirement already satisfied: psutil>=4.3.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (5.6.3)\n", 22 | "Requirement already satisfied: numba>=0.39 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (0.44.1)\n", 23 | "Requirement already satisfied: cytoolz>=0.8.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (0.10.0)\n", 24 | "Requirement already satisfied: scipy>=1.0.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (1.3.0)\n", 25 | "Requirement already satisfied: numpy>=1.12 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (1.16.4)\n", 26 | "Requirement already satisfied: opt-einsum>=2 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (3.1.0)\n", 27 | "Requirement already satisfied: autoray>=0.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quimb) (0.1.1)\n", 28 | "Requirement already satisfied: llvmlite>=0.29.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from numba>=0.39->quimb) (0.29.0)\n", 29 | "Requirement already satisfied: toolz>=0.8.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cytoolz>=0.8.0->quimb) (0.10.0)\n", 30 | "Note: you may need to restart the kernel to use updated packages.\n" 31 | ] 32 | } 33 | ], 34 | "source": [ 35 | "pip install quimb" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 2, 41 | "metadata": {}, 42 | "outputs": [ 43 | { 44 | "name": "stdout", 45 | "output_type": "stream", 46 | "text": [ 47 | "Requirement already satisfied: numba in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (0.44.1)\n", 48 | "Requirement already satisfied: llvmlite>=0.29.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from numba) (0.29.0)\n", 49 | "Requirement already satisfied: numpy in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from numba) (1.16.4)\n", 50 | "Note: you may need to restart the kernel to use updated packages.\n" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "pip install numba" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 3, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "Requirement already satisfied: scipy in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (1.3.0)\n", 68 | "Note: you may need to restart the kernel to use updated packages.\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "pip install scipy" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 4, 79 | "metadata": {}, 80 | "outputs": [ 81 | { 82 | "name": "stdout", 83 | "output_type": "stream", 84 | "text": [ 85 | "Requirement already satisfied: numpy in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (1.16.4)\n", 86 | "Note: you may need to restart the kernel to use updated packages.\n" 87 | ] 88 | } 89 | ], 90 | "source": [ 91 | "pip install numpy" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 5, 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "Requirement already satisfied: cytoolz in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (0.10.0)\n", 104 | "Requirement already satisfied: toolz>=0.8.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cytoolz) (0.10.0)\n", 105 | "Note: you may need to restart the kernel to use updated packages.\n" 106 | ] 107 | } 108 | ], 109 | "source": [ 110 | "pip install cytoolz" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": {}, 117 | "outputs": [ 118 | { 119 | "name": "stdout", 120 | "output_type": "stream", 121 | "text": [ 122 | "Requirement already satisfied: tqdm in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (4.32.1)\n" 123 | ] 124 | } 125 | ], 126 | "source": [ 127 | "pip install tqdm" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": null, 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [ 136 | "pip install psutil" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "pip install opt_einsum" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "metadata": {}, 152 | "outputs": [], 153 | "source": [ 154 | "pip install autoray" 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": null, 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [ 163 | "pip install matplotlib" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": {}, 170 | "outputs": [], 171 | "source": [ 172 | "pip install networkx" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": null, 178 | "metadata": {}, 179 | "outputs": [], 180 | "source": [ 181 | "import quimb as qu\n", 182 | "from quimb import *\n", 183 | "import quimb.tensor as qtn\n", 184 | "import numpy as np" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [ 193 | "up()" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "This returns the spin-up state, a.k.a \n", 201 | "\n", 202 | "$| 0 \\rangle = \\begin{pmatrix} 1 \\\\ 0 \\end{pmatrix}$, \n", 203 | "\n", 204 | "the $+Z$-eigenstate, where \n", 205 | "\n", 206 | "$Z = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix} = -iXY$\n", 207 | "\n", 208 | "is the Pauli-Z operator. Recall, the Pauli operators are:" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": null, 214 | "metadata": {}, 215 | "outputs": [], 216 | "source": [ 217 | "X = pauli('X')\n", 218 | "Y = pauli('Y')\n", 219 | "Z = pauli('Z')\n", 220 | "print(X)\n", 221 | "print(Y)\n", 222 | "print(Z)" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "$ X = \\begin{pmatrix} 0 & 1 \\\\ 1 & 0 \\end{pmatrix}$ \n", 230 | "\n", 231 | "$Y = \\begin{pmatrix} 0 & -i \\\\ i & 0 \\end{pmatrix}$ \n", 232 | "\n", 233 | "$Z = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix}$ \n", 234 | "\n", 235 | "$I = \\begin{pmatrix}1 & 0 \\\\ 0 & 1 \\end{pmatrix}$\n", 236 | "\n", 237 | "Now, let's look at the spin-down state vector ```down()```$= | 1 \\rangle = \\begin{pmatrix} 0 \\\\ 1 \\end{pmatrix}$" 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": null, 243 | "metadata": {}, 244 | "outputs": [], 245 | "source": [ 246 | "down()" 247 | ] 248 | }, 249 | { 250 | "cell_type": "markdown", 251 | "metadata": {}, 252 | "source": [ 253 | "This is the $-1$-eigenstate of the Pauli-Z operator. The $+1$-eigenstate of the Pauli-Y operator is:\n", 254 | "\n", 255 | "```yplus()```$= |y+ \\rangle = \\frac{1}{\\sqrt{2}}\\begin{pmatrix}1 \\\\ i \\end{pmatrix}$" 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": null, 261 | "metadata": {}, 262 | "outputs": [], 263 | "source": [ 264 | "yplus()" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": {}, 270 | "source": [ 271 | "The $-1$-eigenstate of the Pauli-Y operator is:\n", 272 | "\n", 273 | "```yminus()```$= |y-\\rangle = \\frac{1}{\\sqrt{2}}\\begin{pmatrix}1 \\\\ -i \\end{pmatrix}$" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": null, 279 | "metadata": {}, 280 | "outputs": [], 281 | "source": [ 282 | "yminus()" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "metadata": {}, 288 | "source": [ 289 | "Finally, the $+1$-eigenstate of the Pauli-X operator is:\n", 290 | "\n", 291 | "```xplus()```$=|+ \\rangle = \\frac{1}{\\sqrt{2}}\\begin{pmatrix}1 \\\\ 1 \\end{pmatrix}$" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": null, 297 | "metadata": {}, 298 | "outputs": [], 299 | "source": [ 300 | "xplus()" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": {}, 306 | "source": [ 307 | "The $-1$-eigenstate of the Pauli-X operator is:\n", 308 | "\n", 309 | "```xminus()```$=|- \\rangle = \\frac{1}{\\sqrt{2}}\\begin{pmatrix} 1 \\\\ -1 \\end{pmatrix}$" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": {}, 316 | "outputs": [], 317 | "source": [ 318 | "xminus()" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [] 327 | } 328 | ], 329 | "metadata": { 330 | "kernelspec": { 331 | "display_name": "Python 3", 332 | "language": "python", 333 | "name": "python3" 334 | }, 335 | "language_info": { 336 | "codemirror_mode": { 337 | "name": "ipython", 338 | "version": 3 339 | }, 340 | "file_extension": ".py", 341 | "mimetype": "text/x-python", 342 | "name": "python", 343 | "nbconvert_exporter": "python", 344 | "pygments_lexer": "ipython3", 345 | "version": "3.7.3" 346 | } 347 | }, 348 | "nbformat": 4, 349 | "nbformat_minor": 4 350 | } 351 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Quimb-Tutorials 2 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/The-Singularity-Research/Quimb-Tutorials/master?filepath=https%3A%2F%2Fgithub.com%2FThe-Singularity-Research%2FQuimb-Tutorials%2Fblob%2Fmaster%2FQuimb_tutorial1.ipynb) 3 | 4 | Tutorials using [Quimb](https://quimb.readthedocs.io/en/latest/index.html), a quantum circuit simulator that uses tensor networks. 5 | 6 | Although the documentation for Quimb is quite thorough and clear, it requires an understanding of quantum mechanics, quantum computing, machine learning, and some familiarity with Python. This repository is intended to fill these gaps for readers who do not have the background in quantum computing, phsyics, and Python programming. It will provide more tutorials with detailed calculations, modified and additional examples from the Quimb documentation, mathematical background material, links to YouTube video lectures, and visual illustrations. The notebooks in this repository will be linked to Binder making it easy to run and replicate results. 7 | --------------------------------------------------------------------------------