{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9a2bf45c",
   "metadata": {},
   "source": [
    "# Tensor product between QOperations\n",
    "\n",
    "This note describes tensor products between Qoperations and their samples."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ad23cfb",
   "metadata": {},
   "source": [
    "## Tensor Product\n",
    "\n",
    "Tensor product is an operation in the **spatial direction**.  To compute the tensor product, use `tensor_product()` in the `quara.objects.operators` module.\n",
    "\n",
    "As a simple example, let's look at how to compute the tensor product between the following States.\n",
    "\n",
    "**formula:**\n",
    "\n",
    "$\\rho_{z0} {\\otimes } \\rho_{z1}$\n",
    "\n",
    "**quantum circuit diagram:**\n",
    "\n",
    "── $\\rho_{z0}$ ──   \n",
    "── $\\rho_{z1}$ ──"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86f0a40d",
   "metadata": {},
   "source": [
    "First, prepare the State to be used for the operation. Note that the IDs of the ElementalSystems between QOperations to be calculated with tensor products must be different."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2c29e024",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vec of state_z0: [0.70710678 0.         0.         0.70710678]\n",
      "vec of state_z1: [ 0.70710678  0.          0.         -0.70710678]\n"
     ]
    }
   ],
   "source": [
    "from quara.objects.composite_system_typical import generate_composite_system\n",
    "from quara.objects.qoperation_typical import generate_qoperation\n",
    "\n",
    "# Prepare State\n",
    "c_sys_0 = generate_composite_system(\"qubit\", 1, ids_esys=[0])\n",
    "c_sys_1 = generate_composite_system(\"qubit\", 1, ids_esys=[1])\n",
    "state_z0 = generate_qoperation(mode=\"state\", name=\"z0\", c_sys=c_sys_0)\n",
    "state_z1 = generate_qoperation(mode=\"state\", name=\"z1\", c_sys=c_sys_1)\n",
    "\n",
    "print(f\"vec of state_z0: {state_z0.vec}\")\n",
    "print(f\"vec of state_z1: {state_z1.vec}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42e79d53",
   "metadata": {},
   "source": [
    "$\\rho_{z0} {\\otimes } \\rho_{z1}$ can be written as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "53c5e050",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "State\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "Vec:\n",
      "[ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n"
     ]
    }
   ],
   "source": [
    "from quara.objects.operators import tensor_product\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(state_z0, state_z1)\n",
    "\n",
    "# Result\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd5e018c",
   "metadata": {},
   "source": [
    "The result of the tensor product between 1-qubit States is a 2-qubit State."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09687445",
   "metadata": {},
   "source": [
    "### Order of operations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab5672de",
   "metadata": {},
   "source": [
    "The order of operations within `tensor_product()` follows the **order of the ElementalSystem IDs of each QOperation** in ascending order.\n",
    "\n",
    "In the following cases, the tensor product of $\\rho_{z0}$ and $\\rho_{z1}$ is computed. Since the ElementalSystem ID of $\\rho_{z0}$ is `0` and the ElementalSystem ID of $\\rho_{z0}$ is `1`, the tensor product is calculated in the order $\\rho_{z0} {\\otimes } {\\rho_{z1}}$. Because the calculation is based on the order of the IDs in the ElementalSystem, the result will be the same even if the order passed to the `tensor_product()` argument is different."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a6abdf4e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Case 1:\n",
      "[ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n",
      "Case 2:\n",
      "[ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n"
     ]
    }
   ],
   "source": [
    "# Prepare State\n",
    "c_sys_0 = generate_composite_system(\"qubit\", 1, ids_esys=[0])\n",
    "c_sys_1 = generate_composite_system(\"qubit\", 1, ids_esys=[1])\n",
    "state_0 = generate_qoperation(mode=\"state\", name=\"z0\", c_sys=c_sys_0)\n",
    "state_1 = generate_qoperation(mode=\"state\", name=\"z1\", c_sys=c_sys_1)\n",
    "\n",
    "# Case 1:\n",
    "result = tensor_product(state_z0, state_z1)\n",
    "print(\"Case 1:\")\n",
    "print(result.vec)\n",
    "\n",
    "# Case 2: Same result as Case 1\n",
    "result = tensor_product(state_z1, state_z0)\n",
    "print(\"Case 2:\")\n",
    "print(result.vec)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2c6803f",
   "metadata": {},
   "source": [
    "Different ElementalSystem IDs will change the results as follows. Since the ElementalSystem ID of $\\rho_{z0}$ is `1` and the ElementalSystem ID of $\\rho_{z0}$ is `0`, the tensor product is calculated in the order $\\rho_{z1} {\\otimes } {\\rho_{z0}}$, not  $\\rho_{z0} {\\otimes } {\\rho_{z1}}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ef8fef8e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Case 3:\n",
      "[ 0.5  0.   0.   0.5  0.   0.   0.   0.   0.   0.   0.   0.  -0.5  0.\n",
      "  0.  -0.5]\n"
     ]
    }
   ],
   "source": [
    "# Prepare State\n",
    "c_sys_0 = generate_composite_system(\"qubit\", 1, ids_esys=[1])  # change id_esys\n",
    "c_sys_1 = generate_composite_system(\"qubit\", 1, ids_esys=[0])  # change id_esys\n",
    "state_z0 = generate_qoperation(mode=\"state\", name=\"z0\", c_sys=c_sys_0)\n",
    "state_z1 = generate_qoperation(mode=\"state\", name=\"z1\", c_sys=c_sys_1)\n",
    "\n",
    "# Case 3: Different results from Case 1 and Case 2\n",
    "result = tensor_product(state_z0, state_z1)\n",
    "print(\"Case 3:\")\n",
    "print(result.vec)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9592598",
   "metadata": {},
   "source": [
    "### Tensor product of three or more QOperations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7681b787",
   "metadata": {},
   "source": [
    "For three or more QOepration operations, add to the argument. The following code computes the tensor product of three States ( $\\rho_{z0} {\\otimes } \\rho_{z1} {\\otimes } \\rho_{x0}$ ) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "18169f14",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "State\n",
      "\n",
      "Dim:\n",
      "8\n",
      "\n",
      "Vec:\n",
      "[ 0.35355339  0.35355339  0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      " -0.35355339 -0.35355339  0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      "  0.35355339  0.35355339  0.          0.          0.          0.\n",
      "  0.          0.          0.          0.          0.          0.\n",
      " -0.35355339 -0.35355339  0.          0.        ]\n"
     ]
    }
   ],
   "source": [
    "# Prepare States\n",
    "c_sys_0 = generate_composite_system(\"qubit\", 1, ids_esys=[0])\n",
    "c_sys_1 = generate_composite_system(\"qubit\", 1, ids_esys=[1])\n",
    "c_sys_2 = generate_composite_system(\"qubit\", 1, ids_esys=[2])\n",
    "\n",
    "state_z0 = generate_qoperation(mode=\"state\", name=\"z0\", c_sys=c_sys_0)\n",
    "state_z1 = generate_qoperation(mode=\"state\", name=\"z1\", c_sys=c_sys_1)\n",
    "state_x0 = generate_qoperation(mode=\"state\", name=\"x0\", c_sys=c_sys_2)\n",
    "\n",
    "# Tensor product of three or more QOperations\n",
    "result = tensor_product(state_z0, state_z1, state_x0)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aea5914f",
   "metadata": {},
   "source": [
    "It is also possible to specify QOperations as a list. For example, the following two expressions have the same meaning."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e53cf1ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Specify by appending to the argument\n",
    "result = tensor_product(state_z0, state_z1, state_x0)\n",
    "\n",
    "# Specify by list\n",
    "result = tensor_product([state_z0, state_z1, state_x0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "497217e1",
   "metadata": {},
   "source": [
    "### Utility for typical tensor product\n",
    "\n",
    "Tensor products between typical QOperations can also be computed with `generate_qoperation()`. The tensor product of Qoperation names \"a\" and \"b\" is written \"a_b\".\n",
    "\n",
    "For example, the tensor product of two States, z0 and z1, can be written as follows"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "cc295789",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "State\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "Vec:\n",
      "[ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n"
     ]
    }
   ],
   "source": [
    "from quara.objects.qoperation_typical import generate_qoperation\n",
    "\n",
    "# Using utility function\n",
    "# Tensor product of z0 and z1\n",
    "c_sys_2qubit = generate_composite_system(\"qubit\", 2, ids_esys=[0, 1])\n",
    "result =  generate_qoperation(mode=\"state\", name=\"z0_z1\", c_sys=c_sys_2qubit)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d7ded79",
   "metadata": {},
   "source": [
    "## Supported operations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ca4739c",
   "metadata": {},
   "source": [
    "The `tensor_product()` supports the following combinations of QOperations.\n",
    "\n",
    "| Input | Output |\n",
    "|:-------|:---------|\n",
    "| State ${\\otimes }$ State | State|\n",
    "| Povm ${\\otimes }$ Povm | Povm |\n",
    "|Gate ${\\otimes }$ Gate | Gate |\n",
    "| State ${\\otimes }$ StateEnsemble | StateEnsemble |\n",
    "| StateEnsemble ${\\otimes }$ State |  StateEnsemble |\n",
    "| StateEnsemble ${\\otimes }$ StateEnsemble |  StateEnsemble |\n",
    "|Gate ${\\otimes }$ MProcess | MProcess |\n",
    "| MProcess ${\\otimes }$ Gate | MProcess |\n",
    "| MProcess ${\\otimes }$ MProcess | MProcess |\n",
    "| MatrixBasis ${\\otimes }$ MatrixBasis | MatrixBasis |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ff18b8a",
   "metadata": {},
   "source": [
    "## Examples"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a4b32d3",
   "metadata": {},
   "source": [
    "### State ${\\otimes }$ State -> State"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "cf1ab8d6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "State\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "Vec:\n",
      "[ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "c_sys_0 = generate_composite_system(\"qubit\", 1, ids_esys=[0])\n",
    "c_sys_1 = generate_composite_system(\"qubit\", 1, ids_esys=[1])\n",
    "state_0 = generate_qoperation(mode=\"state\", name=\"z0\", c_sys=c_sys_0)\n",
    "state_1 = generate_qoperation(mode=\"state\", name=\"z1\", c_sys=c_sys_1)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(state_0, state_1)\n",
    "print(result)  # State"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0508d8cb",
   "metadata": {},
   "source": [
    "### Povm ${\\otimes }$ Povm -> Povm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "89c717ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "Povm\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "Number of outcomes:\n",
      "4\n",
      "\n",
      "Vecs:\n",
      "[[ 0.5  0.   0.   0.5  0.5  0.   0.   0.5  0.   0.   0.   0.   0.   0.\n",
      "   0.   0. ]\n",
      " [ 0.5  0.   0.  -0.5  0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.\n",
      "   0.   0. ]\n",
      " [ 0.5  0.   0.   0.5 -0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.\n",
      "   0.   0. ]\n",
      " [ 0.5  0.   0.  -0.5 -0.5  0.   0.   0.5  0.   0.   0.   0.   0.   0.\n",
      "   0.   0. ]]\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "povm_0 = generate_qoperation(mode=\"povm\", name=\"x\", c_sys=c_sys_0)\n",
    "povm_1 = generate_qoperation(mode=\"povm\", name=\"z\", c_sys=c_sys_1)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(povm_0, povm_1)\n",
    "print(result)  # Povm"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9a0e023",
   "metadata": {},
   "source": [
    "### Gate ${\\otimes }$ Gate -> Gate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "7a938582",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "Gate\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "HS:\n",
      "[[ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0. -1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0. -1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0. -1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0. -1.  0.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0. -1.  0.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0. -1.  0.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0. -1.  0.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0. -1.  0.]\n",
      " [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.]]\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "gate_0 = generate_qoperation(mode=\"gate\", name=\"x\", c_sys=c_sys_0)\n",
    "gate_1 = generate_qoperation(mode=\"gate\", name=\"y\", c_sys=c_sys_1)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(gate_0, gate_1)\n",
    "print(result)  # Gate"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65eb3f5c",
   "metadata": {},
   "source": [
    "### State ${\\otimes }$ StateEnsemble -> StateEnsemble"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "36c2dc50",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "StateEnsemble\n",
      "\n",
      "States:\n",
      "states[0]: [0.5 0.  0.  0.5 0.  0.  0.  0.  0.  0.  0.  0.  0.5 0.  0.  0.5]\n",
      "states[1]: [ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n",
      "\n",
      "MultinomialDistribution:\n",
      "shape = (2,)\n",
      "ps = [1. 0.]\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "state_0 = generate_qoperation(mode=\"state\", name=\"z0\", c_sys=c_sys_0)\n",
    "state_ensemble_0 = generate_qoperation(mode=\"state_ensemble\", name=\"z0\", c_sys=c_sys_1)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(state_0, state_ensemble_0)\n",
    "print(result)  # StateEnsemble"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3306bd02",
   "metadata": {},
   "source": [
    "### StateEnsemble ${\\otimes }$ State -> StateEnsemble"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "15b4df29",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "StateEnsemble\n",
      "\n",
      "States:\n",
      "states[0]: [0.5 0.  0.  0.5 0.  0.  0.  0.  0.  0.  0.  0.  0.5 0.  0.  0.5]\n",
      "states[1]: [ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n",
      "\n",
      "MultinomialDistribution:\n",
      "shape = (2,)\n",
      "ps = [1. 0.]\n"
     ]
    }
   ],
   "source": [
    "# Tensor product\n",
    "result = tensor_product(state_ensemble_0, state_0)\n",
    "print(result)  # StateEnsemble"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d341850d",
   "metadata": {},
   "source": [
    "### StateEnsemble ${\\otimes }$ StateEnsemble -> StateEnsemble"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d6ec9787",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "StateEnsemble\n",
      "\n",
      "States:\n",
      "states[0]: [0.5 0.  0.  0.5 0.  0.  0.  0.  0.  0.  0.  0.  0.5 0.  0.  0.5]\n",
      "states[1]: [ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.   0.5  0.\n",
      "  0.  -0.5]\n",
      "states[2]: [ 0.5  0.   0.   0.5  0.   0.   0.   0.   0.   0.   0.   0.  -0.5  0.\n",
      "  0.  -0.5]\n",
      "states[3]: [ 0.5  0.   0.  -0.5  0.   0.   0.   0.   0.   0.   0.   0.  -0.5  0.\n",
      "  0.   0.5]\n",
      "\n",
      "MultinomialDistribution:\n",
      "shape = (2, 2)\n",
      "ps = [0. 1. 0. 0.]\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "state_ensemble_0 = generate_qoperation(mode=\"state_ensemble\", name=\"z0\", c_sys=c_sys_0)\n",
    "state_ensemble_1 = generate_qoperation(mode=\"state_ensemble\", name=\"z1\", c_sys=c_sys_1)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(state_ensemble_0, state_ensemble_1)\n",
    "print(result)  # StateEnsemble"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3938276",
   "metadata": {},
   "source": [
    "### Gate ${\\otimes }$ MProcess -> MProcess"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "104c34d6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "MProcess\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "HSs:\n",
      "[array([[ 0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , -0.5, -0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , -0.5, -0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. , -0.5, -0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. , -0.5, -0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ]]), array([[ 0.5, -0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [-0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0.5, -0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. , -0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , -0.5,  0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0.5, -0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. , -0.5,  0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0.5, -0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ]])]\n",
      "\n",
      "ModeSampling:\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "gate_0 = generate_qoperation(mode=\"gate\", name=\"x\", c_sys=c_sys_0)\n",
    "mprocess_0 = generate_qoperation(mode=\"mprocess\", name=\"x-type1\", c_sys=c_sys_1)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(gate_0, mprocess_0)\n",
    "print(result)  # MProcess"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b59afb1e",
   "metadata": {},
   "source": [
    "### MProcess ${\\otimes }$ Gate -> MProcess"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "b14e3541",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "MProcess\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "HSs:\n",
      "[array([[ 0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , -0.5, -0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , -0.5, -0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. , -0.5, -0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. , -0.5, -0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ]]), array([[ 0.5, -0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [-0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0.5, -0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. , -0.5,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , -0.5,  0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0.5, -0.5,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. , -0.5,  0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0.5, -0.5,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,\n",
      "         0. ,  0. ,  0. ,  0. ,  0. ]])]\n",
      "\n",
      "ModeSampling:\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "mprocess_0 = generate_qoperation(mode=\"mprocess\", name=\"x-type1\", c_sys=c_sys_1)\n",
    "gate_0 = generate_qoperation(mode=\"gate\", name=\"x\", c_sys=c_sys_0)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(mprocess_0, gate_0)\n",
    "print(result)  # MProcess"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23edeb2b",
   "metadata": {},
   "source": [
    "### MProcess ${\\otimes }$ MProcess -> MProcess"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "591dc759",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "MProcess\n",
      "\n",
      "Dim:\n",
      "4\n",
      "\n",
      "HSs:\n",
      "[array([[0.25, 0.25, 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.25, 0.25, 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.25, 0.25, 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.25, 0.25, 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.25, 0.25, 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.25, 0.25, 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.25, 0.25, 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.25, 0.25, 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ],\n",
      "       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ,\n",
      "        0.  , 0.  , 0.  , 0.  , 0.  ]]), array([[ 0.25, -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,\n",
      "        -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [-0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  , -0.25,\n",
      "         0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.25, -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,\n",
      "        -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [-0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  , -0.25,\n",
      "         0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ]]), array([[ 0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  , -0.25,\n",
      "        -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  , -0.25,\n",
      "        -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [-0.25, -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,\n",
      "         0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [-0.25, -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,\n",
      "         0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ]]), array([[ 0.25, -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  , -0.25,\n",
      "         0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [-0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,\n",
      "        -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [-0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,\n",
      "        -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.25, -0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  , -0.25,\n",
      "         0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],\n",
      "       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,\n",
      "         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ]])]\n",
      "\n",
      "ModeSampling:\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# Prepare\n",
    "mprocess_0 = generate_qoperation(mode=\"mprocess\", name=\"x-type1\", c_sys=c_sys_1)\n",
    "mprocess_1 = generate_qoperation(mode=\"mprocess\", name=\"y-type1\", c_sys=c_sys_0)\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(mprocess_0, mprocess_1)\n",
    "print(result)  # MProcess"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b613d4ce",
   "metadata": {},
   "source": [
    "### MatrixBasis ${\\otimes }$ MatrixBasis -> MatrixBasis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "5013ec23",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]]), array([[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n",
      "       [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]]), array([[0.+0.j, 0.-1.j, 0.+0.j, 0.-0.j],\n",
      "       [0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 0.-0.j, 0.+0.j, 0.-1.j],\n",
      "       [0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j]]), array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j, -1.+0.j,  0.+0.j, -0.+0.j],\n",
      "       [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j, -0.+0.j,  0.+0.j, -1.+0.j]]), array([[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n",
      "       [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]]), array([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n",
      "       [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]]), array([[0.+0.j, 0.-0.j, 0.+0.j, 0.-1.j],\n",
      "       [0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j],\n",
      "       [0.+0.j, 0.-1.j, 0.+0.j, 0.-0.j],\n",
      "       [0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j]]), array([[ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j, -0.+0.j,  0.+0.j, -1.+0.j],\n",
      "       [ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j, -1.+0.j,  0.+0.j, -0.+0.j]]), array([[0.+0.j, 0.+0.j, 0.-1.j, 0.-0.j],\n",
      "       [0.+0.j, 0.+0.j, 0.-0.j, 0.-1.j],\n",
      "       [0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j]]), array([[0.+0.j, 0.+0.j, 0.-0.j, 0.-1.j],\n",
      "       [0.+0.j, 0.+0.j, 0.-1.j, 0.-0.j],\n",
      "       [0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j],\n",
      "       [0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j]]), array([[ 0.+0.j,  0.-0.j,  0.-0.j, -1.+0.j],\n",
      "       [ 0.+0.j,  0.+0.j,  1.-0.j,  0.-0.j],\n",
      "       [ 0.+0.j,  1.-0.j,  0.+0.j,  0.-0.j],\n",
      "       [-1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j]]), array([[ 0.+0.j,  0.+0.j,  0.-1.j,  0.-0.j],\n",
      "       [ 0.+0.j, -0.+0.j,  0.-0.j,  0.+1.j],\n",
      "       [ 0.+1.j,  0.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j, -0.-1.j,  0.+0.j, -0.+0.j]]), array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j,  0.+0.j, -1.+0.j, -0.+0.j],\n",
      "       [ 0.+0.j,  0.+0.j, -0.+0.j, -1.+0.j]]), array([[ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j,  0.+0.j, -0.+0.j, -1.+0.j],\n",
      "       [ 0.+0.j,  0.+0.j, -1.+0.j, -0.+0.j]]), array([[ 0.+0.j,  0.-1.j,  0.+0.j,  0.-0.j],\n",
      "       [ 0.+1.j,  0.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j,  0.-0.j, -0.+0.j,  0.+1.j],\n",
      "       [ 0.+0.j,  0.+0.j, -0.-1.j, -0.+0.j]]), array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],\n",
      "       [ 0.+0.j, -1.+0.j,  0.+0.j, -0.+0.j],\n",
      "       [ 0.+0.j,  0.+0.j, -1.+0.j, -0.+0.j],\n",
      "       [ 0.+0.j, -0.+0.j, -0.+0.j,  1.-0.j]]))\n"
     ]
    }
   ],
   "source": [
    "from quara.objects.matrix_basis import get_pauli_basis\n",
    "\n",
    "# Prepare\n",
    "basis_0 = get_pauli_basis()\n",
    "basis_1 = get_pauli_basis()\n",
    "\n",
    "# Tensor product\n",
    "result = tensor_product(basis_0, basis_1)\n",
    "print(result)  # MatrixBasis"
   ]
  }
 ],
 "metadata": {
  "hide_input": false,
  "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.8.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
