{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# State space labelling in pyGSTi\n", "\n", "Instances of `pygsti.objects.StateSpaceLabels` describe the structure of a model's state space and associate labels with the parts of that structure. This is particularly useful when dealing with multiple qubits or a qubit and its environment, as it can be useful to reference subspaces or subsystems of the entire quantum state space.\n", "\n", "In general, a state space is the direct sum of one or more *tensor product blocks*, each of which is the tensor product of one or more *factors*: \n", "\n", "$$ \\mbox{State space} = (\\mathcal{H}_1^A \\otimes \\mathcal{H}_2^A \\otimes \\cdots) \\oplus (\\mathcal{H}_1^B \\otimes \\mathcal{H}_2^B \\otimes \\cdots) \\oplus \\cdots$$\n", "\n", "In the above expression the tensor product blocks are in parenthesis and labelled by $A$, $B$, etc., and the $\\mathcal{H}_i^X$ are the factors. We can initialize a `StateSpaceLabels` object using a list of tuples containing labels and dimensions which mirror this structure, i.e.\n", "\n", "~~~\n", "StateSpaceLabels( [(H1A_label, H2A_label, ...), ((H1B_label, H2B_label, ...), ... ],\n", " [(H1A_dim , H2A_dim, ...), ((H1B_dim , H2B_dim, ...), ... ])\n", "~~~\n", "where `_label` variables are either strings or integers (it can be convenient to label qubits, for instance, by integers) and `_dim` variables are always integers. Here are some examples:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H0(2)*H1(3)\n", "H0(2)*H1(3)\n", "H0(2) + H1(3)\n", "H1a(2)*H2a(1) + H1b(3)*H2b(4)\n" ] } ], "source": [ "import pygsti\n", "from pygsti.objects import StateSpaceLabels\n", "\n", "lbls = StateSpaceLabels([('H0','H1')], [(2,3)])\n", "print(lbls) # label(dim) notation, '*' means 'otimes', '+' means 'oplus'\n", "\n", "lbls2 = StateSpaceLabels(('H0','H1'), (2,3)) # same as above - a *single* tensor product block\n", "print(lbls2)\n", "\n", "lbls3 = StateSpaceLabels([('H0',), ('H1',)], [(2,),(3,)]) # direct sum\n", "print(lbls3)\n", "\n", "lbls4 = StateSpaceLabels([('H1a','H2a'), ('H1b','H2b')], [(2,1),(3,4)])\n", "print(lbls4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since we're often dealing with qubits (dimension = 2 factors), the labels beginning with 'Q' or that are integers default to dimension 2. Similarly, labels beginning with 'L' default dimension 1 (an additional \"Level\"). If all the labels in the first argument passed to the `StateSpaceLabels` constructor have defaults, then the **second argument (the dimensions) may be omitted**. For example:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Q0(2)*Q1(2)\n", "0(2)*1(2)*2(2)\n", "Q0(2)*Q1(2) + Leakage(1)\n" ] } ], "source": [ "lbls5 = StateSpaceLabels(['Q0','Q1']) # 2 qubits\n", "print(lbls5)\n", "\n", "lbls6 = StateSpaceLabels(list(range(3))) # 3 qubits\n", "print(lbls6)\n", "\n", "lbls7 = StateSpaceLabels([('Q0','Q1'),('Leakage',)])\n", "print(lbls7)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The raw data within a `StateSpaceLabels` object is stored in the `.labels` and `.labeldims` members (but be careful, `labeldims` is a *dictionary*):" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(('Q0', 'Q1'), ('Leakage',))" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lbls7.labels" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Q0': 2, 'Q1': 2, 'Leakage': 1}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lbls7.labeldims" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can access the total dimensions of the state space using the `.dim` member, which is a `pygsti.baseobjs.Dim` object containing the following dimensions:\n", "- density-matrix dimension $d$ (density matrices are $d \\times d$)\n", "- tensor-product block dimensions $k_i$ (there is a kite structure of are $k_i\\times k_i$ nonzero blocks that form the the $d \\times d$ density matrix, so $\\sum_i k_i = d$)\n", "- super-operator dimension $D$ (superoperators can be represented by $D \\times D$ matrices; $D = \\sum_i k_i^2$)\n", "- the \"embedded\" superoperator dimension, $d^2$ (if you embedded the density matrix kite structure inside a full $d \\times d$ density matrix space, superoperators would have dimension $d^2)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dim object = Dim: dmDim 5 opDim 17 blockDims [4, 1] embedDim 25\n", "Separately: 5 [4, 1] 17 25\n" ] } ], "source": [ "print(\"Dim object = \",lbls7.dim)\n", "print(\"Separately: \",lbls7.dim.dmDim, lbls7.dim.blockDims, lbls7.dim.opDim, lbls7.dim.embedDim)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are also few convenience functions that make it easier to access the raw data: \n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of tensor product blocks = 2\n", "The labels in the 0th tensor product block are: ('Q0', 'Q1')\n", "The dimensions corresponding to those labels are: (2, 2)\n", "The 'Q0' labels exists in the tensor product block w/index= 0\n", "The product of the dimensions associated with 'Q0' and 'Leakage' = 2\n" ] } ], "source": [ "print(\"Number of tensor product blocks = \",lbls7.num_tensor_prod_blocks())\n", "print(\"The labels in the 0th tensor product block are: \",lbls7.tensor_product_block_labels(0))\n", "print(\"The dimensions corresponding to those labels are: \",lbls7.tensor_product_block_dims(0))\n", "print(\"The 'Q0' labels exists in the tensor product block w/index=\",lbls7.tpb_index['Q0'])\n", "print(\"The product of the dimensions associated with 'Q0' and 'Leakage' = \",lbls7.product_dim( ('Q0','Leakage') ))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**That's it!** You know all there is to know about the `StateSpaceLabels` object. Remember you can pass a `StateSpaceLabels` object to `pygsti.construction.build_explicit_model` to create a model which operates on the given state space." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0" } }, "nbformat": 4, "nbformat_minor": 2 }