diff --git a/cv_tutorial_yam.ipynb b/cv_tutorial_yam.ipynb new file mode 100644 index 0000000..17d3471 --- /dev/null +++ b/cv_tutorial_yam.ipynb @@ -0,0 +1,337 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ffce6bfa", + "metadata": {}, + "source": [ + "# Introducing the Wigner Function" + ] + }, + { + "cell_type": "markdown", + "id": "589363aa", + "metadata": {}, + "source": [ + "This notebook is an introduction to the Wigner function, a little about phase space, and the distributions obtained by using the Wigner functions on different types of states." + ] + }, + { + "cell_type": "markdown", + "id": "8c3141a2", + "metadata": {}, + "source": [ + "## Phase Space and Distributions" + ] + }, + { + "cell_type": "markdown", + "id": "3afb474e", + "metadata": {}, + "source": [ + "The phase space is the set of all possible states for some system, both in classical and quantum mechanics. However, due to the Heisenberg principle, we are not able to fully know the values of the position and momentum operators at the same time for some quantum system, thus not be able to create a probability distribution for that given system.\n", + "\n", + "For this problem we can then employ phase-space distributions, which by themselves are quasi-probability distributions. Examples of such distributions include the Wigner function, Q-function, and the Characteristic function, but for this notebook we will only focus on the Wigner function." + ] + }, + { + "cell_type": "markdown", + "id": "cd268017", + "metadata": {}, + "source": [ + "## Wigner Function" + ] + }, + { + "cell_type": "markdown", + "id": "65df1472", + "metadata": {}, + "source": [ + "With the Wigner Function, we can (sort of) represent the probability distributions of several different types of states, including Fock states and the Gaussian states (coherent, squeezed, etc.)\n", + "\n", + "The Wigner function is defined as follows\n", + "\n", + "$ W_p(x,p)=\\frac{1}{2π} * \\int_{-∞}^{∞} \\langle x+\\frac{1}{2}q|\\hat{ρ}| x-\\frac{1}{2}q \\rangle e^{ipq} dq $\n", + "\n", + "Where the bra and ket in the expression are the eigenstates of $\\hat{x}$" + ] + }, + { + "cell_type": "markdown", + "id": "db419069", + "metadata": {}, + "source": [ + "## Wigner Function on Different States" + ] + }, + { + "cell_type": "markdown", + "id": "a1b58f72", + "metadata": {}, + "source": [ + "When it comes to the different types of states we can represent using Wigner functions, there do exist renditions of the function for those specific states we can use instead of the one presented above.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2ccc91da", + "metadata": {}, + "outputs": [], + "source": [ + "# Some packages we will use for plotting\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import ipywidgets as widgets\n", + "import numpy as np\n", + "import math\n", + "from scipy.special import laguerre\n" + ] + }, + { + "cell_type": "markdown", + "id": "0b6b6015", + "metadata": {}, + "source": [ + "### Fock States " + ] + }, + { + "cell_type": "markdown", + "id": "ec72f8b2", + "metadata": {}, + "source": [ + "For the Fock states, to represent an n photon Fock state with the Wigner function, we can use the following expression:\n", + "\n", + "$ W_{|n \\rangle} = \\frac{1}{π} e^{-x^2-p^2}(-1)^n L_n (2x^2+2p^2)$\n", + "\n", + "The below code shows a plot of the Wigner function in a 3D space. We can see that as we increase n (the number of photons), we see an oscillating pattern of peaks and valleys being added to our figure." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42a01f3d", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "279ca3d9f66c415bbd09131feb687cbc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(IntSlider(value=0, description='photons', max=10), Output()), _dom_classes=('widget-inte…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wigner_fock(x,p,n):\n", + " return 1/np.pi * (np.exp(-x**2 - p**2)*(-1)**(n)*laguerre(n)(2*x**(2)+2*p**(2)))\n", + "\n", + "def plot_wigner_fock(photons=0):\n", + " x = np.linspace(-2, 2, 100)\n", + " p = np.linspace(-2, 2, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " ax.set_xlabel(\"x\")\n", + " ax.set_ylabel(\"p\")\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " ax.plot_surface(x,p,wigner_fock(x,p,photons), cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_fock,photons=(0,10,1),)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "44757d37", + "metadata": {}, + "source": [ + "### Coherent States" + ] + }, + { + "cell_type": "markdown", + "id": "7207530b", + "metadata": {}, + "source": [ + "For plotting coherent states, we use the following expression:\n", + "\n", + "$ W_{|\\alpha \\rangle} = \\frac{1}{π}*e^{-(x-x_{\\alpha})^{2}-(p-p_{\\alpha})^{2}} $\n", + "\n", + "The coherent state we will obtain will be the same as a Fock state in vacuum (0 photons), but displaced at position $(x_\\alpha,p_\\alpha)=(\\sqrt{2}Re(\\alpha), \\sqrt{2}Im(\\alpha))$. The figure below has a drop-down, showing the distribution when $\\alpha$ is equal to 0, $\\sqrt{2}$, and $2e^{i\\pi/4}$. These positions correspond to a $(x_\\alpha, p_\\alpha)$ of (0,0), (2,0), and (2,2)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "790e99cf", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "dad2954f543f4ef0b892bd6a2fadcb62", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(Dropdown(description='alpha', options=(0, np.float64(1.4142135623730951), np.complex128(…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wigner_coherent(x,p,alpha):\n", + " x_alpha, p_alpha = np.sqrt(2)*np.real(alpha),np.sqrt(2)*np.imag(alpha)\n", + " return 1/np.pi * (np.exp(-(x-x_alpha)**(2)-(p-p_alpha)**2))\n", + "\n", + "def plot_wigner_coherent(alpha=0):\n", + " x = np.linspace(-4, 4, 100)\n", + " p = np.linspace(-4, 4, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " #Z = np.array([wigner_fock(x,p,1)])\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " #z = wigner_fock(x,p,1)\n", + " ax.plot_surface(x,p,wigner_coherent(x,p,alpha), cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_coherent,alpha=[0,np.sqrt(2),2*np.exp(1j*np.pi/4)])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "3bdb56e7", + "metadata": {}, + "source": [ + "### Squeezed States" + ] + }, + { + "cell_type": "markdown", + "id": "c752117e", + "metadata": {}, + "source": [ + "Squeezed states are another type of Gaussian state which can have its distribution plotted with the use of the wigner function. For single-mode squeezing, the wigner function is defined as:\n", + "\n", + "$W_{|ξ \\rangle}(x,p)=\\frac{1}{\\pi}e^{-e^{2r}[x*cos(\\frac{\\theta}{2}) + p * sin(\\frac{\\theta}{2}] - e^{-2r}[p*cos(\\frac{\\theta}{2}) - x * sin(\\frac{\\theta}{2}])} $\n", + "\n", + "In this figure, we can see as we increase/decrease the value of theta, the distribution of the squeezed state will rotate.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2dd6de2f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "bfc6b6956249489293fbfbffadd91139", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='theta', max=3.141592653589793, min=-3.14159265358979…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Single mode squeezing\n", + "\n", + "def wigner_single_squeeze(x,p,theta, r):\n", + " return 1/np.pi * np.exp(-np.exp(2*r) * (x * np.cos(theta/2) + p * np.sin(theta/2))**2 - np.exp(-2*r) * (p * np.cos(theta/2) - x * np.sin(theta/2))**2)\n", + "\n", + "def plot_wigner_single_squeeze(theta=0):\n", + " x = np.linspace(-4, 4, 100)\n", + " p = np.linspace(-4, 4, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " #Z = np.array([wigner_fock(x,p,1)])\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " z = wigner_single_squeeze(x,p,theta,0.7)\n", + " ax.plot_surface(x, p, z, cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_single_squeeze,theta=(-np.pi,np.pi,0.1))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "sciqis (3.14.6.final.0)", + "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.14.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/cv_tutorial_yam_better.ipynb b/cv_tutorial_yam_better.ipynb new file mode 100644 index 0000000..1274749 --- /dev/null +++ b/cv_tutorial_yam_better.ipynb @@ -0,0 +1,333 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ffce6bfa", + "metadata": {}, + "source": [ + "# Introducing the Wigner Function" + ] + }, + { + "cell_type": "markdown", + "id": "589363aa", + "metadata": {}, + "source": [ + "This notebook is an introduction to the Wigner function, a little about phase space, and the distributions obtained by using the Wigner functions on different types of states." + ] + }, + { + "cell_type": "markdown", + "id": "8c3141a2", + "metadata": {}, + "source": [ + "## Phase Space and Distributions" + ] + }, + { + "cell_type": "markdown", + "id": "3afb474e", + "metadata": {}, + "source": [ + "The phase space is the set of all possible states for some system. They can be useful in showcasing the behavior of physical systems in both in classical and quantum mechanics.\n", + "In quantum mechanics we are not able to fully know the values of the position and momentum operators of harmonic oscillators at the same time, thus not able to create a probability distribution for quantum systems.\n", + "\n", + "For this problem we can then employ phase-space distributions. They are quasi-probability distributions which can be used to calculate important information from a quantum state ρ such as expectation values and the distribution of possible outcomes. Examples of such distributions include the Wigner function, Q-function, and the Characteristic function, but for this notebook we will only focus on the Wigner function." + ] + }, + { + "cell_type": "markdown", + "id": "cd268017", + "metadata": {}, + "source": [ + "## Wigner Function" + ] + }, + { + "cell_type": "markdown", + "id": "65df1472", + "metadata": {}, + "source": [ + "The Wigner function is a common quasi-probability distribution. It can be used to represent the distributions of different types of states such as Fock states, coherent states, and squeezed states. The Wigner function is defined as follows:\n", + "\n", + "$ W_p(x,p)=\\frac{1}{2π} * \\int_{-∞}^{∞} \\langle x+\\frac{1}{2}q|\\hat{ρ}| x-\\frac{1}{2}q \\rangle e^{ipq} dq $\n", + "\n", + "Where the bra and ket in the expression are the eigenstates of $\\hat{x}$.\n", + "Under the different subsections, we will see different variations of the Wigner function for Fock, coherent, and squeezed states.\n" + ] + }, + { + "cell_type": "markdown", + "id": "db419069", + "metadata": {}, + "source": [ + "## Wigner Function on Different States" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2ccc91da", + "metadata": {}, + "outputs": [], + "source": [ + "# Some packages we will use for plotting\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import ipywidgets as widgets\n", + "import numpy as np\n", + "import math\n", + "from scipy.special import laguerre\n" + ] + }, + { + "cell_type": "markdown", + "id": "0b6b6015", + "metadata": {}, + "source": [ + "### Fock States " + ] + }, + { + "cell_type": "markdown", + "id": "ec72f8b2", + "metadata": {}, + "source": [ + "For the Fock states, to represent an n photon Fock state with the Wigner function, we can use the following expression:\n", + "\n", + "$ W_{|n \\rangle} = \\frac{1}{π} e^{-x^2-p^2}(-1)^n L_n (2x^2+2p^2)$\n", + "\n", + "Where $L_n(...)$ is the n'th Laguerre polynomial.\n", + "\n", + "The code below shows a plot of the Wigner function in a 3D space. We can see that as we increase n (the number of photons), we see an oscillating pattern of peaks and valleys being added to our figure." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "42a01f3d", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9b812dcc10854d2bbb07dc054df29b5e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(IntSlider(value=0, description='photons', max=10), Output()), _dom_classes=('widget-inte…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wigner_fock(x,p,n):\n", + " return 1/np.pi * (np.exp(-x**2 - p**2)*(-1)**(n)*laguerre(n)(2*x**(2)+2*p**(2)))\n", + "\n", + "def plot_wigner_fock(photons=0):\n", + " x = np.linspace(-2, 2, 100)\n", + " p = np.linspace(-2, 2, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " ax.set_xlabel(\"x\")\n", + " ax.set_ylabel(\"p\")\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " ax.plot_surface(x,p,wigner_fock(x,p,photons), cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_fock,photons=(0,10,1),)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "44757d37", + "metadata": {}, + "source": [ + "### Coherent States" + ] + }, + { + "cell_type": "markdown", + "id": "7207530b", + "metadata": {}, + "source": [ + "For plotting coherent states, we use the following expression:\n", + "\n", + "$ W_{|\\alpha \\rangle} = \\frac{1}{π}*e^{-(x-x_{\\alpha})^{2}-(p-p_{\\alpha})^{2}} $\n", + "\n", + "The coherent state we will obtain will be the same as a Fock state in vacuum (0 photons), but displaced at position $(x_\\alpha,p_\\alpha)=(\\sqrt{2}Re(\\alpha), \\sqrt{2}Im(\\alpha))$. The figure below has a drop-down, showing the distribution when $\\alpha$ is equal to 0, $\\sqrt{2}$, and $2e^{i\\pi/4}$. These positions correspond to a $(x_\\alpha, p_\\alpha)$ of (0,0), (2,0), and (2,2)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "790e99cf", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "927ff6212c8349fc9d65ac67fbbbf82b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(Dropdown(description='alpha', options=(0, np.float64(1.4142135623730951), np.complex128(…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wigner_coherent(x,p,alpha):\n", + " x_alpha, p_alpha = np.sqrt(2)*np.real(alpha),np.sqrt(2)*np.imag(alpha)\n", + " return 1/np.pi * (np.exp(-(x-x_alpha)**(2)-(p-p_alpha)**2))\n", + "\n", + "def plot_wigner_coherent(alpha=0):\n", + " x = np.linspace(-4, 4, 100)\n", + " p = np.linspace(-4, 4, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " #Z = np.array([wigner_fock(x,p,1)])\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " #z = wigner_fock(x,p,1)\n", + " ax.plot_surface(x,p,wigner_coherent(x,p,alpha), cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_coherent,alpha=[0,np.sqrt(2),2*np.exp(1j*np.pi/4)])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "3bdb56e7", + "metadata": {}, + "source": [ + "### Squeezed States" + ] + }, + { + "cell_type": "markdown", + "id": "c752117e", + "metadata": {}, + "source": [ + "Squeezed states are another type of Gaussian state which can have its distribution plotted with the use of the Wigner function. Squeezing refers to essentially reducing the uncertainty of one of the quadratures and increasing the other, we \"squeeze\" one and \"anti-squeeze\" the other.\n", + "\n", + "When squeezing the $|vac\\rangle$ state, we have what is called single-mode squeezing. For single-mode squeezing, the Wigner function is defined as:\n", + "\n", + "$W_{|ξ \\rangle}(x,p)=\\frac{1}{\\pi}e^{-e^{2r}[x*cos(\\frac{\\theta}{2}) + p * sin(\\frac{\\theta}{2}] - e^{-2r}[p*cos(\\frac{\\theta}{2}) - x * sin(\\frac{\\theta}{2}])} $\n", + "\n", + "In the figure below, you are able to play around with the angle (theta). As you increase/descrease the slider, we can see that the distribution rotates, thus changing the uncertainty of x and p." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2dd6de2f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "17a7afba94e341d6be08affa7ef3f0ce", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='theta', max=3.141592653589793, min=-3.14159265358979…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Single mode squeezing\n", + "\n", + "def wigner_single_squeeze(x,p,theta, r):\n", + " return 1/np.pi * np.exp(-np.exp(2*r) * (x * np.cos(theta/2) + p * np.sin(theta/2))**2 - np.exp(-2*r) * (p * np.cos(theta/2) - x * np.sin(theta/2))**2)\n", + "\n", + "def plot_wigner_single_squeeze(theta=0):\n", + " x = np.linspace(-4, 4, 100)\n", + " p = np.linspace(-4, 4, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " #Z = np.array([wigner_fock(x,p,1)])\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " z = wigner_single_squeeze(x,p,theta,0.7)\n", + " ax.plot_surface(x, p, z, cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_single_squeeze,theta=(-np.pi,np.pi,0.1))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "sciqis (3.14.6.final.0)", + "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.14.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/exercises/cv_submissions/cv_tutorial_yam_better.ipynb b/exercises/cv_submissions/cv_tutorial_yam_better.ipynb new file mode 100644 index 0000000..1274749 --- /dev/null +++ b/exercises/cv_submissions/cv_tutorial_yam_better.ipynb @@ -0,0 +1,333 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ffce6bfa", + "metadata": {}, + "source": [ + "# Introducing the Wigner Function" + ] + }, + { + "cell_type": "markdown", + "id": "589363aa", + "metadata": {}, + "source": [ + "This notebook is an introduction to the Wigner function, a little about phase space, and the distributions obtained by using the Wigner functions on different types of states." + ] + }, + { + "cell_type": "markdown", + "id": "8c3141a2", + "metadata": {}, + "source": [ + "## Phase Space and Distributions" + ] + }, + { + "cell_type": "markdown", + "id": "3afb474e", + "metadata": {}, + "source": [ + "The phase space is the set of all possible states for some system. They can be useful in showcasing the behavior of physical systems in both in classical and quantum mechanics.\n", + "In quantum mechanics we are not able to fully know the values of the position and momentum operators of harmonic oscillators at the same time, thus not able to create a probability distribution for quantum systems.\n", + "\n", + "For this problem we can then employ phase-space distributions. They are quasi-probability distributions which can be used to calculate important information from a quantum state ρ such as expectation values and the distribution of possible outcomes. Examples of such distributions include the Wigner function, Q-function, and the Characteristic function, but for this notebook we will only focus on the Wigner function." + ] + }, + { + "cell_type": "markdown", + "id": "cd268017", + "metadata": {}, + "source": [ + "## Wigner Function" + ] + }, + { + "cell_type": "markdown", + "id": "65df1472", + "metadata": {}, + "source": [ + "The Wigner function is a common quasi-probability distribution. It can be used to represent the distributions of different types of states such as Fock states, coherent states, and squeezed states. The Wigner function is defined as follows:\n", + "\n", + "$ W_p(x,p)=\\frac{1}{2π} * \\int_{-∞}^{∞} \\langle x+\\frac{1}{2}q|\\hat{ρ}| x-\\frac{1}{2}q \\rangle e^{ipq} dq $\n", + "\n", + "Where the bra and ket in the expression are the eigenstates of $\\hat{x}$.\n", + "Under the different subsections, we will see different variations of the Wigner function for Fock, coherent, and squeezed states.\n" + ] + }, + { + "cell_type": "markdown", + "id": "db419069", + "metadata": {}, + "source": [ + "## Wigner Function on Different States" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2ccc91da", + "metadata": {}, + "outputs": [], + "source": [ + "# Some packages we will use for plotting\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import ipywidgets as widgets\n", + "import numpy as np\n", + "import math\n", + "from scipy.special import laguerre\n" + ] + }, + { + "cell_type": "markdown", + "id": "0b6b6015", + "metadata": {}, + "source": [ + "### Fock States " + ] + }, + { + "cell_type": "markdown", + "id": "ec72f8b2", + "metadata": {}, + "source": [ + "For the Fock states, to represent an n photon Fock state with the Wigner function, we can use the following expression:\n", + "\n", + "$ W_{|n \\rangle} = \\frac{1}{π} e^{-x^2-p^2}(-1)^n L_n (2x^2+2p^2)$\n", + "\n", + "Where $L_n(...)$ is the n'th Laguerre polynomial.\n", + "\n", + "The code below shows a plot of the Wigner function in a 3D space. We can see that as we increase n (the number of photons), we see an oscillating pattern of peaks and valleys being added to our figure." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "42a01f3d", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9b812dcc10854d2bbb07dc054df29b5e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(IntSlider(value=0, description='photons', max=10), Output()), _dom_classes=('widget-inte…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wigner_fock(x,p,n):\n", + " return 1/np.pi * (np.exp(-x**2 - p**2)*(-1)**(n)*laguerre(n)(2*x**(2)+2*p**(2)))\n", + "\n", + "def plot_wigner_fock(photons=0):\n", + " x = np.linspace(-2, 2, 100)\n", + " p = np.linspace(-2, 2, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " ax.set_xlabel(\"x\")\n", + " ax.set_ylabel(\"p\")\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " ax.plot_surface(x,p,wigner_fock(x,p,photons), cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_fock,photons=(0,10,1),)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "44757d37", + "metadata": {}, + "source": [ + "### Coherent States" + ] + }, + { + "cell_type": "markdown", + "id": "7207530b", + "metadata": {}, + "source": [ + "For plotting coherent states, we use the following expression:\n", + "\n", + "$ W_{|\\alpha \\rangle} = \\frac{1}{π}*e^{-(x-x_{\\alpha})^{2}-(p-p_{\\alpha})^{2}} $\n", + "\n", + "The coherent state we will obtain will be the same as a Fock state in vacuum (0 photons), but displaced at position $(x_\\alpha,p_\\alpha)=(\\sqrt{2}Re(\\alpha), \\sqrt{2}Im(\\alpha))$. The figure below has a drop-down, showing the distribution when $\\alpha$ is equal to 0, $\\sqrt{2}$, and $2e^{i\\pi/4}$. These positions correspond to a $(x_\\alpha, p_\\alpha)$ of (0,0), (2,0), and (2,2)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "790e99cf", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "927ff6212c8349fc9d65ac67fbbbf82b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(Dropdown(description='alpha', options=(0, np.float64(1.4142135623730951), np.complex128(…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wigner_coherent(x,p,alpha):\n", + " x_alpha, p_alpha = np.sqrt(2)*np.real(alpha),np.sqrt(2)*np.imag(alpha)\n", + " return 1/np.pi * (np.exp(-(x-x_alpha)**(2)-(p-p_alpha)**2))\n", + "\n", + "def plot_wigner_coherent(alpha=0):\n", + " x = np.linspace(-4, 4, 100)\n", + " p = np.linspace(-4, 4, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " #Z = np.array([wigner_fock(x,p,1)])\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " #z = wigner_fock(x,p,1)\n", + " ax.plot_surface(x,p,wigner_coherent(x,p,alpha), cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_coherent,alpha=[0,np.sqrt(2),2*np.exp(1j*np.pi/4)])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "3bdb56e7", + "metadata": {}, + "source": [ + "### Squeezed States" + ] + }, + { + "cell_type": "markdown", + "id": "c752117e", + "metadata": {}, + "source": [ + "Squeezed states are another type of Gaussian state which can have its distribution plotted with the use of the Wigner function. Squeezing refers to essentially reducing the uncertainty of one of the quadratures and increasing the other, we \"squeeze\" one and \"anti-squeeze\" the other.\n", + "\n", + "When squeezing the $|vac\\rangle$ state, we have what is called single-mode squeezing. For single-mode squeezing, the Wigner function is defined as:\n", + "\n", + "$W_{|ξ \\rangle}(x,p)=\\frac{1}{\\pi}e^{-e^{2r}[x*cos(\\frac{\\theta}{2}) + p * sin(\\frac{\\theta}{2}] - e^{-2r}[p*cos(\\frac{\\theta}{2}) - x * sin(\\frac{\\theta}{2}])} $\n", + "\n", + "In the figure below, you are able to play around with the angle (theta). As you increase/descrease the slider, we can see that the distribution rotates, thus changing the uncertainty of x and p." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2dd6de2f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "17a7afba94e341d6be08affa7ef3f0ce", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='theta', max=3.141592653589793, min=-3.14159265358979…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Single mode squeezing\n", + "\n", + "def wigner_single_squeeze(x,p,theta, r):\n", + " return 1/np.pi * np.exp(-np.exp(2*r) * (x * np.cos(theta/2) + p * np.sin(theta/2))**2 - np.exp(-2*r) * (p * np.cos(theta/2) - x * np.sin(theta/2))**2)\n", + "\n", + "def plot_wigner_single_squeeze(theta=0):\n", + " x = np.linspace(-4, 4, 100)\n", + " p = np.linspace(-4, 4, 100)\n", + " #wigner_function = wigner_fock(x,p,2)\n", + "\n", + " fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n", + " x, p = np.meshgrid(x,p)\n", + " #Z = np.array([wigner_fock(x,p,1)])\n", + " ax.set_zlim(-0.3,0.3)\n", + "\n", + " z = wigner_single_squeeze(x,p,theta,0.7)\n", + " ax.plot_surface(x, p, z, cmap=\"managua\")\n", + "\n", + " plt.show\n", + "\n", + "widgets.interact(plot_wigner_single_squeeze,theta=(-np.pi,np.pi,0.1))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "sciqis (3.14.6.final.0)", + "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.14.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}