{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Povm and povm_typical"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "np.set_printoptions(linewidth=200)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Povm\n",
    "Quantum measurement has two mathematical treatments. One is positive operator-valued measure (POVM), which can describe the effect of quantum measurement on the probability distribution of its measurement outcome only. The other is measurement apparatus, which can describe both of the effect on the probability distribution and states after the measurement. Current version of quara prepare a class for POVM only. A class for measurement apparatus will be added in the near future.\n",
    "\n",
    "Povm can be represented by a list of POVM element as `vecs`.  \n",
    "Each emelemts is a linear combination of basis and represents the coefficients of this linear combination in the form of a numpy array.\n",
    "\n",
    "Example:  \n",
    "Povm elements $\\Pi_0 = \\begin{bmatrix} 1 & 0 \\\\ 0 & 0 \\\\ \\end{bmatrix}$, $\\Pi_1 = \\begin{bmatrix} 0 & 0 \\\\ 0 & 1 \\\\ \\end{bmatrix}$.  \n",
    "Povm $\\Pi = \\{ \\Pi_x \\}_{x=0,1}$. index $x$ is called outcomes.  \n",
    "We can write $\\Pi_0= 1/\\sqrt{2} \\cdot I/\\sqrt{2} + 0 \\cdot X/\\sqrt{2} + 0 \\cdot Y/\\sqrt{2} + 1/\\sqrt{2} \\cdot  Z/\\sqrt{2}$ and  $\\Pi_1= 1/\\sqrt{2} \\cdot I/\\sqrt{2} + 0 \\cdot X/\\sqrt{2} + 0 \\cdot Y/\\sqrt{2} - 1/\\sqrt{2} \\cdot  Z/\\sqrt{2}$.  \n",
    "In this case `vecs` of $\\Pi$ is a list of $[ 1/\\sqrt{2}, 0, 0, 1/\\sqrt{2} ]$ and $[ 1/\\sqrt{2}, 0, 0, -1/\\sqrt{2} ]$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The methods for generating a State includes the following:\n",
    "\n",
    "- Generate from `povm_typical` module\n",
    "- Generate Povm object directly\n",
    "\n",
    "Generate from `povm_typical` module by specifying CompositeSystem and povm name (ex. \"z\")."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "Povm\n",
      "\n",
      "Dim:\n",
      "2\n",
      "\n",
      "Number of outcomes:\n",
      "2\n",
      "\n",
      "Vecs:\n",
      "[[ 0.70710678  0.          0.          0.70710678]\n",
      " [ 0.70710678  0.          0.         -0.70710678]]\n"
     ]
    }
   ],
   "source": [
    "from quara.objects.composite_system_typical import generate_composite_system\n",
    "from quara.objects.povm_typical import generate_povm_from_name\n",
    "\n",
    "c_sys = generate_composite_system(\"qubit\", 1)\n",
    "povm = generate_povm_from_name(\"z\", c_sys)\n",
    "print(povm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Generate Povm object directly using CompositeSystem and a list of numpy array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "Povm\n",
      "\n",
      "Dim:\n",
      "2\n",
      "\n",
      "Number of outcomes:\n",
      "2\n",
      "\n",
      "Vecs:\n",
      "[[ 0.70710678  0.          0.          0.70710678]\n",
      " [ 0.70710678  0.          0.         -0.70710678]]\n"
     ]
    }
   ],
   "source": [
    "from quara.objects.composite_system import CompositeSystem\n",
    "from quara.objects.elemental_system import ElementalSystem\n",
    "from quara.objects.matrix_basis import get_normalized_pauli_basis\n",
    "from quara.objects.povm import Povm\n",
    "\n",
    "basis = get_normalized_pauli_basis(1)\n",
    "e_sys = ElementalSystem(0, basis)\n",
    "c_sys = CompositeSystem([e_sys])\n",
    "vec1 = np.array([1, 0, 0, 1]) / np.sqrt(2)\n",
    "vec2 = np.array([1, 0, 0, -1]) / np.sqrt(2)\n",
    "vecs = [vec1, vec2]\n",
    "povm = Povm(c_sys, vecs)\n",
    "print(povm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### specific properties\n",
    "The property `vecs` of Povm is a list of a numpy array specified by the constructor argument `vecs`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vecs: \n",
      "(array([0.70710678, 0.        , 0.        , 0.70710678]), array([ 0.70710678,  0.        ,  0.        , -0.70710678]))\n"
     ]
    }
   ],
   "source": [
    "povm = Povm(c_sys, vecs)\n",
    "print(f\"vecs: \\n{povm.vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The property `dim` of Povm is a square root of the size of element of `vecs`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dim: 2\n",
      "square root of the size of element of vecs: 2\n"
     ]
    }
   ],
   "source": [
    "print(f\"dim: {povm.dim}\")\n",
    "print(f\"square root of the size of element of vecs: {int(np.sqrt(len(vecs[0])))}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The property `num_outcomes` of Povm is the number of POVM elements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "num_outcomes: 2\n",
      "number of POVM elements: 2\n"
     ]
    }
   ],
   "source": [
    "print(f\"num_outcomes: {povm.num_outcomes}\")\n",
    "print(f\"number of POVM elements: {len(vecs)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### functions to check constraints\n",
    "The `is_eq_constraint_satisfied()` function returns True, if and only if $\\sum_x \\Pi_x = I$, where $\\Pi_x$ are Povm elements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "is_eq_constraint_satisfied(): True\n",
      "sum of matrices: \n",
      "[[1.+0.j 0.+0.j]\n",
      " [0.+0.j 1.+0.j]]\n"
     ]
    }
   ],
   "source": [
    "from operator import add\n",
    "from functools import reduce\n",
    "\n",
    "print(f\"is_eq_constraint_satisfied(): {povm.is_eq_constraint_satisfied()}\")\n",
    "print(f\"sum of matrices: \\n{reduce(add, povm.matrices())}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `is_ineq_constraint_satisfied()` function returns True, if and only if all $\\Pi_x$ are positive semidifinite matrices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "is_eq_constraint_satisfied(): True\n",
      "matrix(0): \n",
      "[[1.+0.j 0.+0.j]\n",
      " [0.+0.j 0.+0.j]]\n",
      "matrix(1): \n",
      "[[0.+0.j 0.+0.j]\n",
      " [0.+0.j 1.+0.j]]\n"
     ]
    }
   ],
   "source": [
    "print(f\"is_eq_constraint_satisfied(): {povm.is_eq_constraint_satisfied()}\")\n",
    "print(f\"matrix(0): \\n{povm.matrix(0)}\")\n",
    "print(f\"matrix(1): \\n{povm.matrix(1)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### projection functions\n",
    "`calc_proj_eq_constraint()` function calculates the projection of Povm on equal constraint.  \n",
    "Let `num_outcomes` = $m$, `dim` = $d$, and $\\tilde{I} = I/\\sqrt{d}$. Then $\\sum_{x=0}^{m-1} \\Pi_x = I = \\sqrt{d} \\cdot \\tilde{I}$.  \n",
    "Therefore $\\sum_{x=0}^{m-1} |\\Pi_x\\rangle\\rangle = |\\tilde{I}\\rangle\\rangle = [ \\sqrt{d}, 0, \\dots, 0 ]^T$. Thus, the last element of Povm $\\Pi_{m-1}$ can be determined, depending on other elements, as follows:  \n",
    "\n",
    "- $|\\Pi_x\\rangle\\rangle = [a_{x,0}, \\dots, a_{x,d^2-1}]^T$\n",
    "- $\\bar{a_\\alpha} := \\frac{1}{m} \\sum_{x=0}^{m-1} (|\\Pi_x\\rangle\\rangle)_\\alpha$, where $\\alpha = 0, \\dots, d^2-1$.\n",
    "- $c_\\alpha := \\begin{cases} \\sqrt{d}/m & (\\alpha = 0) \\\\ 0 & (\\alpha = 1, \\dots, d^2-1) \\end{cases}$\n",
    "- $a_{x,\\alpha}^\\prime := a_{x,\\alpha} - \\bar{a_\\alpha} + c_\\alpha$\n",
    "- The projection of Povm  $|\\tilde{\\Pi}_x\\rangle\\rangle$ is $[ a_{x,0}^\\prime, \\dots, a_{x,d^2-1}^\\prime ]^T$.\n",
    "\n",
    "This function replaces the last element of `vecs` with $1/\\sqrt{d}$, where $d$ is `dim`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "vec1 = np.array([1.0, 2.0, 3.0, 4.0])\n",
    "vec2 = np.array([5.0, 6.0, 7.0, 8.0])\n",
    "vecs = [vec1, vec2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vecs: \n",
      "(array([-1.29289322, -2.        , -2.        , -2.        ]), array([2.70710678, 2.        , 2.        , 2.        ]))\n"
     ]
    }
   ],
   "source": [
    "povm = Povm(c_sys, vecs, is_physicality_required=False)\n",
    "proj_povm = povm.calc_proj_eq_constraint()\n",
    "print(f\"vecs: \\n{proj_povm.vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`calc_proj_ineq_constraint()` function calculates the projection of Povm $\\{|\\Pi_x\\rangle\\rangle\\}_x$ on inequal constraint as follows:\n",
    "\n",
    "- For each $x$, calculate the following:\n",
    "  - Executes singular value decomposition on the elements of Povm $\\Pi_x$, $\\Pi_x = U \\Lambda U^{\\dagger}$, where $\\Lambda = \\text{diag}[\\lambda_0, \\dots , \\lambda_{d-1}]$, and $\\lambda_{i} \\in \\mathbb{R}$.\n",
    "  - $\\lambda^{\\prime}_{i} := \\begin{cases} \\lambda_{i} & (\\lambda_{i} \\geq 0) \\\\ 0 & (\\lambda_{i} < 0) \\end{cases}$\n",
    "  - $\\Lambda^{\\prime} = \\text{diag}[\\lambda^{\\prime}_0, \\dots , \\lambda^{\\prime}_{d-1}]$\n",
    "  - $\\Pi_x^{\\prime} = U \\Lambda^{\\prime} U^{\\dagger}$\n",
    "- The projection of Povm is $\\{|\\Pi_x^{\\prime} \\rangle\\rangle\\}_x$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vecs: \n",
      "(array([3.1925824 , 1.18569534, 1.77854301, 2.37139068]), array([8.60327781, 4.22884788, 4.93365586, 5.63846384]))\n"
     ]
    }
   ],
   "source": [
    "povm = Povm(c_sys, vecs, is_physicality_required=False)\n",
    "proj_povm = povm.calc_proj_ineq_constraint()\n",
    "print(f\"vecs: \\n{proj_povm.vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### functions to transform parameters\n",
    "`to_stacked_vector()` function returns a one-dimensional numpy array of all variables. This is equal to a concatenated vector of elements of `vecs`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "to_stacked_vector(): [1. 2. 3. 4. 5. 6. 7. 8.]\n",
      "vecs: \n",
      "(array([1., 2., 3., 4.]), array([5., 6., 7., 8.]))\n"
     ]
    }
   ],
   "source": [
    "print(f\"to_stacked_vector(): {povm.to_stacked_vector()}\")\n",
    "print(f\"vecs: \\n{povm.vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If Povm $\\Pi = \\{ \\Pi_0, \\dots , \\Pi_{m-1} \\}$ and `on_para_eq_constraint` is True, then the last element of Povm $\\Pi_{m-1}$ is equal to $I - \\sum_{x=0}^{m-2} \\Pi_x$. Thus, Povm is characterized by `vecs[0]`,..., `vecs[m-2]`.  \n",
    "Therefore, `to_var()` function returns a vector combining elements of of `vecs[0]`,..., `vecs[m-2]`, where `on_para_eq_constraint` is True."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "vec1 = np.array([1, 0, 0, 1]) / np.sqrt(2)\n",
    "vec2 = np.array([1, 0, 0, -1]) / np.sqrt(2)\n",
    "vecs = [vec1, vec2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "to_var(): [0.70710678 0.         0.         0.70710678]\n"
     ]
    }
   ],
   "source": [
    "# on_para_eq_constraint=True\n",
    "povm = Povm(c_sys, vecs, on_para_eq_constraint=True)\n",
    "print(f\"to_var(): {povm.to_var()}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "to_var(): [ 0.70710678  0.          0.          0.70710678  0.70710678  0.          0.         -0.70710678]\n"
     ]
    }
   ],
   "source": [
    "# on_para_eq_constraint=False\n",
    "povm = Povm(c_sys, vecs, on_para_eq_constraint=False)\n",
    "print(f\"to_var(): {povm.to_var()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### functions to generate special objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "zero: \n",
      "(array([0., 0., 0., 0.]), array([0., 0., 0., 0.]))\n",
      "origin: \n",
      "(array([0.70710678, 0.        , 0.        , 0.        ]), array([0.70710678, 0.        , 0.        , 0.        ]))\n"
     ]
    }
   ],
   "source": [
    "zero_povm = povm.generate_zero_obj()\n",
    "print(f\"zero: \\n{zero_povm.vecs}\")\n",
    "origin_povm = povm.generate_origin_obj()\n",
    "print(f\"origin: \\n{origin_povm.vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### supports arithmetic operations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sum: \n",
      "(array([10., 12., 14., 16.]), array([18., 20., 22., 24.]))\n",
      "subtraction: \n",
      "(array([-8., -8., -8., -8.]), array([-8., -8., -8., -8.]))\n",
      "right multiplication: \n",
      "(array([2., 4., 6., 8.]), array([10., 12., 14., 16.]))\n",
      "left multiplication: \n",
      "(array([2., 4., 6., 8.]), array([10., 12., 14., 16.]))\n",
      "division: \n",
      "(array([0.5, 1. , 1.5, 2. ]), array([2.5, 3. , 3.5, 4. ]))\n"
     ]
    }
   ],
   "source": [
    "vec11 = np.array([1.0, 2.0, 3.0, 4.0])\n",
    "vec12 = np.array([5.0, 6.0, 7.0, 8.0])\n",
    "povm1 = Povm(c_sys, [vec11, vec12], is_physicality_required=False)\n",
    "vec21 = np.array([9.0, 10.0, 11.0, 12.0])\n",
    "vec22 = np.array([13.0, 14.0, 15.0, 16.0])\n",
    "povm2 = Povm(c_sys, [vec21, vec22], is_physicality_required=False)\n",
    "\n",
    "print(f\"sum: \\n{(povm1 + povm2).vecs}\")\n",
    "print(f\"subtraction: \\n{(povm1 - povm2).vecs}\")\n",
    "print(f\"right multiplication: \\n{(2 * povm1).vecs}\")\n",
    "print(f\"left multiplication: \\n{(povm1 * 2).vecs}\")\n",
    "print(f\"division: \\n{(povm1 / 2).vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### calc_gradient functions\n",
    "Calculates gradient of Povm with variable index."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vecs: (array([1., 0., 0., 0.]), array([0., 0., 0., 0.]))\n"
     ]
    }
   ],
   "source": [
    "grad_povm = povm.calc_gradient(0)\n",
    "print(f\"vecs: {grad_povm.vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### convert_basis function\n",
    "Returns `vecs` converted to the specified basis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vecs: [array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]), array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])]\n"
     ]
    }
   ],
   "source": [
    "from quara.objects.matrix_basis import get_comp_basis\n",
    "\n",
    "povm = generate_povm_from_name(\"z\", c_sys)\n",
    "converted_vecs = povm.convert_basis(get_comp_basis())\n",
    "print(f\"vecs: {converted_vecs}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### generate_mprocess function\n",
    "Generates MProcess from this Povm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "MProcess\n",
      "\n",
      "Dim:\n",
      "2\n",
      "\n",
      "HSs:\n",
      "[array([[0.5, 0. , 0. , 0.5],\n",
      "       [0. , 0. , 0. , 0. ],\n",
      "       [0. , 0. , 0. , 0. ],\n",
      "       [0.5, 0. , 0. , 0.5]]), array([[ 0.5,  0. ,  0. , -0.5],\n",
      "       [ 0. ,  0. ,  0. ,  0. ],\n",
      "       [ 0. ,  0. ,  0. ,  0. ],\n",
      "       [-0.5,  0. ,  0. ,  0.5]])]\n",
      "\n",
      "ModeSampling:\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(povm.generate_mprocess())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### some utility functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vec(0): \n",
      "[0.70710678 0.         0.         0.70710678]\n",
      "matrices(): \n",
      "[matrix([[1.+0.j, 0.+0.j],\n",
      "        [0.+0.j, 0.+0.j]]), matrix([[0.+0.j, 0.+0.j],\n",
      "        [0.+0.j, 1.+0.j]])]\n",
      "matrix(0): \n",
      "[[1.+0.j 0.+0.j]\n",
      " [0.+0.j 0.+0.j]]\n",
      "is_hermitian(): \n",
      "True\n",
      "is_positive_semidefinite(): \n",
      "True\n",
      "is_identity_sum(): \n",
      "True\n",
      "calc_eigenvalues(): \n",
      "[[0.9999999999999998, 0.0], [0.9999999999999998, 0.0]]\n"
     ]
    }
   ],
   "source": [
    "print(f\"vec(0): \\n{povm.vec(0)}\")\n",
    "print(f\"matrices(): \\n{povm.matrices()}\")\n",
    "print(f\"matrix(0): \\n{povm.matrix(0)}\")\n",
    "print(f\"is_hermitian(): \\n{povm.is_hermitian()}\")\n",
    "print(f\"is_positive_semidefinite(): \\n{povm.is_positive_semidefinite()}\")\n",
    "print(f\"is_identity_sum(): \\n{povm.is_identity_sum()}\")\n",
    "print(f\"calc_eigenvalues(): \\n{povm.calc_eigenvalues()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## povm_typical\n",
    "`generate_povm_object_from_povm_name_object_name()` function in `povm_typical` module can easily generate objects related to Povm.  \n",
    "The `generate_povm_object_from_povm_name_object_name()` function has the following arguments:\n",
    "\n",
    "- The string that can be specified for `povm_name` can be checked by executing the `get_povm_names()` function. The tensor product of povm_name \"a\", \"b\" is written \"a_b\".\n",
    "- `object_name` can be the following string:\n",
    "  - \"pure_state_vectors\" - list of vector of pure states.\n",
    "  - \"matrices\" - matrices of vector of pure states.\n",
    "  - \"vectors\" - list of vectorized matrices.\n",
    "  - \"povm\" - Povm object.\n",
    "- `c_sys` - CompositeSystem of objects related to Povm. Specify when `object_name` is \"povm\".\n",
    "- `basis` - MatrixBasis of objects related to Povm. Specify when `object_name` is \"vectors\".\n",
    "- `is_physicality_required` - Whether the generated object is physicality required, by default True."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "from quara.objects.povm_typical import (\n",
    "    get_povm_names,\n",
    "    generate_povm_object_from_povm_name_object_name,\n",
    ")\n",
    "\n",
    "#get_povm_names()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### object_name = \"pure_state_vectors\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[array([1.+0.j, 0.+0.j]), array([0.+0.j, 1.+0.j])]\n"
     ]
    }
   ],
   "source": [
    "vecs = generate_povm_object_from_povm_name_object_name(\"z\", \"pure_state_vectors\")\n",
    "print(vecs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### object_name = \"matrices\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[array([[1.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 0.+0.j]]), array([[0.+0.j, 0.+0.j],\n",
      "       [0.+0.j, 1.+0.j]])]\n"
     ]
    }
   ],
   "source": [
    "matrices = generate_povm_object_from_povm_name_object_name(\"z\", \"matrices\")\n",
    "print(matrices)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### object_name = \"vectors\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[array([0.70710678, 0.        , 0.        , 0.70710678]), array([ 0.70710678,  0.        ,  0.        , -0.70710678])]\n"
     ]
    }
   ],
   "source": [
    "basis = get_normalized_pauli_basis(1)\n",
    "vectors = generate_povm_object_from_povm_name_object_name(\"z\", \"vectors\", basis=basis)\n",
    "print(vectors)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### object_name = \"povm\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type:\n",
      "Povm\n",
      "\n",
      "Dim:\n",
      "2\n",
      "\n",
      "Number of outcomes:\n",
      "2\n",
      "\n",
      "Vecs:\n",
      "[[ 0.70710678  0.          0.          0.70710678]\n",
      " [ 0.70710678  0.          0.         -0.70710678]]\n"
     ]
    }
   ],
   "source": [
    "c_sys = generate_composite_system(\"qubit\", 1)\n",
    "povm = generate_povm_object_from_povm_name_object_name(\"z\", \"povm\", c_sys=c_sys)\n",
    "print(povm)"
   ]
  }
 ],
 "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": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
