{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "c8bbfdf2", "metadata": { "execution": { "iopub.execute_input": "2022-08-04T20:09:08.705193Z", "iopub.status.busy": "2022-08-04T20:09:08.704912Z", "iopub.status.idle": "2022-08-04T20:09:08.707656Z", "shell.execute_reply": "2022-08-04T20:09:08.707240Z" }, "nbsphinx": "hidden" }, "outputs": [], "source": [ "# Copyright 2022 Keysight Technologies Inc." ] }, { "cell_type": "raw", "id": "20496ea2", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "\n", "Advanced Qudit Framework\n", "========================\n", "This tutorial outlines the mathematical framework needed to do computations with\n", "qudits and outlines how users can use this framework within |True-Q|.\n", "\n", "The Weyl-Heisenberg Group\n", "-------------------------\n", "The Weyl-Heisenberg group is a generalization of the Pauli group to\n", ":math:d\\-dimensional systems and has operators analogous to the Pauli :math:X and\n", ":math:Z operators, which are referred to as \"shift\" (:math:X\\) and \"clock\"\n", "(:math:Z\\) operators. In cases where the dimension is unclear, we will denote the\n", ":math:d\\-dimensional shift (clock) matrix as :math:X_d (:math:Z_d\\).\n", "\n", "These operators are defined to be,\n", "\n", ".. math::\n", " X &= \\sum_{a\\in\\mathbb{Z}_d}\\ket{a \\oplus 1}\\bra{a}\\\\\n", " Z &= \\sum_{a\\in\\mathbb{Z}_d}\\textrm{exp}(2\\pi i a/d)\\ket{a}\\bra{a},\n", "\n", "where :math:\\oplus denotes addition modulo :math:d\\. When :math:d=2\\,\n", "these operators are the familiar Pauli :math:X and :math:Z operators. Their\n", "actions,\n", "\n", ".. math::\n", " X\\ket{a} &= \\ket{a+1}\\\\\n", " Z\\ket{a} &= \\textrm{exp}(2\\pi i a/d)\\ket{a},\n", "\n", "where :math:a\\in\\mathbb{Z}_d and operations act according to modular\n", "arithmetic, for example for 3-dimensional qudits (aka *qutrits*),\n", ":math:X\\ket{2}=\\ket{0}\\.\n", "\n", "Often, we specify elements of the Weyl-Heisenberg group (Weyl operators) by the powers\n", "of the clock and shift operators acting on a qudit along with an integer :math:k\n", "which specifies the phase. For a single-qudit system, a Weyl operator can be written\n", "as :math:\\omega(k)X^xZ^z\\, where\n", "\n", ".. math::\n", " \\omega(k) =\\begin{cases}\n", " \\textrm{exp}(\\pi i(2k+x\\cdot z\\%2)/2) & d=2 \\\\\n", " \\textrm{exp}(2\\pi ik/d) & d>2\n", " \\end{cases}\n", "\n", "Then, the powers and phase which specify that Weyl operator are :math:(x, z)\\in\n", "\\mathbb{Z}_d^2 and :math:k respectively.\n", "\n", "\n", ".. dropdown:: **Advanced note**: Expectation values of Weyl operators\n", "\n", " For :math:d>2\\, the Weyl operators are unitary but not Hermitian. This means\n", " that they can still be used to describe the evolution of quantum systems.\n", " However, the expectation of a Weyl operator :math:W for a system in the state\n", " :math:\\rho\\, that is, :math:\\mathrm{Tr}(W^\\dagger \\rho)\\, may be\n", " complex-valued, i.e. takes the form :math:r*\\textrm{exp}(i\\phi)\\. When\n", " :math:\\rho is expected to be an eigenstate of :math:W (e.g.\n", " :math:|0\\rangle for :math:W = Z\\)\\, then any other eigenstates are error\n", " states. The phase, :math:\\phi'\\, of a measured expectation value,\n", " :math:r'*\\textrm{exp}[i(\\phi+\\phi')]\\, relative to the ideal phase,\n", " :math:r*\\textrm{exp}(i\\phi)\\, indicates that the error states were not\n", " observed with equal frequencies.\n", "\n", " As the Weyl operators form a trace-orthogonal operator basis with respect to the\n", " Hilbert-Schmidt inner product, any state :math:\\rho can be expanded as\n", " :math:\\sum_W \\frac{p_W(\\rho)}{d^n} W where\n", " :math:p_W(\\rho) = \\mathrm{Tr}(W^\\dagger \\rho) and :math:n is the number of\n", " qudits. The expectation value :math:\\mathrm{Tr}(W^\\dagger \\rho) is thus the\n", " :math:W component of :math:\\rho\\.\n", "\n", "\n", "Defining Weyl Operators in |True-Q|\n", "-----------------------------------\n", "\n", "A :math:n\\-qudit Weyl operator can be expressed as an element\n", ":math:w\\in\\mathbb{Z}_d^{2n} and an integer specifying the phase, where the first\n", "(last) :math:n entries of :math:w are the powers of the shift (clock) operators\n", "acting on each of the first (last) :math:n qudits. For example, the 3-qudit Weyl\n", "operator :math:X\\otimes X^2\\otimes Z can be specified by :math:1,2,0,0,0,1 with\n", ":math:k=0. To initialize a Weyl operator from a string in |True-Q|\\, we specify the\n", "action of the operator on each individual qudit sequentially, separated by a W.\n", "For example, the operator :math:X\\otimes X^2\\otimes Z given above would be specified\n", "by W10W20W01 as" ] }, { "cell_type": "code", "execution_count": 2, "id": "fc0fbadb", "metadata": { "execution": { "iopub.execute_input": "2022-08-04T20:09:08.709691Z", "iopub.status.busy": "2022-08-04T20:09:08.709421Z", "iopub.status.idle": "2022-08-04T20:09:09.604779Z", "shell.execute_reply": "2022-08-04T20:09:09.604296Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 2 0 0 0 1]]\n" ] } ], "source": [ "import numpy as np\n", "import trueq.math as tqm\n", "\n", "# create a three-qutrit Weyls object which stores the example given above\n", "weyl = tqm.Weyls(\"W10W20W01\", 3)\n", "\n", "# we can access the powers as follows:\n", "print(weyl.powers)" ] }, { "cell_type": "raw", "id": "b63a3420", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The second argument in the constructor specifies the dimension of the qudits. If the\n", "global dimension has been specified by tq.settings.set_dim(3), these methods will\n", "use the specified dimension automatically. To instantiate a\n", ":py:class:~trueq.math.weyl.Weyls object with multiple Weyl operators, we separate\n", "the operators by a _ character. In this notation, all operators must act on the\n", "same number of qudits. For example, for the pair :math:\\{Z\\otimes XZ^2,\n", "X^2\\otimes XZ\\}\\, we can run" ] }, { "cell_type": "code", "execution_count": 3, "id": "1be76055", "metadata": { "execution": { "iopub.execute_input": "2022-08-04T20:09:09.607229Z", "iopub.status.busy": "2022-08-04T20:09:09.606795Z", "iopub.status.idle": "2022-08-04T20:09:09.623869Z", "shell.execute_reply": "2022-08-04T20:09:09.623448Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "
True-Q formatting will not be loaded without trusting this\n", "notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking\n", "\"File -> Trust Notebook\".
\n", "\n", "\n", "\n", "
\n", "
\n", "
Type:
\n", "
• Weyls
\n", "\n", "
Dim:
\n", "
• 3
\n", "
\n", "
\n", " \n", "
Powers:
\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "
$X_0$$X_1$$Z_0$$Z_1 00112 12101 \n", " \n", " \n", " \n" ], "text/plain": [ "Weyls('W01W12_W20W11', dim=3)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tqm.Weyls(\"W01W12_W20W11\", 3)" ] }, { "cell_type": "raw", "id": "e7e91aa1", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. note::\n", " In the example above, we stored Weyl operators as\n", " :py:class:~trueq.math.weyl.Weyls objects. |True-Q| has several classes for\n", " storing Weyl operators which are used in different contexts. The\n", " :py:class:~trueq.math.weyl.Weyls class does not store phases, and is used, for\n", " example, to specify targeted errors for error diagnostic protocols such as\n", " :doc:../../guides/error_diagnostics/cb\\. Some of |True-Q|\\'s classes for Weyl\n", " operators account for phases and some do not. If you are unsure which is relevant\n", " for your use-case, consult the API references.\n", "\n", "\n", "The Clifford Group on Qudits\n", "----------------------------\n", "The :math:n\\-qudit Clifford group is defined to be the group of unitary operators\n", "that map each :math:n\\-qudit Weyl operator to a phase multiple of an\n", ":math:n\\-qudit Weyl operator under conjugation. This coincides with the definition\n", "of the :math:n\\-qubit Clifford group with respect to the Pauli group. We can specify\n", "elements of the :math:d\\-dimensional Clifford group by their unique action on a\n", "basis of the Weyl-Heisenberg group. |True-Q| follows the convention of specifying the\n", "mapping of the Weyl basis described by the rows of an identity matrix, that is the set\n", ":math:\\{X_1, X_2,...,X_n, Z_1,Z_2,...,Z_n\\}\\.\n", "\n", "A :py:class:~trueq.math.weyl.Clifford object then stores the outcome of applying the\n", "corresponding Clifford operator to each of those basis elements. For example, a\n", "generalized Hadamard (or Fourier) gate on 2 qudits maps the basis elements\n", ":math:XI\\rightarrow ZI\\, :math:IX\\rightarrow IZ\\, :math:ZI\\rightarrow X^{d-1}I\\,\n", "and :math:IZ\\rightarrow IX^{d-1}\\, and would therefore be stored as the ordered list\n", ":math:\\{ZI,\\: IZ,\\: X^{d-1}I,\\: IX^{d-1}\\}\\. We can instantiate a\n", ":py:class:~trueq.math.weyl.Clifford object which stores a Hadamard as\n", "\n", "instantiate a 2-qudit Hadamard gate with dimension 3" ] }, { "cell_type": "code", "execution_count": 4, "id": "5516fecf", "metadata": { "execution": { "iopub.execute_input": "2022-08-04T20:09:09.625760Z", "iopub.status.busy": "2022-08-04T20:09:09.625528Z", "iopub.status.idle": "2022-08-04T20:09:09.628020Z", "shell.execute_reply": "2022-08-04T20:09:09.627596Z" } }, "outputs": [], "source": [ "hadamard = tqm.Clifford(\"W01W00_W00W01_W20W00_W00W20\", [0, 0, 0, 0], 3)" ] }, { "cell_type": "raw", "id": "2219396f", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The second argument provides the phases on the basis elements after the Clifford is\n", "applied. |True-Q| has :py:class:~trueq.math.weyl.Clifford constructors for\n", "generalized versions of the Hadamard (:py:meth:~trueq.math.weyl.Clifford.fourier),\n", "controlled-X (:py:meth:~trueq.math.weyl.Clifford.cx) and controlled-Z\n", "(:py:meth:~trueq.math.weyl.Clifford.cz) gates." ] }, { "cell_type": "code", "execution_count": 5, "id": "04b1a8df", "metadata": { "execution": { "iopub.execute_input": "2022-08-04T20:09:09.629879Z", "iopub.status.busy": "2022-08-04T20:09:09.629656Z", "iopub.status.idle": "2022-08-04T20:09:09.631988Z", "shell.execute_reply": "2022-08-04T20:09:09.631586Z" } }, "outputs": [], "source": [ "built_in_h = tqm.Clifford.fourier(3)" ] }, { "cell_type": "raw", "id": "485b99ce", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "We can retrieve the unitary matrix representation of a\n", ":py:class:~trueq.math.weyl.Clifford by calling\n", ":py:meth:~trueq.math.weyl.Clifford.mat\\. Let's use the matrices to check if these\n", "constructions are equivalent:" ] }, { "cell_type": "code", "execution_count": 6, "id": "94a6785e", "metadata": { "execution": { "iopub.execute_input": "2022-08-04T20:09:09.633886Z", "iopub.status.busy": "2022-08-04T20:09:09.633584Z", "iopub.status.idle": "2022-08-04T20:09:09.637109Z", "shell.execute_reply": "2022-08-04T20:09:09.636707Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True],\n", " [ True, True, True, True, True, True, True, True, True]])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.isclose(hadamard.mat, np.kron(built_in_h.mat, built_in_h.mat))" ] }, { "cell_type": "raw", "id": "79cd8bd5", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Some users may desire to incorporate random Cliffords in their circuits. For\n", "convenience, we provide the :py:meth:~trueq.math.weyl.Clifford.random function that\n", "can construct a random Clifford as follows:" ] }, { "cell_type": "code", "execution_count": 7, "id": "0c192e17", "metadata": { "execution": { "iopub.execute_input": "2022-08-04T20:09:09.639054Z", "iopub.status.busy": "2022-08-04T20:09:09.638732Z", "iopub.status.idle": "2022-08-04T20:09:09.641992Z", "shell.execute_reply": "2022-08-04T20:09:09.641581Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", " True-Q formatting will not be loaded without trusting this\n", "notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking\n", "\"File -> Trust Notebook\". \n", "\n", "\n", "\n", " \n", " \n", " Type: \n", " • Clifford \n", "\n", " Dim: \n", " • 3 \n", " \n", " \n", " \n", " Generator images: \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " X_0$$X_1$$Z_0$$Z_1$$\\textrm{ph.}$
im($X_0$)21100
im($X_1$)12010
im($Z_0$)20002
im($Z_1$)20022
\n", "
\n", "
\n", "
\n" ], "text/plain": [ "Clifford('W21W10_W10W21_W20W00_W20W02', [0, 0, 2, 2], dim=3)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# construct a random Clifford on 2 qutrits\n", "tqm.Clifford.random(2, 3)" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "nbsphinx,raw_mimetype,-all", "main_language": "python", "notebook_metadata_filter": "-all", "text_representation": { "extension": ".py", "format_name": "percent" } }, "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.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }