{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1>  (some) LaTeX environments for Jupyter notebook </h1>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "IPython.utils.load_extensions('calico-document-tools');"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%javascript \n",
    "IPython.utils.load_extensions('calico-document-tools');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%%html\n",
    "<style>\n",
    "    .prompt{\n",
    "        display: none;\n",
    "</style>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Presentation and main features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This extension for IPython 3.x or Jupyter enables to use some LaTeX commands and environments in the notebook's markdown cells. \n",
    "\n",
    "\\begin{enumerate}\n",
    "\\item **LaTeX commands and environments**\n",
    "\\begin{itemize}\n",
    "\\item support for some LaTeX commands within markdown cells, *e.g.* `\\textit`, `\\textbf`, `\\underline`\n",
    "\\item support for **theorems-like environments**\n",
    "\\item support for **lists**: *enumerate, itemize*,  \n",
    "\\item limited support for a **figure environment**,\n",
    "\\item support for an environment *listing*,\n",
    "\\item additional *textboxa* environment\n",
    "\\end{itemize}\n",
    "\\item **Citations and bibliography**\n",
    "\\begin{itemize}\n",
    "\\item support for `\\cite` with creation of a References section\n",
    "\\end{itemize}\n",
    "\\item **Document-wide numbering of equations, support for `\\label` and `\\ref`**\n",
    "\\item **Configuration toolbar**\n",
    "\\item Styles can be customized in the *latex\\_env.css* stylesheet\n",
    "\\end{enumerate}\n",
    "\n",
    "A simple illustration is as follows: on can type the following in a markdown cell\n",
    "\\begin{listing}\n",
    "\\begin{theorem} \\label{theo:dotp}\n",
    "Let $u$ and $v$ be two vectors of $\\mathbb{R}^n$. The dot product can be expressed as\n",
    "\\begin{equation}\n",
    "\\label{eq:dotp}\n",
    "u^Tv = |u||v| \\cos \\theta,\n",
    "\\end{equation}\n",
    "where $\\theta$ is the angle between $u$ and $v$ ...\n",
    "\\end{theorem}\n",
    "\\end{listing}\n",
    "and have it rendered as\n",
    "\n",
    "\\begin{theorem} \\label{theo:dotp}\n",
    "Let $u$ and $v$ be two vectors of $\\mathbb{R}^n$. The dot product can be expressed as\n",
    "\\begin{equation}\n",
    "\\label{eq:dotp}\n",
    "u^Tv = |u||v| \\cos \\theta,\n",
    "\\end{equation}\n",
    "where $\\theta$ is the angle between $u$ and $v$ ...\n",
    "\\end{theorem}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Implementation principle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The main idea is to override the standard Markdown renderer in order to add a *small* parsing of LaTeX expressions and environments. This heavily uses regular expressions. The LaTeX expression are then rendered using an html version. For instance `\\underline {something}` is rendered as `<u> something </u>`, that is \\underline{something}. The environments are replaced by an html tag with a class derived from the name of the environment. For example, a `definition` denvronment will be replaced by an html rendering corresponding to the class `latex_definition`. The styles associated with the different classes are sepcified in `latex_env.css`. These substitutions are implemented in `thsInNb4.js`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Support for simple LaTeX commands"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We also added some LaTeX commands (e.g. `\\textit`, `\\textbf`, `\\underline`) -- this is useful in the case of copy-paste from a LaTeX document. Labels and references are supported, including for equations."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Available environments"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **theorems-like environments**: *property, theorem, lemma, corollary, proposition, definition,remark, problem,           exercise, example*,\n",
    "- **lists**: *enumerate, itemize*,  \n",
    "- limited support for a *figure* environment,\n",
    "- an environment *listing*,\n",
    "- *textboxa*, wich is a `textbox` environment defined as a demonstration (see below).\n",
    "\n",
    "More environments can be added easily in the javascript source file `thmsInNb.js`. The rendering is done according to the stylesheet `latex_env.css`, which can be customized."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Automatic numerotation, labels and references"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Counters for numerotation are implemented: one for theorems-like environments, a second for exercises-like environments and a third one for numbering figures.   \n",
    "Mathjax-equations with a label are also numbered document-wide (in contrast with standard notebook/mathjax numbering where the scope of numbering is limited to cells). \n",
    "An anchor is created for any label which enables to links things within the document: `\\label` and `\\ref` are both supported. A limitation is that numbering is updated (incremented) each time a cell is rendered. A toolbar button is provided to reset the counters and refresh the rendering of the whole document."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A simple example is as follows, featuring automatic numerotation, and the use of labels and references. Also note that standard markdown can be present in the environment and is interpreted. \n",
    "*The rendering is done according to the stylesheet `latex_env.css`, which of course, can be tailored to specific uses and tastes*.  \n",
    "\n",
    "\\begin{listing}\n",
    "\\begin{definition} \\label{def:FT}\n",
    "Let $x[n]$ be a sequence of length $N$. Then, its **Fourier transform** is given by\n",
    "\\begin{equation}\n",
    "\\label{eq:FT}\n",
    "X[k]= \\frac{1}{N} \\sum_{n=0}^{N-1} x[n] e^{-j2\\pi \\frac{kn}{N}}\n",
    "\\end{equation}\n",
    "\\end{definition}\n",
    "\\end{listing}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\\begin{definition} \\label{def:FT}\n",
    "Let $x[n]$ be a sequence of length $N$. Then, its **Fourier transform** is given by\n",
    "\\begin{equation}\n",
    "\\label{eq:FT2}\n",
    "X[k]= \\frac{1}{N} \\sum_{n=0}^{N-1} x[n] e^{-j2\\pi \\frac{kn}{N}}\n",
    "\\end{equation}\n",
    "\\end{definition}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is now possible to refer to the definition and to the equation by their labels,  as in:\n",
    "\\begin{listing}\n",
    "As an example of Definition \\ref{def:FT}, consider the Fourier transform (\\ref{eq:FT2}) of a pure cosine wave given by\n",
    "$$\n",
    "x[n]= \\cos(2\\pi k_0 n/N),\n",
    "$$\n",
    "where $k_0$ is an integer. \n",
    "\\end{listing}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As an example of Definition \\ref{def:FT}, consider the Fourier transform (\\ref{eq:FT2}) of a pure cosine wave given by\n",
    "$$\n",
    "x[n]= \\cos(2\\pi k_0 n/N),\n",
    "$$\n",
    "where $k_0$ is an integer. \n",
    "Its Fourier transform is given by \n",
    "$$\n",
    "X[k] = \\frac{1}{2} \\left( \\delta[k-k_0] + \\delta[k-k_0] \\right), \n",
    "$$\n",
    "modulo $N$. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Bibliography"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Usage"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is possible to cite bibliographic references using the standard LaTeX `\\cite` mechanism. The extension looks for the references in a bibTeX file, by default `biblio.bib` in the same directory as the notebook. The name of this file can be modified in the configuration toolbar. It is then possible to cite works in the notebook, e.g. \n",
    "\\begin{listing}\n",
    "The main paper on IPython is definitively \\cite{PER-GRA:2007}. Other interesting references are certainly \\cite{mckinney2012python, rossant2013learning}. Interestingly, a presentation of the IPython notebook has also be published recently in Nature \\cite{shen2014interactive}.\n",
    "\\end{listing}\n",
    "The main paper on IPython is definitively \\cite{PER-GRA:2007}. Other interesting references are certainly \\cite{mckinney2012python, rossant2013learning}. Interestingly, a presentation of the IPython notebook has also be published recently in Nature \\cite{shen2014interactive}."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Implementation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The implemention uses several snippets from the nice [icalico-document-tools](https://bitbucket.org/ipre/calico/downloads/) extension that also considers the rendering of citations in the notebook. We also use a modified version of the [bibtex-js](https://code.google.com/p/bibtex-js/) parser for reading the references in the bibTeX file. The different functions are implemented in `bibInNb4.js`. The rendering of citations calls can adopt three styles (Numbered, by key or apa-like) -- this can be selected in the configuration toolbar. It is also possible to customize the rendering of references in the reference list. A citation template is provided in the beginning of file `latex_envs.js`: \n",
    "```\n",
    "var cit_tpl = {\n",
    "// feel free to add more types and customize the templates\n",
    "    'INPROCEEDINGS': '%AUTHOR:InitialsGiven%, ``_%TITLE%_\\'\\', %BOOKTITLE%, %MONTH% %YEAR%.',\n",
    "    ... etc\n",
    "```\n",
    "The keys are the main types of documents, eg inproceedings, article, inbook, etc. To each key is associated a string where the %KEYWORDS% are the fields of the bibtex entry. The keywords are replaced by the correponding bibtex entry value. The template string can formatted with additional words and effects (markdown or LaTeX are commands are supported)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Figure environment"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, it is sometimes useful to integrate a figure within a markdown cell. The standard markdown markup for that is `![link](image)`, but a limitation is that the image can not be resized, can not be referenced and is not numbered. Furthermore it can be useful for re-using existing code. Threfore we have added a limited support for the `figure` environment. This enables to do something like\n",
    "\\begin{listing}\n",
    "\\begin{figure}[H]\n",
    "\\centerline{\\includegraphics[width=10cm]{example.png}}\n",
    "\\caption{\\label{fig:example} This is an example of figure included using LaTeX commands.}\n",
    "\\end{figure}\n",
    "\\end{listing}\n",
    "which renders as\n",
    "\\begin{figure}[H]\n",
    "\\centerline{\\includegraphics[width=10cm]{example.png}}\n",
    "\\caption{\\label{fig:example} This is an example of figure included using LaTeX commands.}\n",
    "\\end{figure}\n",
    "Of course, this Figure can now be referenced: \n",
    "\\begin{listing}\n",
    "Figure \\ref{fig:example} shows a second filter with input $X_2$, output $Y_2$  and an impulse response denoted as $h_2(n)$\n",
    "\\end{listing}\n",
    "Figure \\ref{fig:example} shows a second filter with input $X_2$, output $Y_2$  and an impulse response denoted as $h_2(n)$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Other features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- It is possible to mix LaTeX and markdown markup in environments  \n",
    "- Environments can be nested. However, this is not always perfect..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## User interface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Buttons on main toolbar"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On the main toolbar, the extension provides three buttons \n",
    "\\begin{figure}[H]\n",
    "\\centerline{\\includegraphics[width=10cm]{main_toolbar.png}}\n",
    "\\end{figure}\n",
    "The first one  can be used to refresh the numerotation of equations and references in all the document. The second one fires the reading of the bibliography bibtex file and creates (or updates) the reference section. Finally the third one is a toogle button that opens or closes the configuration toolbar."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Configuration toolbar"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The configuration toolbar  \n",
    "\\begin{figure}[H]\n",
    "\\centerline{\\includegraphics[width=10cm]{configuration_toolbar.png}}\n",
    "\\end{figure}\n",
    " enables to enter  some configuration options for the extension. First, one can indicate the name of the bibtex file. If this file is not found and the user creates the reference section, then this section will indicate that the file was not found. The references drop-down menu enables to choose the type of reference calls. The Equations input box enable to initiate numbering of equations at the given number (this may be useful for complex documents in several files/parts). Finally the last drop-down menu let the user choose to number equation or to display their label instead.  These configuration options are then stored in the notebook's metadata (and restored on reload)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Installation, usage and further examples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Installation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The extension consists in several javascript scripts: `latex_envs.js`, `thmsInNb4.js`, `bibInNb4.js` and `initNb.js`,  together with a stylesheet `latex_envs.css`. \n",
    "With Jupyter, you may also simply install the extension with\n",
    "```python\n",
    "from notebook.nbextensions import install_nbextension, check_nbextension\n",
    "install_nbextension(\"https://rawgit.com/jfbercher/latex_envs/master/latex_envs.zip\", user=True)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An even more simple procedure is to issue\n",
    "```\n",
    "jupyter nbextension install https://rawgit.com/jfbercher/latex_envs/master/latex_envs.zip  --user\n",
    "\n",
    "```\n",
    "at the command line."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you are still with IPython 3, you can install with\n",
    "```python\n",
    "from IPython.html.nbextensions import install_nbextension, check_nbextension\n",
    "install_nbextension(\"https://rawgit.com/jfbercher/latex_envs/master/latex_envs.zip\", user=True)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You may then try the extension.  Load it by typing \n",
    "```python\n",
    "%%javascript\n",
    "require(\"base/js/utils\").load_extensions(\"latex_envs/latex_envs\")\n",
    "```\n",
    "in a code cell of the notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want to automatically load the extension for any notebook, you may use\n",
    "```python\n",
    "from IPython.html.services.config import ConfigManager\n",
    "ip = get_ipython()\n",
    "cm = ConfigManager(parent=ip, profile_dir=ip.profile_dir.location)\n",
    "cm.update('notebook', {\"load_extensions\": {\"latex_envs/latex_envs\": True}})\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "and replace the `True` by `None if you want to unload the extension. \n",
    "\n",
    "Alternatively you may also do this in javascript via\n",
    "```python\n",
    "%%javascript\n",
    "IPython.notebook.config.update({\"load_extensions\":{\"latex_envs/latex_envs\":true}})\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "replace the `true` by `null` to unload. \n",
    "\n",
    "The last alternative is\n",
    "```\n",
    "jupyter nbextension enable latex_envs/latex_envs\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "and `disable` to disable it, of course."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You may follow the instructions in the [wiki](https://github.com/ipython-contrib/jupyter_contrib_nbextensions/wiki) to install the extension."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## First example (continued)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We continue the first example on fthe Fourier transform definition \\ref{def:FT} in order to show that, of course, we can illustrate things using a simple code. Since the Fourier transform is an essential tool in signal processing, We put this in evidence using the `textboxa` environment -- which is defined here in the css, and that one should define in the LaTeX counterpart:\n",
    "\\begin{listing}\n",
    "\\begin{textboxa}\n",
    "The Fourier transform is an extremely useful tool to have in your toolbox!\n",
    "\\end{textboxa}\n",
    "\\end{listing}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{textboxa}\n",
    "The Fourier transform is an extremely useful tool to have in your toolbox!\n",
    "\\end{textboxa}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Fourier transform of a pure cosine is given by \n",
    "$$\n",
    "X[k] = \\frac{1}{2} \\left( \\delta[k-k_0] + \\delta[k-k_0] \\right), \n",
    "$$\n",
    "modulo $N$. This is illustrated in the following simple script:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f486021e7b8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt \n",
    "from numpy.fft import fft\n",
    "k0=4; N=128; n=np.arange(N); k=np.arange(N)\n",
    "x=np.sin(2*np.pi*k0*n/N)\n",
    "X=fft(x)\n",
    "plt.stem(k,np.abs(X))\n",
    "plt.xlim([0, 20])\n",
    "plt.title(\"Fourier transform of a cosine\")\n",
    "_=plt.xlabel(\"Frequency index (k)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Second example"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example shows a series of environments, with different facets; **links, references, markdown or/and LaTeX formatting within environments**. Again, the rendering is done according to the stylesheet `latex_env.css`, which can be customized. The listing of environments below is typed using the environment *listing*..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{listing}\n",
    "\\begin{definition} \\label{def:diffeq}\n",
    "We call \\textbf{difference equation} an equation of the form\n",
    "$$\n",
    "\\label{eq:diffeq}\n",
    "y[n]= \\sum_{k=1}^{p} a_k y[n-k] + \\sum_{i=0}^q b_i x[n-i]\n",
    "$$\n",
    "\\end{definition}\n",
    "\n",
    "\\begin{property}\n",
    "If all the $a_k$ in equation (\\ref{eq:diffeq}) of definition \\ref{def:diffeq} are zero, then the filter has a **finite impulse response**. \n",
    "\\end{property}\n",
    "\n",
    "\\begin{proof}\n",
    "Let $\\delta[n]$ denote the Dirac impulse. Take $x[n]=\\delta[n]$ in (\\ref{eq:diffeq}). This yields, by definition, the impulse response:\n",
    "$$\n",
    "\\label{eq:fir}\n",
    "h[n]= \\sum_{i=0}^q b_i \\delta[n-i],\n",
    "$$\n",
    "which has finite support. \n",
    "\\end{proof}\n",
    "\n",
    "\\begin{theorem}\n",
    "The poles of a causal stable filter are located within the unit circle in the complex plane.\n",
    "\\end{theorem}\n",
    "\n",
    "\\begin{example} \\label{ex:IIR1}\n",
    "Consider $y[n]= a y[n-1] +  x[n]$. The pole of the transfer function is $z=a$. The impulse response $h[n]=a^n$ has infinite support.\n",
    "\\end{example}\n",
    "\n",
    "In the following exercise, you will check that the filter is stable iff $a$<1.\n",
    "\n",
    "\\begin{exercise}\\label{ex:exofilter}\n",
    "Consider the filter defined in Example \\ref{ex:IIR1}. Using the **function** `lfilter` of scipy, compute and plot the impulse response for several values of $a$.\n",
    "\\end{exercise}\n",
    "\n",
    "\\end{listing}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The lines above are rendered as follows (of course everything can be tailored in the stylesheet):\n",
    "\n",
    "\\begin{definition} \\label{def:diffeq}\n",
    "We call \\textbf{difference equation} an equation of the form\n",
    "\\begin{equation}\n",
    "\\label{eq:diffeq}\n",
    "y[n]= \\sum_{k=1}^{p} a_k y[n-k] + \\sum_{i=0}^q b_i x[n-i]\n",
    "\\end{equation}\n",
    "\\end{definition}\n",
    "Properties of the filter are linked to the coefficients of the difference equation. For instance, an immediate property is \n",
    "\n",
    "\\begin{property}\n",
    "If all the $a_k$ in equation (\\ref{eq:diffeq}) of definition \\ref{def:diffeq} are zero, then the filter has a **finite impulse response**. \n",
    "\\end{property}\n",
    "\n",
    "\\begin{proof}\n",
    "Let $\\delta[n]$ denote the Dirac impulse. Take $x[n]=\\delta[n]$ in (\\ref{eq:diffeq}). This yields, by definition, the impulse response:\n",
    "\\begin{equation}\n",
    "\\label{eq:fir}\n",
    "h[n]= \\sum_{i=0}^q b_i \\delta[n-i],\n",
    "\\end{equation}\n",
    "which has finite support. \n",
    "\\end{proof}\n",
    "\n",
    "\n",
    "\\begin{theorem}\n",
    "The poles of a causal stable filter are located within the unit circle in the complex plane.\n",
    "\\end{theorem}\n",
    "\n",
    "\n",
    "\\begin{example} \\label{ex:IIR1}\n",
    "Consider $y[n]= a y[n-1] +  x[n]$. The pole of the transfer function is $z=a$. The impulse response $h[n]=a^n$ has infinite support.\n",
    "\\end{example}\n",
    "\n",
    "In the following exercise, you will check that the filter is stable iff $a$<1.\n",
    "\n",
    "\\begin{exercise}\\label{ex:exofilter}\n",
    "Consider the filter defined in Example \\ref{ex:IIR1}. Using the **function** `lfilter` of scipy, compute and plot the impulse response for several values of $a$.\n",
    "\\end{exercise}\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{listing}\n",
    "The solution of exercise \\ref{ex:exofilter}, which uses a difference equation as in Definition \\ref{def:diffeq}:\n",
    "\\end{listing}\n",
    "The solution of exercise \\ref{ex:exofilter}, which uses a difference equation as in Definition \\ref{def:diffeq}:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAEKCAYAAAAYd05sAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXeYlNX1xz8HBJQmRQRFUAGJFEGiQSnqtaCAQbFEg4A1\nUbEk/tSIGnXYKBE1RmNBsaFEsEUsCLHvVRHsigKiIkFBpQhI75zfH/edZXZ3dsruzLwzy/08z31m\n5i33Pe+wfN875557jqgqHo/H46l+1AjbAI/H4/FkBy/wHo/HU03xAu/xeDzVFC/wHo/HU03xAu/x\neDzVFC/wHo/HU03ZKVcXEhEfj+nxeDyVQFWlMuflTOCh8kZWN0RkhKqOCNuOsBChJnAZcA2c+BG8\ncLwqW8O2K2x29L+LWPx3sZ2qDI69i8aTU0ToCLwLDAAOhRff8+Lu8WQHL/CenCBCbRGuA94GHgWO\nUmVuuFZ5PNWbnLpoPCXYsA3IJSIcDDwM/AD8WpXvY3bbUIzKT2zYBuQRNmwDqgOSq1w0IqLeB79j\nIUJdoAg4E7gCGK+Kn2z3eNKgKtrpR/CerCDC0cADwPvAAaosCdkkT4r4iLfwyPQg2Au8J6OI0AS4\nDTgGuEiVySGb5KkEPsts7hHJvIPDT7J6MoIIIsLvgVnAOqCzF3ePJ1z8CN5TZUTYGxgNtAZOUuW9\nkE3yeDykMIIXkUdEZLGIfJHkuN+IyBYROTlz5nnyGRF2EuEK4GNgGnCQF3ePJ39IxUUzFuib6AAR\nqQncArwM+EiZHYAg9PEDoD/QQ5WRqmwK2SyPxxNDUoFX1XeAFUkOuxT4D7A0E0Z58hcRGorwL+Al\n4E7gGFW+CdksjyctJkyYwN577039+vU56aSTWLEivsQtXbqUQYMG0bJlSxo1akTv3r354IMPcmxt\n5anyJKuItAROBO4LNvnp92pIMIl6Mm4StT7QSZVxPq7dU2jMmjWLCy+8kPHjx7N48WLq1q3LRRdd\nFPfYNWvWcMghh/DJJ5+wYsUKzjrrLI4//njWrl2bY6srR0oLnURkH2CSqh4QZ98zwD9U9X0ReTQ4\n7tk4xylu0UsUq6q2cmZ7cokI+wD3AG2AC1V5O1yLPNkkWFgTthkVMmrUKB566CGWLFlCq1atGDly\nJAMHDkz5/GuvvZbvv/+exx9/HIB58+bRoUMHli9fTr169ZKev+uuu2KtpVu3bpW+h3iICKoqImIA\nE7MrEuZCp4OAJ4MYzt2AfiKyWVVfLHugzw5XWIhQG7gcuBK4HTjZ+9k9YdOuXTumTp1KixYtePrp\npxkyZAhz585l7ty5DBgwoMLzJk+eTM+ePZk9eza9evUq2d6mTRvq1KnD119/nVS0P/vsMzZt2kS7\ndu0ydj9lCQa+NvpZRCKV7avKAq+qbWIMGYsbwZcTd09hIcIRuNDH74DuqswL2SRPHpGpNTmV+aFw\n6qmnlrw/7bTTuPnmm/nggw844YQTKvSlx7JmzRp23XXXUtsaNmzI6tWrE563atUqhg4dyogRI2jQ\noEH6hodAUoEXkSeAI4DdRGQBEAFqAajqmOya58k1IjTHrUQ1uJztz3k/u6csYXpwxo0bxx133MH8\n+fMBJ9jLli1L+fz69euzcuXKUttWrlyZULTXr1/PgAED6NmzJ8OHD6+U3WGQVOBVdVCqnanqOVUz\nxxMWQRGOYbgH+KNAR1XWhGqUx1OG7777jvPPP58333yTHj16ICJ069YNVWXq1Kn069evwnNffvll\nevXqRadOnZgxY0bJ9m+//ZZNmzbRvn37uOdt3LiRgQMH0rp1a8aMKawxrV/J6kGEQ3HumNWAUWVW\nyCZ5PHFZu3YtIsJuu+3Gtm3bGDduHDNnzgSgd+/eSd0sAIMHD6ZHjx5MnTqVbt26cf3113PKKafE\nnWDdvHkzp556KnXr1uXRRx/N9O1kHZ+LZgdGhGYiPAxMBP6JF3dPntOxY0euuOIKevToQYsWLZg5\ncya9e/dOu4/777+fwYMH07x5c9avX8/o0aNL9g8bNoxhw4YBMG3aNCZPnsxrr71Go0aNaNCgAQ0a\nNODdd9/N6H1lC58PfgckcMecjwtbHQ+MUGVl4rM8Owr5HiZZXYmGScbZ7vPBe1JDhJ64mPbVwNGq\nJMwx5PF4Chcv8DsIIrTA5Qs6GhfX/pSPjvF4qjfeB1/NCYpdXwHMBBYB+6vypBd3j6f640fw1RgR\njgP+BcwDeqrydcgmeTyeHOIFvhoiQjtcVExH3GKlyX7E7vHseHgXTTVChAYi3AK8B7yLy/j4khd3\nj2fHxAt8NUCEGiKcA3wFNAcOUOUWVTaGbJrH4wkR76IpcETohfOzbwJOVOXDkE3yeDx5ghf4AiXI\n0X4L0AO4BpjgXTEejycW76IpMAI/+0hcoevZuLDH8V7cPZ7USbVkH7gKUMYYGjVqRKtWrbjpppty\naGnV8AJfIIhQU4Q/4PzsrYGuqhSpsi5k0zyegiKdkn0AQ4cO5bDDDmPFihW89dZbjB49mkmTJuXQ\n4srjBb4AEOEY4BPgLOAEVYaqsjBkszyeUBg1ahTt2rWjYcOGdOrUieeffz6t88ePH88JJ5xA7969\nqVevHjfeeCMTJ06ssM7q7NmzGTx4MCJCmzZt6N27N7Nnz87ErWQdL/B5jAgdRZgMjAFuBA5X5aOQ\nzfJ4QiVasm/VqlVEIhGGDBnCokWLmDp1Ko0bN66wTZs2DXCC3bVr15L+Ykv2xePYY4/lscceY8uW\nLcyZM4fp06dzzDHH5OReq4qfZM1DgqpKI4BTgJtxtVB9yKMnb5CizCSG1Uj6U0e5Ltl3xx130KdP\nH/7xj3+wdetWIpEIBx10UNp2h4EX+DxChLq4IteXAeNwE6jLw7XK4ylPZYQ5U+SyZN+6des46qij\nGDlyJGeccQY//fQTp556KrvvvntJzvh8xrto8oBgAvVc4GvgAOAQVS734u7xlCZasu/ee+9l+fLl\nrFixgs6dO5eU7IsW5IjXokU60inZN2vWLFavXs2QIUOoUaMGLVu25PTTT2fKlCk5u+eq4EfwISKC\nAH2BW4FfgFNVeS9cqzye/CXXJfvatWvHpk2beOKJJzj99NNZsmQJTz31FEcffXTG7y0b+BF8SIhw\nMPAGcAdwHW4C1Yu7x5OAXJfsa9y4Mc888wy33XYbjRs3plu3bnTp0oXrrrsuo/eVLZKW7BORR4Dj\ngSWqekCc/YOBqwDBVQkapqqfxznOl+wDRGgLjAQOw5XMe0SVLeFa5fFsx5fsC4dslOxLZQQ/FudG\nqIh5wOGq2gUXyvdAZQyp7ojQXIR7gPdxxTfaq/KAF3ePx5Mtkgq8qr4DVBh7pKrTVTU6Jf0+sFeG\nbKsWiNBQhCJcWoHNQAdVblIl/qoKj8fjyRCZ9sGfBxTG9HKWEWFnES7DRcbsCxykyv+psjRk0zwe\nzw5CxqJoRORI4FygV4JjRsR8tKpqM3X9fEGEnYChuIVKnwHHqDIzVKM8Hk/BICIGMBnpK5XJFBHZ\nB5gUb5I12N8FmAj0VdW5FRxTrSdZg5DHU3DzEEuAa1V5N1yrPJ708ZOs4ZCNSdYqj+BFpDVO3IdU\nJO7VmUDYjwNuwrm8/g94xafv9Xg8YZNKmOQTwBHAbsBiIALUAlDVMSLyEHAS8H1wymZV7R6nn2o3\nghfhMODvuO/mBuBZVbaFa5XHUzX8CD4csjGCT8lFkwmqk8CL0B3nimmP87WP9+GOnuqCF/hwCCsO\n3hMgQlcRXsC5pJ4DfqXKY17cPR5PPuIFPgWCvOzPAK8AFthPlftV2RSuZR6PpzKkU7Jv2rRpdO/e\nnYYNG9K1a9eSpGWFgBf4BIjwKxHGA8XAh0BbVe5QZX3Ipnk8nkqSTsm+5cuXM2DAAIYPH87KlSu5\n6qqrGDBgAL/88kuOra4cXuDjIMJ+IowDpuJWoLZT5Va/+tTjCZ9cluybNm0aLVq04JRTTkFEGDx4\nMM2aNWPixImZup2s4gU+BhHaiTAWmA7MxQn7SFWS5yD1eDw5Idcl+8qybds2Zs2alZV7yzQ+HzxO\n2IG/AgOAu3HCXhi/wTyeMJAMBcRVIlonlyX7evTowU8//cRTTz3FySefzIQJE5g3bx7r1q1L2+4w\n2KFH8IEr5jHgPeA7nLAXeXH3eJKgmplWCcaNG0e3bt1KRuYzZ87MWsm+pk2b8vzzz3P77bfTokUL\nXnnlFY455hj22qswcirukCN4EfbHjdj74kfsHk/BEC3Z9+abb9KjRw9EhG7dupWU7OvXr1+F5778\n8sv06tUrrZJ9AIcffjgffPABAFu2bKFt27ZceeWVmb2xLLFDCbwInXDVk44G7gIuUWVl4rM8Hk++\nkOuSfQCffvopnTt3Zv369dxwww20bt2aPn36ZPS+ssUO4aIRoZsIzwJv4jI8tg1ysntx93gKiFyX\n7AO47bbbaNasGa1bt2bx4sU899xzGbufsojILyKyIGP9VedUBSIcihuxdwNuAx70oY4eT2J8qoJw\nEDdx3QRYo6qbY7aHl00y3wiyOx6J87G3BW4BTlVlQ6iGeTweTxJUNXkYUBpUG4EPhP144FqgKXAz\nLgnY5oQnejweTzWl4AVehJrA74BrgG04YX9Wla2hGubx5DEishNQD6gfp3mqCQUr8CLsDJwJXIXL\nU38N8F9faMNT3QjEOJ4QR1uDNPc3AGoDa4E1wOrgNdo81YSCE3gRGgIX4ConfQqcrcrUcK3yeEDc\nLFlttgtpRSPkdAW5FqUFOFaQ18Z8XguswBXfWZvguDXAuopmUkXED5KqCQUj8CI0B/4MnI9L29tP\nlRmJz/J44hOIcV1KC2lFgpysxQoylBbhssIa3bcW+Bn4X5nj4p23wYe1eCpD3gt8kCfmSuB0YALQ\nXZV54VrlySUiUouKBbiyolwP2ED8UXC8ke/CVI5TVV8jwJM35K3AB2Xx/gIY4H5c9aQloRrlSYiI\n1KD0qLgi8U13e01Kj4DLCm3s9lXAjxXsKyXIquon4j3VmrwSeBFqAP1xwr4PcAdwjqqf+MkkgXti\nZxILbFmxTTZ6rgfsAqyntLAmEtofKD8Kjvd+o3dReDzpkxcCL0IdYDBwBbAJt+r0mR09hr2MEMcT\n34oEOdn7erjvuSJhLTtCXorzFccT7tjj1qnqtux8Gx5P5pgwYQLXXHMNy5Yto0+fPjzyyCM0btw4\n7rHTpk3jsssuY86cOey7776MHj2aXr16AWCt5aijjiqVx2b06NEMHTo0J/eRjKSpCkTkEdwCoiWq\nekAFx9wF9APWAWer6qdxjim33FaEJsCFwCXADOAfwJuFFuoYCPEulBbQVEQ2FUHeTOLRbawgr01w\nXKwge/eEp0Kqe6qCWbNm0aNHD6ZMmUK3bt04//zz2bZtG0888US5Y5cvX85+++3HAw88UJIP/tJL\nL2XevHk0atQIay1Dhw5lwYKqp48REeKlJMh2qoKxuJS64yowqj/QTlX3E5FDgPuAQxN1GEycXgac\nAbwAHKfKF+kYXhnK+IgrEuFUtpfdHyvEZYU3niCvABaQgjir6pbsfBseT2EyatQoHnroIZYsWUKr\nVq0YOXIkAwcOTPn82JJ9ADfeeCMdOnRg7dq15TJKxpbsA5eJ8m9/+xsTJ07k3HPPzdxNZYmkAq+q\n74jIPgkOOQF4LDj2fRFpJCLNVXVx2QNFOAy4HOgNPAB0UuWn8seVLOxIVWxTFeRYH3FFfuLYfUuB\n+VQs2lFxXueF2OPJDdGSfS1atODpp59myJAhzJ07l7lz5zJgwIAKz5s8eTI9e/Zk9uzZJS4WKF2y\nr1u3bkmvX7Zk35IlS2jRogV169Zl4MCB3HTTTdStW7dqN5khMuGDb4kbjUZZCOyFW11ailq1vn+l\nYcP7f6xT5555mzevPnbTJo6vV4/amzdTZ9s2dt62jV1UqYeLmognpmWFOCq8P1ZwXNkRsvcRezwZ\nQKzNSD9qTNrn5FPJvg4dOjBjxgz2339/5s+fz1lnncXll1/O/fffn/Z9ZYNMTbKW9Q/FdeAdsMdB\ntbbWWdtYd16/837tWX3ggWyoVw/q10fr1UPr1oVddkFr10aCiBrB5awv+z621Uyh1QpaTVy+Go/H\nUwUqI8yZYty4cdxxxx3Mnz8fcIKd7ZJ9V155JRdddBHHHXdcqZJ9zZs3p3nz5gDss88+3Hrrrfz2\nt7+tksCLiMGFh1eZTAj8D0CrmM97BdvKcdyvnjnv2NcYCBzGFzzOs9xj1Cwse5y1JYmQKnLFlN22\nO7BvnO3l+rBWtlHxL4O1FWxLtn8tsNYYP3Hp8WSTQijZt21b1caQqmoBG/0sIpHK9pUJgX8RFwXz\npIgcCvwSz/8OcPtfNvf5+6t9TrZi2wB/Aj63Yl8B7jRq3o8eZ4xuAVYGLWNYWypXSNwHQJz3e8U5\nNt6DpK61sonyD4JED4lE+2M/r/MPD48n/0r2WWvZd999ad26NQsXLmT48OFpTfhmm6QCLyJPAEcA\nuwWlpCI4dweqOkZVp4hIfxGZixOjcyrqa5vIQLF2T1UzD7jMio0A5wFPWrGLgH8Bzxo1WYl/N0YV\n2Bi01H/TpUDw8IiNWU/l4dE0zrHxzq1rrWwk8QMinYdJ2V8efoLYUxDEluyrUaMGZ555ZpVK9kXj\n4MeOHVuyP1qu77777gNcyb4pU6YA0K9fv1Il+z799FOGDBnCihUraNq0KSeffDIjR46s6m1mjJyW\n7DP//Od7tlu3YjXm2th9VmxNYAAudLIdMBp40KhZmhPj8pzg4RGNs0/khqps20KGHhZBWxfzflPw\nYPUUCNU9Dj5fyUYcfE4F/oN2bd7u/uDDHYF91Zi46Qes2AOBS4GTgeeAu42acgunPJkh5pdHJh8Y\nsU0o/8BYR+UfGLFtvTE+KirTeIEPh4IX+M3CL7XeePNNRKwac3ei463YZsAfgWG4WPS7geey5b7x\nZAdrpTbxhb9uBdsravGO35nS6xoqeiCk8kCJd84O+evDC3w4FLzAr6nF0vOuvv6Sp446ahTQXo1J\n6vu1YncCBuJG9W2BMTj3zaLsWuzJd6wtWZmc6gMj0THx9sX++kj2kEj2UCn3OV/nPrzAh0PBC/yM\n3fmoyxLuleLic4Exasz4dPqwYrsAFwOnAVOAe4D3jBr/1+jJONZKLRI/CMo+FNL9HDv3sa7M+7Qf\nGGXfVzbyygt8OBS8wN97MK9e9BHzpbj4OVzGyK5qTNo+VCu2MXA2cBFuleq9wBNGzbpM2uzxZItg\n7qMOmXlgxOujLhU/QGI/l31de+SR/MsLfO4peIHvN5gpU8bTWoqLuwAfAxE1ZlJl+7RiawB9cHH4\nPYB/A/cZNV9nxGiPp0CJeYCUfSBU9EAp2XfkkVzqBT73FLzA176OtzbexMFASykuPg5XOLunmqq7\nWKzYfXD1Ws8DvsBltXzRT8p6POnhXTThkA2Br1F1s1Jn007shRu5HwI8i1voc0Qm+jZq5hs11wKt\ngUdwMfXzrdgiK3avTFzD4/F4ComcCjywl8I03Kh9K3ArcE0mL2DUbDRqJhg1hwF9gSbADCv2BSu2\nX7CoyuPxePIOa+Vv1sqfMtVfrgV+7ZzdmAn0DD7/G+go1v4mGxczar4wai7FjepfBG4EvrVi/2rF\n7pGNa3o8nvxnwoQJ7L333tSvX5+TTjopYZrhadOm0b17dxo2bEjXrl159913S+0fOXIke++9N7vu\nuiuDBg1KKR9OArbiVqpnBlXNSQOUEXx23BCMwkqFWqoKxcWXUFw8KVd2FFN8UDHFY4opXlFM8cRi\nivsWU1wzV9f3zbd8b04Wqi8zZ87UBg0a6DvvvKNr1qzRM844Q3//+9/HPXbZsmXapEkT/c9//qPb\ntm3Txx9/XBs3bqwrVqxQVdVHH31U999/f124cKGuWbNGTzzxRD3rrLMqZVfwvVf071Gpf8tcj+AX\nvNKOXXEFnH8dbHsI6CbWHpwLA4yaj42aC3Cj+peBm3Cj+uut2Ja5sMHj8VSeUaNG0a5dOxo2bEin\nTp14/vnn0zo/tmRfvXr1uPHGG5k4cSJr164td2xsyT4RYfDgwTRr1oyJEycCMGnSJM477zxatmxJ\nvXr1GD58OE899RQbNmzIyL1WlVwL/EJc7nhLkNBejdkAjAJuyKUhRs1qo+YBo+Zg4BRgT+ALK3aS\nFXtCsILW4/HkGdGSfatWrSISiTBkyBAWLVrE1KlTady4cYVt2rRpAMyePZuuXbuW9Bdbsi8VYkv2\nBZEvpfZt3LiRb775JoN3XHlyLWIL2C7wFwC3BNsfAq4Waw9SYz7OsU0YNR8DH1uxV+JWyV4N3G/F\nPgo8bNR8m2ubPJ58xorNSD9GTdrn5FPJvr59+3Lrrbdy2mmn0ahRI265xUladH/Y5FbgVRYg2gl4\nG3gMkVqoblZjNoi1t+BG8Sfm1KYYjJq1wFhgrBXbERdTP92KnQU8jMtVvz4s+zyefKEywpwp8qlk\n37nnnsuCBQswxrB161Yuv/xyXnrppZL9YZNbF836JouAVqgup7QfHuBB4GCx9tdxz80xRs1so+YK\nXEWne4HBwEIr9j4r9jdWbKUWHng8nsoTLdl37733snz5clasWEHnzp1RdSX7GjRoUGGLRr9UtmTf\nsmXLGDduHHPmzKF79+6Ac9GMGDGC//3vf3z//fd07NiRvfbai5Yt82M6L7cCv7jzUrbXb7XEFJYN\nfPE3A0U5tSkJRs0mo+Y/Rk0/4EDcPMKTuHKD/xekNfZ4PDmgbMm+sWPHlivZV1Hr1asX4Er2TZo0\nialTp7J27dqUSvZt3ryZVatWceWVV5Yq2bdixQq+/fZbVJXZs2dzxRVXcMMNOZ1OTEhuBf6da5cB\ne0qR1KCMwAc8CBwg1vbKqV0pYtQsMGpGAvvh8t90A76xYp8LJmZrhWuhx1O9iS3Z16JFC2bOnFml\nkn3Nmzdn/fr1jB49umT/sGHDSsr2gSvZ16xZM1q3bs3ixYtLlez7+eefOf7446lfvz79+/fnvPPO\n4w9/+EPVbzRD5DQXDWhrRsjHQFcdwUacm2Y3VEvyxYi1Z+PquppM5KjJNlZsQ9zE7Dm4fPXjgceM\nms9DNczjqSQ+F004FHwuGlx2uwXAXhX44QEeB3YHjs2xbZXCqFll1Dxk1PQCDsdVGJpsxX5ixf7Z\nu3A8Hk9YJBV4EekrInNE5BsRGR5n/24i8rKIfCYiM0Xk7ATdRQU+rh8eIKjydD3wd7GFNZFp1Hxt\n1FwH7ANcBRyMc+G8YMWeYsXWCdVAj8ezQ5FQ4EWkJq5qUl+gIzBIRDqUOewS4FNVPRAn1reLSEXh\nl3XYvtgJ4vvhASYGr6ckNj8/MWq2GjWvGzVDcff6PK4S1Y9BFE5PH4Xj8XiyTbIRfHdgrqrOV+cn\nf5Lyceo/AQ2D9w2BZaoV1prcmdIj+LeBnoiUmpwMqjxdC9wktrAnLoMVs2ONmqNw7qiFuHTG31ix\nESu2bbgWejye6koygW+JE+QoC4NtsTwIdBKRH4EZwJ8T9LfdBw8Efvh5QLxskq8G18ufKekqYtR8\nF0ThdAB+j0tlPM2KnWbFXmTF7hauhR6PpzqRTOBTmUq/FvhMVffExYnfKyLll4Q5ogLfOmbbq8Bx\n5S7sImj+Atwg1jYsu7+QMWrUqPnIqPkz7mF3E9AbmBvkwjndiq0brpUej6fQSSbwP7DdnULwfmGZ\nY3oCzwCo6re4yJhfxe/usLP4BwN5nQNExAQbXyGOwAOoMZ8Cr+EmLKslRs1mo2aKUXMG7vt9BjgX\n+MGKfcyKPc4nPvN4dhxExIjIiGirUl+J4l2DydKvgKOBH4EPgEGq+mXMMf8EVqpqkYg0x5Xk66LO\n/RLbl4Kezgj5D7AGaK4RXY1IHWAJ0AbVcgklxNrWwKdAFzXmh6rcbCFhxbbAxdcPxkXlPA1MAN4z\nmv/rAzyFi4+DD4ecx8EHk6WX4EbZs4GnVPVLEblARC4IDvs7cLCIzABeB64qK+4x1NGIbgO+xS0K\nAtWNuMnWY+LaYMz3wAO4akw7DEbNIqPmLqPmEKAXsBQ3OTvPir3Ziu3iI3E8Hk8iksbBq+p/VfVX\nqtpOVW8Oto1R1THB+59VdYCqdlXVA1R1QoLudg5e5wLtYrZX6KYJGAX0F2sPTGZvdcSomWvU/A0X\nqnoS7t9tEjDTir3Oim2XsAOPx1OKXJXs++GHHzjxxBNp2rQprVq1YsyYMVm7p3iEsZIVKhJ4kbgj\nUjVmJTACuKvQFj9lkmBy9jOjZjiwL3A+0AKYasV+ZMX+xYrdO1wrPZ78ZtasWVx44YWMHz+exYsX\nU7duXS666KK4xy5fvpwBAwYwfPhwVq5cyVVXXcWAAQP45ZdfAHjsscd4/PHHmTZtGj/++CPr16/n\n0ksvLTl/yJAhtG3bliVLljB58mSuvfZarLW5uE1HZWv9pdsABb1CVWEEFzCCh0r2gyjMU+hc4fnF\nxTUpLv6M4uLTc2VzobRiimsWU3xUMcUPFFP8czHF04spvqyY4pZh2+Zb4TXyvCbrzTffrG3bttUG\nDRpox44d9bnnnkvr/GuuuUYHDx5c8vnbb7/V2rVr65o1a8odO2nSJO3YsWOpbe3bt9eHH35YVVVP\nOeUUve2220r2TZs2TXfeeWddv369rl69WkVEly5dWrL//PPP16FDh8a1i2pQkzX+CN7dRUI3jRqz\nFfgTcJtYH0IYS7By9k2j5nxgD1zK5a64EoTvWLGXWrF7hmulx5MZCqVkX3R72f3R9Ma5INfhdxW5\naMAJ/EXA7RWdrMa8LdZOB4YDkaxYWOAYNZtxxcRfDnLf9AF+BxRZsV/gwjAnGjU/hmimp8DJlKe0\nMgljC6VkX4MGDejVqxc33ngjt912G7NmzWLixInsvvvuad9zZcm1wEcnWRcCu0mR1NWIRosXvgn8\nG5G6qCYqaPgX4FOx9hE15rtsGlvoGDUbgZeAl2LE/jTgb0EZwqjYl13b4PEkJMxM3oVUsm/8+PFc\nfPHFtGrVirZt2zJkyJCS0X8uCMVFoxHdilsQ1aZkj+oqXLz74Yk6CMIm7wLuyJqV1RCjZqNR85JR\ncybOjXOy1/PvAAAgAElEQVQLrmDJjCBVwuVW7D6hGunxJKHQSva1bt2aSZMmsWTJEqZPn87SpUs5\n5JBDsvwtbScsFw1sd9PEOqT+C/THuRgScQswU6ztr8ZMyayJ1Z8yI/vawFG4zJ0fWrHfAc/iCoyn\n5pT0eHJE2ZJ948aNK1eyLxmDBw+mR48eTJ06lW7duqVUsq9z586sX7+eG264oVzJvuXLl9OmTRu+\n/PLLciX75syZQ8uWLalTpw5PP/00r732GnPmzMnAN5EaYU2yQnw//IvAiRWFS0YJ6rdeDNwj1u6S\nWRN3LIKasy8bNX/EjeyvwiWUs1bsTCu2yIrt6hdVefKBQivZ98orr9C2bVuaNGnCAw88wCuvvELT\npk2r8A2kR65L9k1QZTCAFMnFwAEa0QtjDwK+AU5F9bOkfVr7NPCVGnN9lszeYbFiawCH4Eb2J+MS\nzz0XtPeMmq0hmufJIj5VQThUh5J9O8e8Lz+Cd39VL1A+53xF/B8wTKytILmZp7IYNduMmulGzZW4\ntBInA+uA+3CJ0B6wYvv5KlUeT/6S6xH8ZFV+CyBF0hZ4QyO6T5kDDwfuRLVsrdb4/Vr7f8DxQJ9C\nKNJdHQhSIwwMWmdciOvzwBSjZmWicz35jx/Bh0M2RvC5FvjXVekDIEWyE7AWaKgR3Rhz4E64KlEH\nofp90n6t3QmX5fIuNebRbNjuqRgrtjkwAJcj5zDgPdyvsBeNmgWJzvXkJ17gw6E6CPw7qtvDIKVI\nvgEGaETnlDn4UeAjVO9JqW9ru+FGkQeoMYszZ7UnHazY+rjVyCfiflV9RyD2wGc+zXFh4AU+HKqD\nD76svzZeJA2k54ePFgZ5BLi78qZ5qopRs8aoeTaItW+OmyNpiFtQ9Z0Ve68V29f77T2e3JDrEfzn\nqpQkgZAiuRv4ViN6Z5mD6+HcNK1R/SWl/l245AzgL2rMC5mz3FNVghDL/YETcO6cA4A3cCmPJxs1\nS0I0z1MGP4IPh+rgovlKlf1LthXJn4H9NKKXxDlhEjAB1SdSvoa1RwDjgc5qTEoPBk/uCYqL98eJ\nfR9gDsHCK2CGd+WEixf4cKgOAj9flX1LthXJ8cClGtG+cU74A3AMqr9P6zrW3gfsrMacU1WbPdkn\nWEl7GPBbnODvDEwBJgOvGzVrQzRvh8QLfDhUB4H/SZWStLVSJL8CJmtEy/vhXX3Xr4A9UF2f8nWs\nrQ98DvxZjZlUdcs9ucSKbY8T+98CvwGm4cR+ilEzN0zbdhS8wIdDdZxknQ+0kiKpVe5I1cXAR7if\n8imjxqwBzgHGiLW5WxPsyQhGzddGzT+NmqNwKRMeAA4E3rFiv7Zi77Rij7Vid07ck8cTn0WLFnHC\nCSfQsmVLatSowfffJ47Gnj9/PkceeST16tWjQ4cOvPHGG6X2Jyr/9/TTT9OzZ0/q1avHkUcemZX7\nSUSYK1kJ4t9/hO1umzI8CaTlogFQY94Kzk0pzNKTnxg1q4KonHNxYn86rvh4BFhixb5kxV5sxbZJ\n2JHHE0ONGjXo378/zz77bErHDxo0iIMOOojly5czcuRITj31VH7++Wcgefm/pk2bcvnll3P11Vdn\n5V6SkWsXzVbV0hkspUheAh7RiE6Mc1ITXFrhvVBNniYu9lQXVfMpcIMa83TlLffkI1ZsE9wEbT+g\nL7AKl430ZeAtoyZRTQFPAvLdRTNq1CgeeughlixZQqtWrRg5ciQDBw5Mu58tW7ZQu3Zt5s+fT+vW\nreMe8/XXX9OlSxeWLVtWkm3yiCOO4IwzzuCCCy7g2muv5fvvv+fxxx8HYN68eXTo0IHly5eXyk75\n0EMPMX78eIqLiyu0JxQXjYj0FZE5IvKNiAyv4BgjIp+KyEwRsYmuJ0LNMtu+wC13L4/qcmAqbvIt\nLdSY9cBQ4G6xtlW653vyG6NmuVHzlFFzNrAnrpDJIly1r8VW7KtW7BVWbGefCbN6UdWSfekwa9Ys\n2rRpU0qsu3btWlK0Y9asWVUq/5dtEuaDF5GaODfHMcAPwIci8qKqfhlzTCPgXuA4VV0oIrsl6HIj\nzg8fO7r6ArfMvSKibpoJiWyNhxrzoVj7L2CcWHtMUNfVU80warYBnwXtZiu2IS7H/XHAJUAtK/ZV\n3GrnN4yan0MztpqQJKN3ylTml0JVS/alQ7zyfg0aNOCnn34CXH76VMv/hUGyEXx3YK6qzlfVzTix\nLbvC9AzgWVVdCKCqif7zRAU+li9wC18q4gXgCEQaJ7G1Im7B3eeVlTzfU2AEvvvnjZphuKphR+Hc\ndYOBb63YD63YkVasCcI0PWmiqhlplWHcuHF069atZGQ+c+bMtEr2pUP9+vVZtWpVqW2x5f3SKf8X\nBskEviUQmzBqYbAtlv2AJiJSLCIficjQBP1tpMxEKy4Ucm8pkviFO1wpv9dJPMqvkGDUPhS4Qqw9\nuDJ9eAoXo0aDyJy7jZoTgGa4h70CtwI/W7GTrdjLrNhO3p2T32SiZF86dOrUiXnz5rFmzZqSbTNm\nzKBTp04l+1Mp/5epXzzpkkzgU3nE1gJ+jQtnPA64XkT2q+DYDZQZwWtEN+GKfHRIcI2ncBEUlSKo\n43oJMEGszY9HqycUggpWbxk11xk13XERXI8CHXEraX+wYsdZsWdasWUHM56QKVuyb+zYseVK9lXU\nevXqVdLPhg0b2LBhQ7n3ZWnfvj0HHnggRUVFbNiwgYkTJzJz5kxOOeUUwJX/mzRpElOnTmXt2rXl\nyv9t27aNDRs2sHnzZrZt28bGjRvZvHlzNr+iUiSryfoDEDtB2Qo3io9lAfCzusVI60XkbaArTrTL\ncFV9+M8VIv9bBlhVtcGOqJvmkwrsmAw8gMjuqFYqb4ka87RYewwuPn6wzx3vATBqluGSoT0TjN7b\n4uacTgDutGIX4X5BvgFYn+8+XGJL9tWoUYMzzzwz7ZJ9AHXr1gXcyHr//fdHRNi61U3RRcv13Xff\nfQA8+eSTnH322TRp0oS9996bZ599tqTsXmz5v2XLltGnTx/Gjh1bcp1x48Zx7rnnlnzeZZddOPvs\ns3nkkUcqtE1EDGDSvql4fSXyg4nLzf4VcDQuXv0DYFCZSdb9cROxx+FG5+8Dp6vq7DJ9KehMYLAq\nn5faVyRXA7tpRCv2k4uMAz5ByyQmS4MgdPI9YLQaM6ay/Xh2DKzYmkA3nOAfDRwKzMKJ/RvANKMm\n/tCvgMn3MMnqSiipCkSkH3AnUBN4WFVvFpELAFR1THDMlbjVo9uAB1X1rnhGgn4MDFPlw1L7XE6a\nP2lEj0tgyJHAv4CulZ6dAYLyflOBY4M0wx5PSgSrZ3vgJm2Pxv3q/BB4M2gfGjW5+/2dJbzAh0N1\nyEUzDbhalXdK7SuS1sB7GtE9458NiNTA5Y8/DdWPqmSLtYOAvwEHqTGrkh3v8cTDim0AHI4T+yNx\n7p13geKgfWrUbAnPwsrhBT4cqoPAFwN/V+X1UvuKRIAVQFuNaMXxTiLXAy1QvbjK9risky2AU9SY\nbVXtz+MJVtcegRvhHwnsBbyDE3uLS4Wc92sxvMCHQ3UQ+P8C96oyudz+IpkKXKeRkonXeJ20xsUz\nt0S1Sr5PsbYO7j/dJDXm71Xpy+OJhxW7O26y7Aic4O+BE/y3gvZZPo7wvcCHQ3UQ+OeBf6tSLu+M\nFMl9wGyNaOKyeyKvAo+g+mSVbbK2Jc6Heo4a80pV+/N4EhEUKD8iaAa3puRdtgv+J/ngw/cCHw7V\nQeCfAl5QpVyVJimSi4ADNaLnJ+loEHAOqsdmxC5rD8eFyfVQY+Zlok+PJxWCEf5hbBf9fXFRXm8H\n7YMwonS8wIdDdRD4cYBVZWy5/UVyGHCrRrRHko52wcXid0M1cSLnVG2z9k/AH4Beakx+JJHw7HAE\nPvxeOLE/HLf46lOc2L+DC8vMelCAF/hwqA4C/yDwiSr3l9tfJI2B74BGGtHEk54i9wJLUC3KiG3W\nCvAgbhn7SX7S1ZMPWLH1cWGZh+NG+gcDX+PE/h1gqlGzKNPX9QIfDtVB4O8GvlXlX3GPKZIFwOEa\n0f8l6awLLvf3PrgkaFW3z9rawGvAdDUmnOz8Hk8CrNg6wEFAb5zg9wKiKbWn4vz5c6patNwLfDhU\nh5J98bJJxpIss6RD9XNcTHylEpDF7dKYTcApwO/E2jMz1a/HkymMmo1GzTSj5lajZgCwGzAQmI4b\n5U8BllqxL1qxw63Y3r60YXkyWbIv3b5yTT4KfNcE+2O5B5dALGOoMT/jiov8Q6w9IpN9ezyZxqjZ\nZtTMNGrGGDVnGjX7Al2Af+OKoNwBLLNip1uxt1uxJ1uxe4RqdB6QyZJ96faVa3LtorkB2FmVv8Y9\npkhOAc7WiCav4CRSC1fO73hUZyQ7PC1brT0aV2DEqDFfJjve48lXrNh6wG9w7pweQE9gJTAtaNOB\nz2Pj8fPdRZNPJfvS6SsZ2XDRJMsmmWk2Arsm2P8ecL8UiWgkyV+Y6mZE7seN4v+YORNBjXlDrP0L\nMEWs7anG/JTJ/j2eXGHUrMUt6LMAVmwN4FdsF/uLgVZW7Mc4sZ8eiqFpEC3Z16JFC55++mmGDBnC\n3LlzmTt3LgMGVDw2nDx5Mj179kzrWslK9uU7uRb4cvngY9GI/iBFsgGX02NuCv09AHyFyPCgfmvG\nUGPGibV7Ay+JtUeoMWuSnuTx5DlBecMvg/YIgBXbGFe9rQdO8JOSqfoVlfmhEHbJvoYNG/LDDz9k\n9DrZIowRfCIfPLhR/KGkIvCqSxB5CZfJ8vYqW1eem4DWwESxdoAaszEL1/B4QsWoWYGrV+tWc0vy\nQj9henDGjRvHHXfcwfz58wEnwrks2ffLL7/QsGHDrFwv0+TbJCu4n4iHptGnm2x1ueszSlAUZBiw\nBle4u2amr+HxeFIn30r25Tv5KPDREXxqqL6Pqyr1u8qblaB7Y7bgCos3A+4NFkV5PJ4QyLeSfen0\nFQZhCHyyuNxPgQ5SJHXT6HcUcHW2KtuqMRtw8cYH49w2Ho8nBGJL9rVo0YKZM2dWumRfw4YNS0r2\nxU6iDhs2rKRsH7iSfR999BFNmjThr3/9a6mSfcn6Cptch0keD1yqSr+ExxbJB8AVGtF3Eh0X2znw\nGXANqlOqbGxFl7G2GS6395NqjBd6T7Uk38Mkqys7wkrWKOn54d1f4yjgmsqZleJljFmKq885NAij\n9Hg8nrwlXwU+PT+84xlgT0TS/72WBmrMIlzFnguDLJQej8eTl+SzwPcISvmlhuoW4DZgeOVMSx01\n5gecyP+fWPvnbF/P4/F4KkM+TrICzAdqAq3S7P9R4GBEUs1nU2nUmO9wVXn+JNZeme3reTweT7ok\nFXgR6Ssic0TkGxGpcHQsIr8RkS0icnKC7hKuZI0SpClI303j6rTeAvwtrfMqSSDyRwDni7VZ9f97\nPB5PuiQUeBGpiVtI1BdXXWaQiHSo4LhbgJeBRG6VVF00kP6Cpyj3A79GpDLnpo0asxA3kj9TrL3R\nx8l7PJ58IdkIvjswV1Xnqyus8SRwYpzjLgX+AyxN0l86Av8eLhlSerhR/N+AkWmfW0nUmB9xI/nj\ngbvF2ly7vjyejCIivuW4ZYNky/tb4laJRlkIHBJ7gIi0xIn+Ubi0pIkCaNMR+A+ATlIku2pEV6Z4\nTpRHgasQORrVN5IdnAnUmCVi7ZHAi8C/xdqz1ZiMVJvyeHJJZWOuC5UgpXJnXC2Krric+l1wKUo+\nD9oMXL2Kr4yaTSGZmjbJBD6V1Q53Alerqop7DCX446h7JVxZX+TGEYBVVVvhhSO6TopkOnAk8HwK\ndsScrJsRuQEYicib5GjVhhqzUqztCzwNvCDWnuazUHo8+U2QUvn9oAFgxQqwN9vF/iTgBmBvK/Yb\nnNjHtgVVLZUYRUQMzu1b9b4SaZ84P/YIVe0bfL4G2Kaqt8QcM4/tor4bsA74o6q+WKYvBd0J2AzU\nVE3+8JAiuRJooxG9KL3bAkRq4Fa3Xo/qC2mfXwXE2lrAGFz5wd+qMYtzeX2Px5MdrNhdcPORB5Rp\nuwAz2S74M4GZRk2V05hXZSVrMoHfCfgKOBr4Eec2GaSqcascichYYJKqTqzISBE2A/VUSfozR4qk\nC/CcRrRtSndT/qLH49IIH5Cp4twpX9pNtkaAoUA/NebrXF7f4/HkDit2N7aLfafgtTPOzTMTmBW8\nzgRmGzWrU+07awIfdN4P54apCTysqjeLyAUAqjqmzLGpCPwaYA9Vkt5gsNDpR6C3RvTbVG8q9qK4\nQsSvonpH2udnALH2PNyE72lqzNth2ODxeHJP4OZphRP6aOsE7I8LSJkFzA5eZwFfGi3v0s2qwGeK\nGIFfBvxKlZ9TOq9IHgPe04jeV8kL7w+8A3RCdUml+qgiYm0f4HHgajVmbBg2eDye/MCKrQnsixP7\naOuIK6W4BPjAqDktenyhCfyPQHdVFqZ0XpEMBk7ViJ5UhYv/E6iP6vmV7qOKiLX7A5NwE8ZXqzFb\nw7LF4/HkHzHCv5dRY6PbC03g5wF9VEnJ5SJFsjvwNdBMI5X0o4s0AuYA/VH9pFJ9ZACxtiluvcA6\nYLAa80tYtng8nsKgKgIfxoKcdGLh0YguAeZRJv4+LVR/Aa4H7gqia0JBjVkGHIurN/uhWFsYdb88\nHk9BkvcCH/AqThirwiO4uP8/VLGfKqHGbFZj/oxbbWvF2qyUGvR4PJ5CEfhXgOOqdFXVrThxH4lb\nfRsqasy/cfd0q1h7p1hbO2ybPB5P9SIsgU8lZXAs03B1WpsmPTIRqjOB0cDorCV/SMccYz4Bfo2b\nWHlHrN0nXIs8Hk91IgyBTyllcCwa0Y3AG8CADFz/78B+QF64RtSYFbiC3k8D74u1idItezweT8oU\niosGXCbL31f56qobgfOAfyFV/EWQIdQYVWNuxyVt+4dYO0aszZ/S7B6PpyApJIF/CVfGr1mVLVCd\nDjwBPJAPrpooasx7wIFAXeAjsbZbyCZ5PJ4CpmAEXiO6Fpd2IFMujGuAtrjRfN6gxqxSY4YCNwGv\niLXXibXJsn56PB5POQplkjXKU2TCTQNRV80ZwM2I/CojfWYQNWY8cBBwODAtWAnr8Xg8KVMQk6wx\nvAwcKEWyZ0YsUZ2NWwD1BCKVtSlrqDELcKGUY4GpYu1wP5r3eDypUjAuGgCN6AbgBTIbATMG+B64\nOYN9ZoxgAvY+4GBc2ub3xdoDQzbL4/EUAAUl8AGZiaaJ4pLxnAsMRCRz/WYYNWY+bjR/F/CqWHub\nj7TxeDyJKESBfwNoJ0Wyb4bsAdXluJJcdyPSNWP9ZphgNP8YrphAc2C2WHtCyGZ5PJ48pdAmWQky\nSj5LJkfxAKozgD8BExFpktG+M4was1iNORM4G5fqYJJY2y5kszweT55RaJOsUR4GLpAiqZkBe7aj\n+gTwHG7SNe8nM9WYYlxB4HeA98Tam8Xa+iGb5fF48oRCdNGgEf0Q+InMpC4oy9XANvIkX00y1JhN\nasytOKFvCXwl1p4r1mb24efxeAqOghT4gLtwLpXMoroFF6VzEHBdxvvPEmrMj4Hb5mTcpPEnQalA\nj8ezg1LIAv8ssL8UyQEZ6Ks0qmuA44FzEDkn4/1nETXmfeAwoAgYLda+Jtb+JmSzPB5PCBTcJGsU\njegm4D7gkipbFPcCugjoh1vp+tusXCNLBNE2E3GFfP8DPC/WPivWdgzZNI/Hk0NSEngR6Ssic0Tk\nGxEZHmf/YBGZISKfi8i7ItIlQXeZmGSN8gBwmhRlKepF9SvgBOARRPpm5RpZJKgeNQaXHvl9XAWp\nCWJth5BN83g8OSCpwItITeAeoC9uRDhIRMoKxDzgcFXtAtyIE96KyJSLBo3oYmAS2UwYpvoBLo3v\nOESOydp1sogasy6YiG0LfAG8JdaOF2s7h2yax+PJIqmM4LsDc1V1vqpuxq0kPTH2AFWdrqorg4/v\nA3sl6C9jAh9wF3CpFGUxl4xLL3wyMAGRo7J2nSyjxqxWY24G2uGE/nWx9nmxtnvIpnk8niyQisC3\nBBbEfF4YbKuI83BpfSsiIz74KBrRj4AZwLBM9Rn/QjoVOBV4EpGBWb1WlglSEo8C2gCvA8+ItVas\nPV6sDWNexuPxZIFU/jNrqp2JyJG4EL1yfvpg/wjYZxAMby8iJtV+U+Ba4Bopkl0z2Gd5VN/GTbze\nh0he5ZGvDIHr5h7ciP4BXA76mWLtH8XauuFa5/HsmIiIEZER0ValvlyurYQXOxQYoap9g8/XANtU\n9ZYyx3UBJgJ9VXVunH5UVUWEWsBqoKEqm6pifKn+i+RRYIFG9PpM9VnxxaQ98ApOFEeR7EssEMRa\nAY4CLgMOxa0YHq3GfB+qYR7PDkxUOyt1bgoCvxPwFS5V7Y/AB8AgVf0y5pjWwJvAEFV9L5mRIswF\n+qvydWWMjtt/kewNfAJ00oguylS/FV9Q9gT+C3wMDAsKiFQbgtw2FwNn4lIh3A+8qsZsC9Uwj2cH\nI6sCH1ygH3AnUBN4WFVvFpELAFR1jIg8hMvGGB3pbVbV7mX6iBX4l4G7VBP66tNGiuSfwM4a0Ysy\n2W/FF5T6wDhcZseTUV2ck+vmkCC3zSDcHEcj4CHgUTXmx1AN83h2ELIu8JmgjMDfA3ytyl0ZvUaR\n7AbMAXprROdksu+KLyo1gBHAWTiR/zgn180xgfvmN8AfcKkc3gEeAaaoMRlztXk8ntIUosBfBrRR\nzXwuGSmSS3C1Vg/TiG7NdP8VX1hOxa2svRG4u7r45eMRjOp/B5wDdMCFzo4DPlJjqu19ezxhUIgC\n/1vgIlX6Z/w6RVIDVxTkJY3o7ZnuP/HFpS2uMPgC4FxUV+T0+iEg1rYBhuB89duACcATasxXoRrm\n8VQTClHg9wdeVKV9Vq5VJG1wC64Oy5mrpuTiUgcYBZwC/BHVV3J6/ZCIceEMwhVjWQQ8AzyjxnwT\npm0eTyFTiAJfB1gJ1FdlS1auVyTDcH7xXjl11ZQYIMfgJiRfB65g+0rfak+Qi743cBruQbcIV0jl\nOeAL78bxeFKn4ATefWY+cJQq87JyPeeqeQ14UyM6MhvXSG6ENABuA/rjYsufq86++XgEYt8TF2V1\nEs6NMwl4EXhHjdkconkeT95TqAL/OnCrKq9m7ZpFshfwHnCRRvTFbF0nuSFyBHAv8ANwKaoZi/8v\nJAI3TldcJa4BuCyXr+HWE7ysxvwUonkeT15SqAJ/P/C5KqOzet0i+Q0uN04fjehn2bxWYkOkFnAp\nLq3CWOBmVJeHZk8eINa2wGUp7Qf0Ab7DCf5rwFQ1Zn2I5nk8eUGhCvyVwJ6qXJ71axfJaThXySE5\nWeWa0BjZA4jgfNO34UIqd3ghE2t3wmUu7QMci6sx+wFuhfSbuBBM787x7HAUqsCfBJyjygk5uX6R\nRHBl+PpoJA8mPEX2B0YCh+CE/kFU14VrVP4g1u6KKz14FC5Nxr44d9tbwNvAh2rMhvAs9HhyQ6EK\n/AHAU6rkpIycFIngCpd0B/pqRJfl4rpJEfk1rrh3T+AOYAyqv4RrVP4h1jbBCf7hwBG4BVafAe8C\n04Hpaky4v848nixQqAJfD/gZFyqZkzDGQORH4aJa+oTurolFpDNwDc4fPR64C1UfP14BwWra7rhw\nzEODthK3/uGDoH2qxqwNzUiPJwMUpMC7bfwA9FAlZ+loA5G/Drf6sq9G9H+5unZKiLQELgLOBz4C\nHgQm4appeSogKFTSHif6vwleD8CVk/wYl2n0E2CGGrMqLDs9nnQpZIF/CyhS5c2cGBF77SK5GLgB\n+INGdFKur58Ukbq4ClJ/wAnXOOBxVD8P1a4CQqytDXQGDgragTjR/wnn3vk8ps33qZA9+UghC/zD\nwPuqCYt0Z8+mIumByx3zBPBXjWhWVtVWGTchezYuidpKnAvnP8QprOJJTBCt0x4XpRNtXYHGwJfA\nTGB20L7EC78nZApZ4K8BGqtyVU6MiEOQYvhx3H/wCzWin4ZlS1JcauJeOKE/CViCq6L1IvAZql6I\nKkkQtdMJN+LvAHQMWlPgG1zRm6+Ar6NNjan2yeQ84VPIAv87YJAqJ+fEiAoI0hqcA/wdN5q/QSOa\n335akZq4icWTgd8CDYGXcatCi1FdGqJ11YZgMrc9sD/wK9zq2/bB6xbgW2Bu8DoP+F/w+oMak/sc\nSJ5qRyELfDfgMVW65MSIJASj+WiUza3AAxopkNh0l6q4H25l6GE4oXkTV5jjXVSXhGhdtSNIu7Ab\nrmB5O6AtLla/TdB2AxYC83ErdL/DVTz7HpdOeoFfqetJhUIW+Ia4Ca/6quRNEi4pKhWb/k9gTF4s\njkoVlxbhINwCod5AD2AxLl78w6DNqG51ZPMJsbYO0Bon+q2BvWNeWwEtgTW4h0C0/YCre/wj7v/F\nT8BSPwewY1OwAu+2sxjoqcq3OTEkDaRIDsDFpvcHnsel/31XIwWWEdK5czrhXDrRMML2OJ/yZ8Cn\nwBfALGDJjpbxMgyCsM5mOKHfK2h7lml7ALsCS3EplxfhHtTRtiRoS4PXn306h+pHoQv833CC0z+f\nRvGxSJE0A4YCfwRq4fKavwBMDyXXfCZwYZidcKGD3XCTi51x6Xxn42rbRicWvwX+h6pPDZBjglDP\n5kFrEbTmwO5Ba457UDTDTQivxQn+z0FbFvO6PGjLgBVBWw6s9jn685esCryI9AXuBGoCD6nqLXGO\nuQvn/10HnK1aPhIlgcDXwi03f0yVeytzE7kiWCR1IDAwaHsAxYAN2pyCG93HIiI4AemAm1CMtrY4\n98JSnG9/ftCi/uSoi2GVH/2HR/CrYFdKC35T3HxAU6BJ0JriosYaB593wYXf/oIT/V+CtjJOWxXT\nVse8rvGTytkhawIv7qf9V8AxOP/gh8AgVf0y5pj+wCWq2l9EDgH+paqHpmOkCO1xIn+4Kl/GOyYf\nkSLZGzAxrRFu1eTHOLfHl8DXGimdLVJEjKraHJpaddzfQitgn5jWOti2V/AqbPchR90Ii9juRoi2\nZVOm58MAAAkqSURBVMAvqG4tyO8iS4T1XQRrAxqxXfR3DVqjmPe74iK1GsZ8bhC0hkA9YD1O7Ffj\n5heibW3Ma7y2LuZ1HbCe4cMP4JZbbNDnemDTjvoroyoCv1OS/d2Buao6P7jQk8CJUEqETwAeA1DV\n90WkkYg0V9XFqRqhytci/BUYL8KhqmxK5ybCQiP6He7eHwOQItkdN7l5MG4VagegjRTJT2wPofsf\nbTg4CM2MTqatyvuRv+pWto/c4+MqWEX9x7GuhENxo8jYkWVDRFZd5c6bx/aRY3Sk+AulR4qxwlFa\nHLRA3WTlMbhfgjlFjdnCdpdOpQh+PdRlu+jXA+rHvK9X5v2ewesuwXn1glf3vk2bPYCNwf5dgJpi\n7Qa2C/6GoMW+j7aNMa+xLXbbppjXTRV83gRsTvC6Jd8fOslG8KcCx6nqH4PPQ4BDVPXSmGMmATer\n6rTg8+vAcFX9uExfCZ9CIghuIrNl8Ppf4FNVCjqCQIqkFtvD5/YF9uVF+nECy9g+kVYb959rKdt9\noyvY/pM4Km6xI571Ma3sH3L0j3Br3j443C+CRvtAZD78m/Kjx+iIMTpCrM92wajPdqGoi7vX6Chw\nfZlW9j98vP/4if4zl21bKmhbY17Lvo+2bWU+a6xLS0RGqOqIyn+p1Yey30XwK2NnnNhHX3cB6gSf\nd47zuU6CVrvM++jnWnE+1yrzvnbwWhP371z27yPZa/T9VuL/HS1TY/70/+3dbYgdVx3H8e9v5u5u\nNommVASbNmIQA42oGFtMC9IqRYqKigqmL7T4oohYrL7wIXlR+8YXgo9YqqJtkYr2RQuyQmubaquC\noC2NmD6kD6DQNSZqijZpS7L3np8vzpndu5u9m6b17iYz/w9c5szM3Tsz/73z39k5c84ZisXYruBf\nanJYuvHTTio2Lg2fLmehR8XNEs+ykOiaoAzKNprX0m2eQUltuV35zCQPf/8oTSXmxLGKV89O8qqD\nU2z49zqmj7ye6SNvZOq5HlPP9Zg8ll8TL9ZMvJCn9fGK3vGa+nhNPVdRzVXUJyrquQoNKqq+qJJ0\n/YRxnUi1cW1cOZerhfmFF3mqXEbGAgSWl0zLwTXl4XXknwXmvxqLvp8y11yc3/fg7AZdvGXX0Lqh\n0GmF36MAnpf9/LpBYn0/aePcYN30IE2v7ydN95PWDxJTfWvdIGl9PzGVktaV+cmUmEzW5MBMpaSJ\nZCaTNTVI9JI1mcxEsiZSYiJZPef52tBLTdnUNr1kTdhUCWo3yxeXK5vKqM5TapsKGFQiIZJgj+CF\nXn19EiSJBCSB83q7LDcL01zGRvMhtiCV+fmTpHlPWZ+Xa9GvZclyD397veg9WmZZU1687qTySZ87\ntANDxU9umKx/e96m3c38/aM/bySflJZO/XOnkTgGSRoMqpp+r677da8a1PVUv67p1z0Gda1BXdO8\nmuWpqujXtQa9XB5UNYOqYvi9JxIDhhL8K3GqK/idwA22ryzzu4E0XNEq6QfAA7ZvL/MHgMuW3qKR\nVjpZQwghjDKuK/iHgDdJegP5fvHHgauWvGcGuBa4vfxB+M9y999f7g6GEEJ4eVZM8Lb7kq4F7iHf\nb7rZ9uOSPl3W/9D2XZLeJ+lp8j3QT419r0MIIZzSqjV0CiGEsLqqcW9A0pWSDkh6StKXx729M4mk\nLZLul/SopEckfa4sP1fSXklPSrpX0jlrva+rRVItaV95+qqzsSiPE98h6XFJj0l6Z4djsbucI/sl\n/UzSVFdiIekWSYcl7R9aNvLYS6yeKjn1vaf6/LEm+NJQ6kZyD4fbgaskXTjObZ5h5oAv2G76gfls\nOf6vAHttbwN+Xea74jpyVwjNv45djcV3gbtsX0gedOQAHYxFqd+7Bthh+y3kW8G76E4sbiXnx2HL\nHruk7eR60O3lZ25SHiNipHFfwc83lHIeU7RpKNUJtg/Z/nMpHyM3EDufocZhZfrhtdnD1SXpAnLH\nbT9m4aG4zsVC0ibgXbZvgVzXZfu/dDAWLDz+vF5Sj9yu4SAdiYXt35PbvAwbdewfAn5ue640Pn2a\nnGNHGneCP5/cV0ljtizrnHKl8nbgj8BwS9/D5BafXfBt4IuwqPFaF2OxFfiXpFslPSzpR5I20MFY\n2H4W+Ca5X6OD5Kfw9tLBWAwZdeybyTm0ccp8Ou4EHzW4gKSNwJ3AdbaPDq9zruVufZwkfQD4Z+mI\nbtlHZrsSC/LTazuAm2zvID99tugWRFdioTxQzefJfRttBjaWFvPzuhKL5byEY18xLuNO8H8nd0LV\n2MLiv0Ctpzz4xp3AbbZ/URYflvS6sv48cmdcbXcp8EFJfyUPi/geSbfRzVjMArO2Hyzzd5AT/qEO\nxuIi4A+2j9juk8cYvoRuxqIx6pxYmk8vKMtGGneCn28oJWmSXEEwM+ZtnjGUu9+9GXjM9neGVs0A\nV5fy1eS+d1rN9h7bW2xvJVei/cb2J+hmLA4Bz0jaVhZdQR5s5Zd0LBbkyuWdkqbL+XIFuRK+i7Fo\njDonZoBdkiYlbSWPC/ynFT/J9lhf5H5lniBXCOwe9/bOpBd5uLzEwqhJ+8i13+cC9wFPAvcC56z1\nvq5yXC4DZkq5k7EA3kYzdGK+at3U4Vh8ifwHbj+5UnGiK7Eg/zd7kNy53TPkhqIjjx3YU3LpAXJH\nkCt+fjR0CiGElhp7Q6cQQghrIxJ8CCG0VCT4EEJoqUjwIYTQUpHgQwihpSLBhxBCS0WCD60j6TWl\nS+J9kv4habaUj0q6ca33L4TVEs/Bh1aT9FXgqO1vrfW+hLDa4go+dIEAJF0+NNDIDZJ+Iul3kv4m\n6SOSviHpL5LuLl3XIukdkh6Q9JCkXzV9hIRwNogEH7psK/Bucv/bPyUPsvBW4EXg/aWjuO8BH7V9\nEXlwhq+t1c6GcLpWHHQ7hBYzcLftgaRHgMr2PWXdfnL3tduANwP35X6wqMn9hoRwVogEH7rsBIDt\nJGluaHkinxsCHrV96VrsXAivVNyiCV217KAjSzwBvFbSTsh9+5dxMUM4K0SCD13goelyZTh5ZBw7\njyP8MeDrkpouny8Z546G8P8Uj0mGEEJLxRV8CCG0VCT4EEJoqUjwIYTQUpHgQwihpSLBhxBCS0WC\nDyGElooEH0IILRUJPoQQWup/lAtzMWJ4g58AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f486021e978>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt \n",
    "from scipy.signal import lfilter\n",
    "d=np.zeros(100); d[0]=1 #dirac impulse\n",
    "alist=[0.2, 0.8, 0.9, 0.95, 0.99, 0.999, 1.001, 1.01]\n",
    "for a in alist:\n",
    "    h=lfilter([1], [1, -a],d)\n",
    "    _=plt.plot(h, label=\"a={}\".format(a))\n",
    "plt.ylim([0,1.5])\n",
    "plt.xlabel('Time')\n",
    "_=plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Third example:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example shows that environments like itemize or enumerate are also available. As already indicated, this is useful for copying text from a TeX file. Following the same idea, text formating commands `\\textit`, `\\textbf`, `\\underline`, etc are also available."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{listing}\n",
    "The following \\textit{environments} are available:\n",
    "\\begin{itemize}\n",
    "    \\item \\textbf{Theorems and likes}\n",
    "    \\begin{enumerate}\n",
    "        \\item theorem,\n",
    "        \\item lemma,\n",
    "        \\item corollary\n",
    "        \\item ...\n",
    "    \\end{enumerate}\n",
    "    \\item \\textbf{exercises}\n",
    "    \\begin{enumerate}\n",
    "        \\item problem,\n",
    "        \\item example,\n",
    "        \\item exercise\n",
    "    \\end{enumerate}\n",
    "\\end{itemize}\n",
    "\\end{listing}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "which gives... \n",
    "\n",
    "The following \\textit{environments} are available:\n",
    "\\begin{itemize}\n",
    "\\item \\textbf{Theorems and likes}\n",
    "\\begin{enumerate}\n",
    "\\item theorem,\n",
    "\\item lemma,\n",
    "\\item corollary\n",
    "\\item ...\n",
    "\\end{enumerate}\n",
    "\\item \\textbf{exercises}\n",
    "\\begin{enumerate}\n",
    "\\item problem,\n",
    "\\item example,\n",
    "\\item exercise\n",
    "\\end{enumerate}\n",
    "\\end{itemize}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# (post)-Converters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The extension works in the live-notebook. Since it relies on a bunch of javascript, the notebook does not render as is in very nice services such as `nbviewer` or `github` viewer. Similarly, `nbconvert` does not know of the LaTeX constructs which are used and therefore do not fully convert notebooks making use of this extension. Therefore, it is necessary to add a post conversion step to conversions provided by `nbconvert`. Though an interface exists for adding post-converters to nbconvert, this (first) author was too lazy and not enough strong to implement the post conversion along these lines. What has be done are simple `bash` and `python` scripts that perform this conversion."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Installation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copy the scripts files to a directory in your search path, or launch the scripts with the complete path. The two main scripts are `ipynb_thms_to_html` (conversion to html, of course:) and `ipynb_thms_to_latex`  (conversion to LaTeX!)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conversion to html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Requirements**: You will need `perl`, `nodejs`, and `ipython3` (the script calls `ipython3`; if your interpreter is `ipython`, edit the script and replace the different occurences).\n",
    "\n",
    "**Configuration**: \n",
    "\n",
    "- If you still use IPython 3.x (not Jupyter), edit `ipynb_thms_to_html` and set the variable `stillIPython3=true`. IPython 3.x will also have to change the `nbextensionsDir` to `/.ipython/nbextensions` in the file `post_html_thms.js`. \n",
    "- Finally **all users** should check the path for their `marked.js` library as indicated in `post_html_thms.js`. On Debian, it is located \n",
    "`/usr/share/jupyter/notebook/static/components/marked/lib/marked.js`. It shoud be similar for other flavors of linux\n",
    "(may be `/usr/local/share/...`). \n",
    "You may locate the right library by issuing `locate -eb0P marked.js | xargs -r0 ls -ald` on the command line. Please update the variable `marked` for your system in `post_html_thms.js`. \n",
    "\n",
    "The conversion to html is done by something like \n",
    "\n",
    "        [path/]ipynb_thms_to_html filename\n",
    "or a list of files such as\n",
    "\n",
    "        [path/]ipynb_thms_to_html *.ipynb\n",
    "In turn, this script makes somes substitutions using `perl`, and then uses the `nodesj` javascript interpreter to make the very same substitutions that are done in the live notebook.\n",
    "The conversion uses the template `thmsInNb.tpl` (located in the script directory). It also copies the css `latex_env.css` in the directory of the output html file (it must be copied with html files in the case of web upload)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conversion to LaTeX"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Requirements**: You will need `perl` and `ipython3`. \n",
    "\n",
    "The conversion to LaTeX is done by something like \n",
    "\n",
    "        [path/]ipynb_thms_to_latex filename\n",
    "or a list of files such as\n",
    "\n",
    "        [path/]ipynb_thms_to_latex *.ipynb\n",
    "        \n",
    "The script makes some substitutions and cleaning in markdown cells, then calls the legacy `nbconvert`. Afterward, it runs through the LaTeX environments and converts their contents (which can contain markdown markup) to  LaTeX. Note that the script contains a list of the LaTeX environments to process. In the case of the addition of an environment in the main javascript (`thmsInNb.js`), this list must also be updated. \n",
    "\n",
    "Finally, the script removes the header and footer in the LaTeX file. This is a personnal choice, and the corresponding line can be safely commented. \n",
    "\n",
    "\\begin{example}\n",
    "As for an example, the present document has been converted using\n",
    "    \n",
    "    ipynb_thms_to_latex latex_env_doc.ipynb\n",
    "    \n",
    "Then the resulting file (without header/footer) has been included in the main file `documentation.tex`, where some LaTeX definitions of environments are done (namely listings, colors, etc) and compiled using \n",
    "    \n",
    "    xelatex documentation\n",
    "    \n",
    "The output can be consulted [here](documentation.pdf).    \n",
    "\\end{example}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Disclaimer, sources and thanks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a not-quick but certainly dirty hack. I am a complete beginner in javascript and of course there are obviously a large amount of possible improvements of the code, in cleaning, factorizing, etc! Language also needs improvement. \n",
    "\n",
    "**Contributions will be welcome and deeply appreciated.** \n",
    "\n",
    "Originally, I used a piece of code from the nice online markdown editor `stackedit` [https://github.com/benweet/stackedit/issues/187](https://github.com/benweet/stackedit/issues/187), where the authors also considered the problem of incorporating LaTeX markup in their markdown. I also used examples and code from [https://github.com/ipython-contrib/jupyter_contrib_nbextensions](https://github.com/ipython-contrib/jupyter_contrib_nbextensions). \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# References\n",
    "\n",
    "(<a id=\"cit-PER-GRA:2007\" href=\"#call-PER-GRA:2007\">P\\'erez and Granger, 2007</a>) P\\'erez Fernando and Granger Brian E., ``_IPython: a System for Interactive Scientific Computing_'', Computing in Science and Engineering, vol. 9, number 3, pp. 21--29, May 2007.  [online](http://ipython.org)\n",
    "\n",
    "(<a id=\"cit-mckinney2012python\" href=\"#call-mckinney2012python\">McKinney, 2012</a>) Wes McKinney, ``_Python for data analysis: Data wrangling with Pandas, NumPy, and IPython_'',  2012.\n",
    "\n",
    "(<a id=\"cit-rossant2013learning\" href=\"#call-rossant2013learning\">Rossant, 2013</a>) Cyrille Rossant, ``_Learning IPython for interactive computing and data visualization_'',  2013.\n",
    "\n",
    "(<a id=\"cit-shen2014interactive\" href=\"#call-shen2014interactive\">Shen, 2014</a>) Shen Helen, ``_Interactive notebooks: Sharing the code_'', Nature, vol. 515, number 7525, pp. 151--152,  2014.\n",
    "\n"
   ]
  }
 ],
 "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.4.3+"
  },
  "latex_envs": {
   "bibliofile": " biblio_ipython.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 0
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
