[404218]: / Code / Cirq / 03 Qudits 10 Dimensions kkawchak.ipynb

Download this file

1647 lines (1646 with data), 58.3 kB

{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Vc_pi_tJfgbD"
      },
      "source": [
        "##### Copyright 2020 The Cirq Developers"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "cellView": "form",
        "id": "nF8-mErJfgv6"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lsV6t2orfimn"
      },
      "source": [
        "# Qudits"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "H8uAzxCifjsb"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://quantumai.google/cirq/build/qudits\"><img src=\"https://quantumai.google/site-assets/images/buttons/quantumai_logo_1x.png\" />View on QuantumAI</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/quantumlib/Cirq/blob/master/docs/build/qudits.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/colab_logo_1x.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/quantumlib/Cirq/blob/master/docs/build/qudits.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/github_logo_1x.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a href=\"https://storage.googleapis.com/tensorflow_docs/Cirq/docs/build/qudits.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/download_icon_1x.png\" />Download notebook</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "bd9529db1c0b",
        "outputId": "caf05880-26d9-4425-f5cd-6e671269643f",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "installing cirq...\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m17.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m577.4/577.4 kB\u001b[0m \u001b[31m15.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m57.6/57.6 kB\u001b[0m \u001b[31m3.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m66.4/66.4 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m594.6/594.6 kB\u001b[0m \u001b[31m44.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.0/2.0 MB\u001b[0m \u001b[31m66.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m120.2/120.2 kB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m223.8/223.8 kB\u001b[0m \u001b[31m21.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m229.9/229.9 kB\u001b[0m \u001b[31m20.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h  Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m151.7/151.7 kB\u001b[0m \u001b[31m10.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m45.6/45.6 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h  Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m60.6/60.6 kB\u001b[0m \u001b[31m5.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m71.5/71.5 kB\u001b[0m \u001b[31m7.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.7/1.7 MB\u001b[0m \u001b[31m70.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m112.2/112.2 kB\u001b[0m \u001b[31m11.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m69.6/69.6 kB\u001b[0m \u001b[31m6.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m485.6/485.6 kB\u001b[0m \u001b[31m34.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h  Building wheel for lark (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Building wheel for rpcq (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "installed cirq.\n"
          ]
        }
      ],
      "source": [
        "try:\n",
        "    import cirq\n",
        "except ImportError:\n",
        "    print(\"installing cirq...\")\n",
        "    !pip install --quiet cirq\n",
        "    print(\"installed cirq.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9c07f9b01c71"
      },
      "source": [
        "Most of the time in quantum computation, we work with qubits, which are 2-level quantum systems. However, it is possible to also define quantum computation with higher dimensional systems. A qu-*d*-it is a generalization of a qubit to a d-level or d-dimension system.  For example, the state of a single qubit is a superposition of two basis states, $|\\psi\\rangle=\\alpha|0\\rangle+\\beta|1\\rangle$, whereas the state of a qudit for a three dimensional system is a superposition of three basis states $|\\psi\\rangle=\\alpha|0\\rangle+\\beta|1\\rangle+\\gamma|2\\rangle$.\n",
        "\n",
        "Qudits with known values for d have specific names. A **qubit** has dimension 2, a **qutrit** has dimension 3, a **ququart** has dimension 4, and so on.\n",
        "In Cirq, qudits work exactly like qubits except they have a `dimension` attribute different than 2, and they can only be used with gates specific to that dimension. In cirq, both qubits and qudits are subclasses of the class `cirq.Qid`.\n",
        "\n",
        "To apply a gate to some qudits, the dimensions of the qudits must match the dimensions it works on.  For example, consider gate represents a unitary evolution on three qudits,. Further suppose that there are a qubit, a qutrit, and another qutrit. Then the gate's \"qid shape\" is `(2, 3, 3)` and its `on` method will accept exactly 3 `Qid`s with dimension 2, 3, and 3, respectively.\n",
        "\n",
        "This is an example single qutrit gate acting on a single qutrit in a simple quantum circuit:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "6b3c6308ddd3",
        "outputId": "ae36fd55-97fb-40de-fe34-ee63028d21de",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=3): ───[+1]───\n"
          ]
        }
      ],
      "source": [
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QutritPlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (3,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1],\n",
        "                         [1, 0, 0],\n",
        "                         [0, 1, 0]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=3)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QutritPlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vWUhanx-fofU"
      },
      "source": [
        "## cirq.Qid\n",
        "\n",
        "`cirq.Qid` is the type that represents both qubits and qudits.\n",
        "\n",
        "Cirq has the built-in qubit types, `cirq.NamedQubit`, `cirq.GridQubit`, and `cirq.LineQubit`, and it also provides corresponding `cirq.Qid` types:\n",
        "\n",
        "- `cirq.NamedQid`\n",
        "  - Example: Create a qutrit named 'a' by specifying the dimension in the constructor: `cirq.NamedQid('a', dimension=3)`.\n",
        "- `cirq.GridQid`\n",
        "  - Example: Create a qutrit at location (2, 0) by specifying the dimension in the constructor: `cirq.GridQid(2, 0, dimension=3)`.\n",
        "  - Example: You can create regions of `cirq.GridQid`s. For example, to create a 2x2 grid of ququarts, use `cirq.GridQid.rect(2, 2, dimension=4)`.\n",
        "- `cirq.LineQid`\n",
        "  - Example: Create a qutrit at location 1 on the line by specifying the dimension in the constructor: `cirq.LineQid(0, dimension=3)`.\n",
        "  - Example: You can create ranges of `cirq.LineQid`s. For example, to create qutrits on a line with locations from 0 to 4, use `cirq.LineQid.range(5, dimension=3)`.\n",
        "  \n",
        "By default `cirq.Qid` classes in cirq will default to qubits unless their `dimension` parameter is specified in creation. Thus a `cirq.Qid` like `cirq.NamedQid('a')` is a qubit."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CYYtVX6Ffq0b"
      },
      "source": [
        "### The `cirq.qid_shape` protocol\n",
        "\n",
        "Quantum gates, operations, and other types that act on a sequence of qudits can specify the dimension of each qudit they act on by implementing the `_qid_shape_` magic method.  This method returns a tuple of integers corresponding to the required dimension of each qudit it operates on, e.g. `(2, 3, 3)` means an object that acts on a qubit, a qutrit, and another qutrit.  When you specify `_qid_shape_` we say that the object implements the `qid_shape` protocol.\n",
        "\n",
        "When `cirq.Qid`s are used with `cirq.Gate`s, `cirq.Operation`s, and `cirq.Circuit`s, the dimension of each qid must match the corresponding entry in the qid shape. An error is raised otherwise.\n",
        "\n",
        "Callers can query the qid shape of an object or a list of `Qid`s by calling `cirq.qid_shape` on it. By default, `cirq.qid_shape` will return the equivalent qid shape for qubits if `_qid_shape_` is not defined.  In particular, for a qubit-only gate the qid shape is a tuple of 2s containing one 2 for each qubit e.g. `(2,) * cirq.num_qubits(gate)`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "ace20c5d8540",
        "outputId": "34526b03-6503-45c7-c74e-1334958c26a8",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(3,)\n"
          ]
        }
      ],
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QutritPlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GFh0hjB4ftMA"
      },
      "source": [
        "### Unitaries, mixtures, and channels on qudits\n",
        "\n",
        "The magic methods `_unitary_`, `_apply_unitary_`, `_mixture_`, and `_kraus_` can be used to define unitary gates, mixtures, and channels can be used with qudits (see [protocols](protocols.ipynb) for how these work.)\n",
        "\n",
        "Because the state space for qudits for $d>2$ live on larger dimensional spaces, the corresponding objects returned by the magic methods will be of corresponding higher dimension."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "d6ea1b23d1c5",
        "outputId": "4c8e16d6-9156-44ad-9f1f-2bb1c69f9361",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[[0 0 1]\n",
            " [1 0 0]\n",
            " [0 1 0]]\n"
          ]
        }
      ],
      "source": [
        "# Create an instance of the qutrit gate defined above. This gate implements _unitary_.\n",
        "gate = QutritPlusGate()\n",
        "\n",
        "# Because it acts on qutrits, its unitary is a 3 by 3 matrix.\n",
        "print(cirq.unitary(gate))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "cdd798defc4d"
      },
      "source": [
        "For a single qubit gate, its unitary is a 2x2 matrix, whereas for a single qutrit gate its unitary is a 3x3 matrix.  A two qutrit gate will have a unitary that is a 9x9 matrix (3 * 3 = 9) and a qubit-ququart gate will have a unitary that is an 8x8 matrix (2 * 4 = 8).  The size of the matrices involved in defining mixtures and channels follow the same pattern."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8a68e38cd33a"
      },
      "source": [
        "### Simulating qudits\n",
        "\n",
        "Cirq's simulators can be used to simulate or sample from circuits which act on qudits.\n",
        "\n",
        "Simulators like `cirq.Simulator` and `cirq.DensityMatrixSimulator` will return simulation results with larger states than the same size qubit circuit when simulating qudit circuits. The size of the state returned is determined by the product of the dimensions of the qudits being simulated. For example, the state vector output of `cirq.Simulator` after simulating a circuit on a qubit, a qutrit, and a qutrit will have 2 * 3 * 3 = 18 elements. You can call `cirq.qid_shape(simulation_result)` to check the qudit dimensions.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "509a4796a715",
        "outputId": "5d74127a-e402-4f07-8ef5-e5a08d850ec0",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(3,)\n"
          ]
        }
      ],
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=3)\n",
        "circuit = cirq.Circuit(QutritPlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "d4jXoXdiutPr"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "BgY6cKI3utZC"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Q4\n",
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QuquartPlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (4,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1, 0],\n",
        "                         [1, 0, 0, 0],\n",
        "                         [0, 1, 0, 0],\n",
        "                         [0, 1, 0, 1]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=4)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QuquartPlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ],
      "metadata": {
        "id": "vkfESNuulg1m",
        "outputId": "b23443f6-f494-48f3-f642-0ee93bd56d65",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 20,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=4): ───[+1]───\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QuquartPlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ],
      "metadata": {
        "id": "GAaYbNKplONH",
        "outputId": "3f9832cb-f717-4ae5-97b0-347dab9fe8f3",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 21,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(4,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=4)\n",
        "circuit = cirq.Circuit(QuquartPlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ],
      "metadata": {
        "id": "CqQGjR9KkQ0-",
        "outputId": "d75bef33-0974-46a8-e7b1-39120a540382",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(4,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "id": "f08d7216b7eb",
        "outputId": "83228b5e-ecd8-4a97-9dff-394c58eb2bf1",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x=1111, 3232\n"
          ]
        }
      ],
      "source": [
        "# Ququart\n",
        "q0, q1 = cirq.LineQid.range(2, dimension=4)\n",
        "circuit = cirq.Circuit([\n",
        "    QuquartPlusGate()(q0),\n",
        "    QuquartPlusGate()(q1),\n",
        "    QuquartPlusGate()(q1),\n",
        "    cirq.measure(q0, q1, key=\"x\")\n",
        "])\n",
        "\n",
        "# Sample from this circuit.\n",
        "result = cirq.sample(circuit, repetitions=4)\n",
        "\n",
        "# See that the results are all integers from 0 to 2.\n",
        "print(result)"
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "6v_Fvlo7n2Gb"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "pOWcMPSIupCd"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Q5\n",
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QuFivePlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (5,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1, 0, 0],\n",
        "                         [1, 0, 0, 0, 0],\n",
        "                         [0, 1, 0, 0, 0],\n",
        "                         [0, 1, 0, 1, 0],\n",
        "                         [0, 0, 1, 0, 0]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=5)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QuFivePlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ],
      "metadata": {
        "id": "0c5kHMBPn2KY",
        "outputId": "4724ca54-e6bd-40b0-c939-4bee128acadb",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 35,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=5): ───[+1]───\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QuFivePlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ],
      "metadata": {
        "id": "TCGmpsQdp_4X",
        "outputId": "dfd67d87-7ac7-410f-fba5-43ed2df84e56",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 36,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(5,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=5)\n",
        "circuit = cirq.Circuit(QuFivePlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ],
      "metadata": {
        "id": "eL6DheW5qARO",
        "outputId": "69b0235b-4422-4ca9-9d48-4b0d0bf8a354",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 37,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(5,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# 5 Dimension\n",
        "q0, q1 = cirq.LineQid.range(2, dimension=5)\n",
        "circuit = cirq.Circuit([\n",
        "    QuFivePlusGate()(q0),\n",
        "    QuFivePlusGate()(q1),\n",
        "    QuFivePlusGate()(q1),\n",
        "    cirq.measure(q0, q1, key=\"x\")\n",
        "])\n",
        "\n",
        "# Sample from this circuit.\n",
        "result = cirq.sample(circuit, repetitions=5)\n",
        "\n",
        "# See that the results are all integers from 0 to 2.\n",
        "print(result)"
      ],
      "metadata": {
        "id": "zYZSi3HpqAVL",
        "outputId": "24518560-9b7a-4715-bdd6-0b95e1800226",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 38,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x=11111, 33322\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "kV3npVBjqAY3"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "Q6-vxZ2PqAct"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Q6\n",
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QuSixPlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (6,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1, 0, 0, 1],\n",
        "                         [1, 0, 0, 0, 0, 0],\n",
        "                         [0, 1, 0, 0, 0, 1],\n",
        "                         [0, 1, 0, 1, 0, 0],\n",
        "                         [0, 0, 1, 0, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=6)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QuSixPlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ],
      "metadata": {
        "id": "8ns4RPV2qAg1",
        "outputId": "35f67a91-15a3-427a-ccfa-0a6435aca35d",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 39,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=6): ───[+1]───\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QuSixPlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ],
      "metadata": {
        "id": "G3cYgAIqq1nj",
        "outputId": "0c35bcc2-4d8b-42c1-9aa7-88c1deb8b89f",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 40,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(6,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=6)\n",
        "circuit = cirq.Circuit(QuSixPlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ],
      "metadata": {
        "id": "oAdsQHmhq2vr",
        "outputId": "061361f6-e4e5-4edf-99cd-ddca98d40ffa",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 41,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(6,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# 6 Dimension\n",
        "q0, q1 = cirq.LineQid.range(2, dimension=6)\n",
        "circuit = cirq.Circuit([\n",
        "    QuSixPlusGate()(q0),\n",
        "    QuSixPlusGate()(q1),\n",
        "    QuSixPlusGate()(q1),\n",
        "    cirq.measure(q0, q1, key=\"x\")\n",
        "])\n",
        "\n",
        "# Sample from this circuit.\n",
        "result = cirq.sample(circuit, repetitions=6)\n",
        "\n",
        "# See that the results are all integers from 0 to 2.\n",
        "print(result)"
      ],
      "metadata": {
        "id": "USes6WhPq241",
        "outputId": "ddd1b7f7-6b4f-4a9f-92dd-c676e3b7f84e",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 42,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x=111111, 333232\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "uLwO8Nr-q2-J"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "WZ1FYjDSq3Cd"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Q7\n",
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QuSevenPlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (7,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1, 0, 0, 1, 0],\n",
        "                         [1, 0, 0, 0, 0, 0, 0],\n",
        "                         [0, 1, 0, 0, 0, 1, 0],\n",
        "                         [0, 1, 0, 1, 0, 0, 0],\n",
        "                         [0, 0, 1, 0, 0, 1, 0],\n",
        "                         [0, 1, 0, 0, 0, 1, 0],\n",
        "                         [0, 0, 1, 0, 0, 1, 0]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=7)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QuSevenPlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ],
      "metadata": {
        "id": "Eqloncwbq3F7",
        "outputId": "4660e430-435e-45ce-c46f-d00598f7b822",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 43,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=7): ───[+1]───\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QuSevenPlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ],
      "metadata": {
        "id": "ug6lRi8-q3JT",
        "outputId": "aeabf6b7-8012-4d0d-bba1-8cccafcfcba1",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 44,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(7,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=7)\n",
        "circuit = cirq.Circuit(QuSevenPlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ],
      "metadata": {
        "id": "9JKiM-e4q3M_",
        "outputId": "f4dd1a05-dc68-4db0-e638-f5df6fdb67d4",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 45,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(7,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# 7 Dimension\n",
        "q0, q1 = cirq.LineQid.range(2, dimension=7)\n",
        "circuit = cirq.Circuit([\n",
        "    QuSevenPlusGate()(q0),\n",
        "    QuSevenPlusGate()(q1),\n",
        "    QuSevenPlusGate()(q1),\n",
        "    cirq.measure(q0, q1, key=\"x\")\n",
        "])\n",
        "\n",
        "# Sample from this circuit.\n",
        "result = cirq.sample(circuit, repetitions=7)\n",
        "\n",
        "# See that the results are all integers from 0 to 2.\n",
        "print(result)"
      ],
      "metadata": {
        "id": "Xi2D6KyCq3QS",
        "outputId": "e336de14-42c3-475f-f3c6-7f1d7dd1f215",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 46,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x=1111111, 2322323\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "_6d3Hk5jrrBA"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "y8rpR3M3rrGh"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Q8\n",
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QuEightPlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (8,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1, 0, 0, 1, 0, 1],\n",
        "                         [1, 0, 0, 0, 0, 0, 0, 1],\n",
        "                         [0, 1, 0, 0, 0, 1, 0, 1],\n",
        "                         [0, 1, 0, 1, 0, 0, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1],\n",
        "                         [0, 1, 0, 0, 0, 1, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=8)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QuEightPlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ],
      "metadata": {
        "id": "_U-QKZSnsgQL",
        "outputId": "91ae3d27-8bf9-41b5-ea19-52d9227fbbf5",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 47,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=8): ───[+1]───\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QuEightPlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ],
      "metadata": {
        "id": "h3vlOnZ7sgWD",
        "outputId": "9a369d3c-d14c-4587-e691-228c23285829",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 48,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(8,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=8)\n",
        "circuit = cirq.Circuit(QuEightPlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ],
      "metadata": {
        "id": "MzrYVYN2sga1",
        "outputId": "8d8e6841-a83e-48b6-e565-b208f7b243e2",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 49,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(8,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# 8 Dimension\n",
        "q0, q1 = cirq.LineQid.range(2, dimension=8)\n",
        "circuit = cirq.Circuit([\n",
        "    QuEightPlusGate()(q0),\n",
        "    QuEightPlusGate()(q1),\n",
        "    QuEightPlusGate()(q1),\n",
        "    cirq.measure(q0, q1, key=\"x\")\n",
        "])\n",
        "\n",
        "# Sample from this circuit.\n",
        "result = cirq.sample(circuit, repetitions=8)\n",
        "\n",
        "# See that the results are all integers from 0 to 2.\n",
        "print(result)"
      ],
      "metadata": {
        "id": "u_Rwq74nsgfC",
        "outputId": "fea25813-b2db-4e35-d775-30d197c188b7",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 50,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x=11111111, 32232333\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "wemMn4oTsgi5"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "eMTwVF0prrLo"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Q9\n",
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QuNinePlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (9,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1, 0, 0, 1, 0, 1, 0],\n",
        "                         [1, 0, 0, 0, 0, 0, 0, 1, 0],\n",
        "                         [0, 1, 0, 0, 0, 1, 0, 1, 0],\n",
        "                         [0, 1, 0, 1, 0, 0, 0, 1, 0],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0],\n",
        "                         [0, 1, 0, 0, 0, 1, 0, 1, 0],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=9)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QuNinePlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ],
      "metadata": {
        "id": "pCk94RT-rrQU",
        "outputId": "822493b6-f335-470e-c4ef-716bcf14dd29",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 51,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=9): ───[+1]───\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QuNinePlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ],
      "metadata": {
        "id": "TJ1404lbtH5Q",
        "outputId": "10eeddef-f603-4c08-e5f4-fbfdfefa770f",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 52,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(9,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=9)\n",
        "circuit = cirq.Circuit(QuNinePlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ],
      "metadata": {
        "id": "4Ba4Ax70tH-v",
        "outputId": "285d6fcc-c89f-4354-c85c-c5247078fbae",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 53,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(9,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# 9 Dimension\n",
        "q0, q1 = cirq.LineQid.range(2, dimension=9)\n",
        "circuit = cirq.Circuit([\n",
        "    QuNinePlusGate()(q0),\n",
        "    QuNinePlusGate()(q1),\n",
        "    QuNinePlusGate()(q1),\n",
        "    cirq.measure(q0, q1, key=\"x\")\n",
        "])\n",
        "\n",
        "# Sample from this circuit.\n",
        "result = cirq.sample(circuit, repetitions=9)\n",
        "\n",
        "# See that the results are all integers from 0 to 2.\n",
        "print(result)"
      ],
      "metadata": {
        "id": "gEL4q4eAtID0",
        "outputId": "78940d9b-1224-493f-fadc-5836a01c3978",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 54,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x=111111111, 352322333\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "SSxtSSjHt03_"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "_rY6_xU0t08b"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Q10\n",
        "import cirq\n",
        "import numpy as np\n",
        "\n",
        "class QuTenPlusGate(cirq.Gate):\n",
        "    \"\"\"A gate that adds one in the computational basis of a qutrit.\n",
        "\n",
        "    This gate acts on three-level systems. In the computational basis of\n",
        "    this system it enacts the transformation U|x〉 = |x + 1 mod 3〉, or\n",
        "    in other words U|0〉 = |1〉, U|1〉 = |2〉, and U|2> = |0〉.\n",
        "    \"\"\"\n",
        "\n",
        "    def _qid_shape_(self):\n",
        "        # By implementing this method this gate implements the\n",
        "        # cirq.qid_shape protocol and will return the tuple (3,)\n",
        "        # when cirq.qid_shape acts on an instance of this class.\n",
        "        # This indicates that the gate acts on a single qutrit.\n",
        "        return (10,)\n",
        "\n",
        "    def _unitary_(self):\n",
        "        # Since the gate acts on three level systems it has a unitary\n",
        "        # effect which is a three by three unitary matrix.\n",
        "        return np.array([[0, 0, 1, 0, 0, 1, 0, 1, 0, 1],\n",
        "                         [1, 0, 0, 0, 0, 0, 0, 1, 0, 1],\n",
        "                         [0, 1, 0, 0, 0, 1, 0, 1, 0, 1],\n",
        "                         [0, 1, 0, 1, 0, 0, 0, 1, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0, 1],\n",
        "                         [0, 1, 0, 0, 0, 1, 0, 1, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0, 1],\n",
        "                         [0, 0, 1, 0, 0, 1, 0, 1, 0, 1]])\n",
        "\n",
        "    def _circuit_diagram_info_(self, args):\n",
        "        return '[+1]'\n",
        "\n",
        "# Here we create a qutrit for the gate to act on.\n",
        "q0 = cirq.LineQid(0, dimension=10)\n",
        "\n",
        "# We can now enact the gate on this qutrit.\n",
        "circuit = cirq.Circuit(\n",
        "    QuTenPlusGate().on(q0)\n",
        ")\n",
        "\n",
        "# When we print this out we see that the qutrit is labeled by its dimension.\n",
        "print(circuit)"
      ],
      "metadata": {
        "id": "6GGWJYxIt1L9",
        "outputId": "11abc73a-dff9-45ed-a72f-1e2c68724804",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 55,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 (d=10): ───[+1]───\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create an instance of the qutrit gate defined above.\n",
        "gate = QuTenPlusGate()\n",
        "\n",
        "# Verify that it acts on a single qutrit.\n",
        "print(cirq.qid_shape(gate))"
      ],
      "metadata": {
        "id": "8hTjWaugt1QZ",
        "outputId": "276febfa-f84a-4070-b417-01ed08f8f3e3",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 56,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(10,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Create a circuit from the gate we defined above.\n",
        "q0 = cirq.LineQid(0, dimension=10)\n",
        "circuit = cirq.Circuit(QuTenPlusGate()(q0))\n",
        "\n",
        "# Run a simulation of this circuit.\n",
        "sim = cirq.Simulator()\n",
        "result = sim.simulate(circuit)\n",
        "\n",
        "# Verify that the returned state is that of a qutrit.\n",
        "print(cirq.qid_shape(result))"
      ],
      "metadata": {
        "id": "h_dzwKMRt1Uf",
        "outputId": "724bf082-519c-4816-b603-ef9f20a074aa",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 57,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(10,)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# 10 Dimension\n",
        "q0, q1 = cirq.LineQid.range(2, dimension=10)\n",
        "circuit = cirq.Circuit([\n",
        "    QuTenPlusGate()(q0),\n",
        "    QuTenPlusGate()(q1),\n",
        "    QuTenPlusGate()(q1),\n",
        "    cirq.measure(q0, q1, key=\"x\")\n",
        "])\n",
        "\n",
        "# Sample from this circuit.\n",
        "result = cirq.sample(circuit, repetitions=10)\n",
        "\n",
        "# See that the results are all integers from 0 to 2.\n",
        "print(result)"
      ],
      "metadata": {
        "id": "2w1H0oybtIJn",
        "outputId": "6fff18e8-5f21-4028-ff46-65d066a0b514",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        }
      },
      "execution_count": 58,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "x=1111111111, 2552532525\n"
          ]
        }
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "qudits.ipynb",
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}