{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SEEING Tutorial\n",
    "\n",
    "## Working with a Formulary\n",
    "- A Formulary is a way to group expressions and functions which are related somehow and possibly share the same symbols.\n",
    "- You can use the code generation and the numerical algorithms in SEEING without defining any Formulary, it's just a set of functions\n",
    "- The expessions you add can also be in the form: sp.Eq( functionDef, functionExpr)\n",
    "\n",
    "- Import seeing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from seeing import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Create and display a Formulary\n",
    "  - first define sympy expressions (somehwere in seeing there is a \"import sympy as sp\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "oneFunction\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle e^{- a x^{2} - b y^{2}}$"
      ],
      "text/plain": [
       "exp(-a*x**2 - b*y**2)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "anotherFunction\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle e^{\\sin{\\left(b y \\right)}} + \\sin^{2}{\\left(a x \\right)}$"
      ],
      "text/plain": [
       "exp(sin(b*y)) + sin(a*x)**2"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "aNicerFunction\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle f{\\left(x,y \\right)} = \\cos{\\left(x y \\right)}$"
      ],
      "text/plain": [
       "Eq(f(x, y), cos(x*y))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "anIntegral\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle g{\\left(y \\right)} = \\int\\limits_{-\\infty}^{0} \\cos{\\left(x y \\right)}\\, dx$"
      ],
      "text/plain": [
       "Eq(g(y), Integral(cos(x*y), (x, -oo, 0)))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A local formulary symbols:\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}y & a & b & x\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "Matrix([[y, a, b, x]])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def oneFunction():\n",
    "    x, y, a, b = sp.symbols(\"x y a b\")\n",
    "    return sp.exp(-a*x**2-b*y**2)\n",
    "    \n",
    "def anotherFunction():\n",
    "    x, y, a, b = sp.symbols(\"x y a b\")\n",
    "    return sp.sin(a*x)**2 + sp.exp(sp.sin(b*y) )\n",
    "\n",
    "def aNicerFunction():\n",
    "    x, y = sp.symbols(\"x y\")\n",
    "    return sp.Eq( sp.Function('f')(x,y), sp.cos(x*y) )\n",
    "\n",
    "def anIntegral():\n",
    "    x, y = sp.symbols(\"x y\")\n",
    "    return sp.Eq( sp.Function('g')(y), sp.Integral(aNicerFunction().rhs, (x,-sp.oo, 0 )))\n",
    "\n",
    "                 \n",
    "formulas_names = ['oneFunction', 'anotherFunction', 'aNicerFunction', 'anIntegral']\n",
    "formulas = [oneFunction(), anotherFunction(), aNicerFunction(), anIntegral()]\n",
    "\n",
    "localFormulary = Formulary(\"A local formulary\", formulas_names, formulas)\n",
    "localFormulary.displayAll()\n",
    "print(localFormulary.name+ \" symbols:\")\n",
    "localFormulary.displaySymbols()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Save a Formulary to a file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "localFormulary.writeToFile(\"local.frm\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Load a Formulary from file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "oneFunction\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle e^{- a x^{2} - b y^{2}}$"
      ],
      "text/plain": [
       "exp((-a)*x**2 - b*y**2)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "anotherFunction\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle e^{\\sin{\\left(b y \\right)}} + \\sin^{2}{\\left(a x \\right)}$"
      ],
      "text/plain": [
       "exp(sin(b*y)) + sin(a*x)**2"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "aNicerFunction\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle f{\\left(x,y \\right)} = \\cos{\\left(x y \\right)}$"
      ],
      "text/plain": [
       "Eq(f(x, y), cos(x*y))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "anIntegral\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle g{\\left(y \\right)} = \\int\\limits_{-\\infty}^{0} \\cos{\\left(x y \\right)}\\, dx$"
      ],
      "text/plain": [
       "Eq(g(y), Integral(cos(x*y), (x, -oo, 0)))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "localCopy = Formulary.loadFromFile(\"local.frm\")\n",
    "localCopy.displayAll()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Retrieve a formula by name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle e^{- a x^{2} - b y^{2}}$"
      ],
      "text/plain": [
       "exp(-a*x**2 - b*y**2)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(localFormulary['oneFunction'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Substitute Parameters with values using string names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle e^{- 4 x^{2} - 7 y^{2}}$"
      ],
      "text/plain": [
       "exp(-4*x**2 - 7*y**2)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "specializedOneFunc = subsParamsByName(localFormulary['oneFunction'], {'a':4, 'b':7 })\n",
    "display(specializedOneFunc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- obtain a numpy or cupy lambda function\n",
    "    - you decide which are the free variables and which are the parameters ...\n",
    "    - ... and the target backend: use \"cpulib\" for NumPy (CPU) or \"gpulib\" for CuPy (GPU)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NumPy lambdas:\n",
      "\n",
      "def _lambdifygenerated(y):\n",
      "    return (exp(-7*y**2))\n",
      "\n",
      "def _lambdifygenerated(a, b):\n",
      "    return (exp(-2.25*a - 9.86960440108936*b))\n",
      "\n",
      "def _lambdifygenerated(x, y, a):\n",
      "    return (exp(-a*x**2 - y**2))\n",
      "\n",
      "<function _deprecated.<locals>.wrap.<locals>.call at 0x7fe7b6e65ea0>\n",
      "\n",
      "CuPy lambdas\n",
      "\n",
      "def _lambdifygenerated(y):\n",
      "    return (exp(-7*y**2))\n",
      "\n",
      "def _lambdifygenerated(a, b):\n",
      "    return (exp(-2.25*a - 9.86960440108936*b))\n",
      "\n",
      "def _lambdifygenerated(x, y, a):\n",
      "    return (exp(-a*x**2 - y**2))\n",
      "\n",
      "<ufunc 'cupy_exp'>\n"
     ]
    }
   ],
   "source": [
    "import inspect\n",
    "\n",
    "# cpu\n",
    "alambda1c = localFormulary.getRestrictedLambda('oneFunction', {'a':4, 'b':7, 'x':0 }, ['y'], modules=cpulib)\n",
    "alambda2c = localFormulary.getRestrictedLambda('oneFunction', {'x':1.5, 'y':np.pi }, ['a', 'b'], modules=cpulib)\n",
    "alambda3c = localFormulary.getRestrictedLambda('oneFunction', {'b':1}, ['x', 'y', 'a'], modules=cpulib)\n",
    "print('NumPy lambdas:\\n')\n",
    "print(inspect.getsource(alambda1c))\n",
    "print(inspect.getsource(alambda2c))\n",
    "print(inspect.getsource(alambda3c))\n",
    "print(alambda1c.__globals__['exp'])\n",
    "print()\n",
    "# gpu\n",
    "alambda1g = localFormulary.getRestrictedLambda('oneFunction', {'a':4, 'b':7, 'x':0 }, ['y'], modules=gpulib)\n",
    "alambda2g = localFormulary.getRestrictedLambda('oneFunction', {'x':1.5, 'y':np.pi }, ['a', 'b'], modules=gpulib)\n",
    "alambda3g = localFormulary.getRestrictedLambda('oneFunction', {'b':1}, ['x', 'y', 'a'], modules=gpulib)\n",
    "print('CuPy lambdas\\n')\n",
    "print(inspect.getsource(alambda1g))\n",
    "print(inspect.getsource(alambda2g))\n",
    "print(inspect.getsource(alambda3g))\n",
    "print(alambda1g.__globals__['exp'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- there is also a versions of getRestrictedLambda that is not a member of a Formulary, to which you can pass directly a sympy expression:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "def _lambdifygenerated(y):\n",
      "    return (exp(-7*y**2))\n",
      "\n"
     ]
    }
   ],
   "source": [
    "alambda1c = getRestrictedLambda(oneFunction(), {'a':4, 'b':7, 'x':0 }, ['y'], modules=cpulib)\n",
    "print(inspect.getsource(alambda1c))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Thus you can generate a lambda from an expression which you loaded in a Formulary or not, the you can evaluate it and for example plot the result:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7fe7b2263e80>]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 14508 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot( alambda1c( np.asarray(np.linspace(-1, 1, 1000)) ) )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using a Calculator\n",
    "- a Calculator allows you to evaluate a function or an integral, selecting different methods and using one the different avaiable backend (currently, NumPy or CuPy)\n",
    "- You can use it together with a Formulary or by itsself (which means you have to pass a sympy expression to perform the numerical evaluation/integration)\n",
    "- when you create it you choose the backend (either np for NumPy or cp for CuPy), the numerical type used in the computations (typically float32 or float64) and the kind of final reduction you want to apply in case of integration ('none', 'absolute', 'intensity')\n",
    "- evaluation and integretion work for n-dimensional domains (see later examples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- create a CPU and a GPU calculator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "mCalcGPU = Calculator(cp, cp.float64, 'none')\n",
    "mCalcCPU = Calculator(np, np.float64, 'none')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- use them as stanalone or with a Formulary\n",
    "- the overall evaluation domain is implictly defined as the cartesian product of the single variables evaluations domains\n",
    "    - it is specified a list, where each element represent a variable domain\n",
    "        - ( name_of_variable, lower_point, higher_point, number_of_samples, strategy ) (see x_evaluationDomain in the code down here)\n",
    "        - aviable sampling stragies are: 'linear', 'geometric', 'sqrt', 'random', 'provided'\n",
    "            - 'provided' is a special: in this case you have to pass an array containing the samples you want to use in place of lower_point"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 0.606530659712633 e^{- x^{2}}$"
      ],
      "text/plain": [
       "0.606530659712633*exp(-x**2)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 15848 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 15848 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 22108 characters]\n",
      "text/plain": [
       "<Figure size 504x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# common part\n",
    "substitutionsDictionary = {'y':0.5, 'a':1, 'b':2}\n",
    "x_evaluationDomain = ( 'x', -1, 1, 1000, 'linear' )\n",
    "evaluationDomain =  [x_evaluationDomain]\n",
    "\n",
    "# this is basically the same that is done in \"localFormulary.evaluateFormula\"\n",
    "aFunc = subsParamsByName( oneFunction(), substitutionsDictionary )\n",
    "display(aFunc)\n",
    "xplot, yplot = mCalcCPU.functionEval(aFunc, evaluationDomain)\n",
    "plt.plot(yplot)\n",
    "plt.show()\n",
    "\n",
    "# simpler way to do it\n",
    "xplot, yplot = localFormulary.evaluateFormula('oneFunction', substitutionsDictionary, evaluationDomain, mCalcGPU)\n",
    "plt.plot(yplot)\n",
    "plt.show()\n",
    "\n",
    "# even simpler way if you just want the plot, works also for a 2D output (see next examples)\n",
    "localFormulary.plotFormula('oneFunction', substitutionsDictionary, evaluationDomain, mCalcGPU)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Evaluating integrals with a Calculator\n",
    "\n",
    "- Available integration methods are:\n",
    "    0 - 'raw': compute the sum of the function in the points of the integratios domain\n",
    "    1 - 'rect': Rectagles method\n",
    "    2 - 'trap' : Trapezoidal method\n",
    "    3 - 'mc': Monte Carlo Integration\n",
    "- Let's see if 1, 2, 3 all yield a similar result:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Some more complex examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Rayleigh-Sommerfeld\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\operatorname{E_{1}}{\\left(x_{1},y_{1},z_{1} \\right)} = \\int\\limits_{- a}^{a}\\int\\limits_{- a}^{a} - \\frac{i E_{0} z_{1} \\left(i \\lambda \\frac{1}{2 \\pi \\sqrt{z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}}} + 1\\right) e^{\\frac{2 i \\pi \\sqrt{z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}}}{\\lambda}}}{\\lambda \\left(z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}\\right)}\\, dx_{0}\\, dy_{0}$"
      ],
      "text/plain": [
       "Eq(E_1(x_1, y_1, z_1), Integral(-I*E_0*z_1*(I*lambda*(1/(2*pi*sqrt(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2))) + 1)*exp(2*I*pi*sqrt(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2)/lambda)/(lambda*(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2)), (x_0, -a, a), (y_0, -a, a)))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Approximate Rayleigh-Sommerfeld\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\operatorname{E_{1}}{\\left(x_{1},y_{1},z_{1} \\right)} = \\int\\limits_{- a}^{a}\\int\\limits_{- a}^{a} - \\frac{i E_{0} z_{1} e^{\\frac{2 i \\pi \\sqrt{z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}}}{\\lambda}}}{\\lambda \\left(z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}\\right)}\\, dx_{0}\\, dy_{0}$"
      ],
      "text/plain": [
       "Eq(E_1(x_1, y_1, z_1), Integral(-I*E_0*z_1*exp(2*I*pi*sqrt(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2)/lambda)/(lambda*(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2)), (x_0, -a, a), (y_0, -a, a)))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Near Fresnel\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\operatorname{E_{1}}{\\left(x_{1},y_{1},z_{1} \\right)} = \\int\\limits_{- a}^{a}\\int\\limits_{- a}^{a} - \\frac{i E_{0} e^{\\frac{2 i \\pi z_{1}}{\\lambda}} e^{\\frac{i \\pi \\left(\\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}\\right)}{\\lambda z_{1}}}}{\\lambda z_{1}}\\, dx_{0}\\, dy_{0}$"
      ],
      "text/plain": [
       "Eq(E_1(x_1, y_1, z_1), Integral(-I*E_0*exp(2*I*pi*z_1/lambda)*exp(I*pi*((-x_0 + x_1)**2 + (-y_0 + y_1)**2)/(lambda*z_1))/(lambda*z_1), (x_0, -a, a), (y_0, -a, a)))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Far Fresnel\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\operatorname{E_{1}}{\\left(x_{1},y_{1},z_{1} \\right)} = \\int\\limits_{- a}^{a}\\int\\limits_{- a}^{a} - \\frac{i E_{0} e^{\\frac{2 i \\pi z_{1}}{\\lambda}} e^{\\frac{i \\pi \\left(x_{0}^{2} + y_{0}^{2}\\right)}{\\lambda z_{1}}} e^{\\frac{2 i \\pi \\left(x_{0} x_{1} + y_{0} y_{1}\\right)}{\\lambda z_{1}}}}{\\lambda z_{1}}\\, dx_{0}\\, dy_{0}$"
      ],
      "text/plain": [
       "Eq(E_1(x_1, y_1, z_1), Integral(-I*E_0*exp(2*I*pi*z_1/lambda)*exp(I*pi*(x_0**2 + y_0**2)/(lambda*z_1))*exp(2*I*pi*(x_0*x_1 + y_0*y_1)/(lambda*z_1))/(lambda*z_1), (x_0, -a, a), (y_0, -a, a)))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "propMethodsCartesian = Formulary.loadFromFile('Propagation100.frm')\n",
    "approximations = [\"Rayleigh-Sommerfeld\", \"Approximate Rayleigh-Sommerfeld\", \"Near Fresnel\", \"Far Fresnel\"]\n",
    "propMethodsCartesian.display(approximations)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "waveLength = 10e-6\n",
    "apertureRadius =  waveLength*10\n",
    "mCalc = Calculator(cp, cp.float64, 'intensity')\n",
    "xyCircle = propMethodsCartesian.getFormula('xyCircle')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Rayleigh-Sommerfeld Arg\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - \\frac{i E_{0} z_{1} \\left(i \\lambda \\frac{1}{2 \\pi \\sqrt{z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}}} + 1\\right) e^{\\frac{2 i \\pi \\sqrt{z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}}}{\\lambda}}}{\\lambda \\left(z_{1}^{2} + \\left(- x_{0} + x_{1}\\right)^{2} + \\left(- y_{0} + y_{1}\\right)^{2}\\right)}$"
      ],
      "text/plain": [
       "-I*E_0*z_1*(I*lambda*(1/(2*pi*sqrt(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2))) + 1)*exp(2*I*pi*sqrt(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2)/lambda)/(lambda*(z_1**2 + (-x_0 + x_1)**2 + (-y_0 + y_1)**2))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 162396 characters]\n",
      "text/plain": [
       "<Figure size 504x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 35144 characters]\n",
      "text/plain": [
       "<Figure size 504x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "propMethodsCartesian.display([\"Rayleigh-Sommerfeld Arg\"])\n",
    "subdiv_points = 512\n",
    "subsDictC = {'E_0': 1, 'z_1': 2*apertureRadius, 'x_0': 0, 'y_0': apertureRadius, 'lambda': waveLength, 'a':apertureRadius}\n",
    "paramAndRanges = [( 'x_1', -apertureRadius, apertureRadius, subdiv_points, 'linear' ),\n",
    "                  ( 'y_1', -apertureRadius, apertureRadius, subdiv_points, 'linear' )]\n",
    "propMethodsCartesian.plotFormula(\"Rayleigh-Sommerfeld Arg\", subsDictC, paramAndRanges, mCalc)\n",
    "paramAndRanges = [( 'x_1', -apertureRadius, apertureRadius, subdiv_points, 'linear' )]\n",
    "subsDictC = {'E_0': 1, 'z_1': 2*apertureRadius, 'y_1':0.0, 'x_0': 0, 'y_0': apertureRadius, 'lambda': waveLength, 'a':apertureRadius}\n",
    "propMethodsCartesian.plotFormula(\"Rayleigh-Sommerfeld Arg\", subsDictC, paramAndRanges, mCalc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 98388 characters]\n",
      "text/plain": [
       "<Figure size 720x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "subdiv_points = 256\n",
    "ez0_c =  subsParamsByName( xyCircle, {'a':apertureRadius} )\n",
    "subsDictC = {'E_0': ez0_c, 'x_1': 0, 'y_1': 0, 'lambda': waveLength, 'a':apertureRadius}\n",
    "paramAndRange = ( 'z_1', 0.01*apertureRadius, apertureRadius*100, subdiv_points, 'geometric' )\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(10,5))\n",
    "plt.xscale('log')\n",
    "plt.yscale('linear')\n",
    "\n",
    "for appr in reversed(approximations):\n",
    "    eeq = propMethodsCartesian.getFormula(appr)\n",
    "    xplot2, zplot2 = mCalc.IntegralEvalE(subsParamsByName(eeq, subsDictC), [paramAndRange], None, 'trap')\n",
    "    plt.plot(xplot2[0]/apertureRadius, np.clip(zplot2, -4.5, 4.5), label=appr)\n",
    "        \n",
    "plt.legend(loc=(1.0, 0.78))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 72676 characters]\n",
      "text/plain": [
       "<Figure size 720x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "approximationsF = [\"Rayleigh-Sommerfeld\", \"Far Fresnel\"]\n",
    "fig, ax = plt.subplots(figsize=(10,5))\n",
    "plt.xscale('log')\n",
    "plt.yscale('linear')\n",
    "paramAndRange = ( 'z_1', apertureRadius, apertureRadius*10, 500, 'geometric' )\n",
    "ez0_l =  subsParamsByName( xyCircle, {'a':apertureRadius} )\n",
    "subsDictC = {'E_0': ez0_l, 'x_1': 0, 'y_1': 0, 'lambda': waveLength, 'a':apertureRadius}\n",
    "for appr in reversed(approximations):\n",
    "    eeq = propMethodsCartesian.getFormula(appr)\n",
    "    xplot2, zplot2 = mCalc.IntegralEvalE(subsParamsByName(eeq, subsDictC), [paramAndRange], [(subdiv_points, 'linear'), (subdiv_points, 'linear')], 'rect')\n",
    "    plt.plot(xplot2[0]/apertureRadius, np.clip(zplot2, -4.5, 4.5), label=appr)\n",
    "plt.legend(loc=(1.0, 0.78))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7fe7966c8f98>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 63952 characters]\n",
      "text/plain": [
       "<Figure size 720x720 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "subdiv_points = 256\n",
    "subsDict = {'E_0': ez0_l, 'y_1': 0, 'lambda': waveLength, 'a':apertureRadius}\n",
    "paramsAndRanges = [ ('x_1', -1.5*apertureRadius, 1.5*apertureRadius, subdiv_points, 'linear'), ('z_1',  waveLength, 15*apertureRadius, subdiv_points, 'linear')]\n",
    "eeq = propMethodsCartesian.getFormula(\"Rayleigh-Sommerfeld\")\n",
    "xplot, fplot1 = mCalc.IntegralEvalE(subsParamsByName(eeq, subsDict), paramsAndRanges) \n",
    "fig, ax = plt.subplots(figsize=(10,10))\n",
    "ax.imshow( fplot1, cmap='hot' )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7fe7b00de0b8>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 41372 characters]\n",
      "text/plain": [
       "<Figure size 720x720 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "subsDict = {'E_0': ez0_l, 'z_1': 2*apertureRadius, 'lambda': waveLength, 'a':apertureRadius}\n",
    "paramsAndRanges = [ ('x_1', -2*apertureRadius, 2*apertureRadius, subdiv_points, 'linear'), ('y_1', -2*apertureRadius, 2*apertureRadius, subdiv_points, 'linear')]\n",
    "eeq = propMethodsCartesian.getFormula(\"Rayleigh-Sommerfeld\")\n",
    "xplot, fplot1 = mCalc.IntegralEvalE(subsParamsByName(eeq, subsDict), paramsAndRanges) \n",
    "fig, ax = plt.subplots(figsize=(10,10))\n",
    "ax.imshow( np.log(fplot1+1), cmap='hot' )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "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.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
