{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Parallel computing\n",
    "\n",
    "**We show how to use multiprocessing to compute profile likelihood.\n",
    "The process will be divided per parameter.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-01-27T04:21:01.153401Z",
     "start_time": "2022-01-27T04:21:01.139090Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from profile_likelihood import profile_likelihood\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define the model\n",
    "\n",
    "The model is defined as the sum of trigonometric functions, in the form of\n",
    "$$ f\\left(t; \\vec{\\theta}\\right) = \\sin(\\theta_0 t) + \\cos(\\theta_1 t), $$\n",
    "where we sample at 3 time points $t = [1.0, 1.2, 2.0]^T$.\n",
    "The default parameters are chosen to be $\\vec{\\theta} = [1.0, 2.5]^T$.\n",
    "The data is set to be the predictions of the model at the default parameters and the standard deviation is chosen to be 30% of the data.\n",
    "The implementation of this model is given in `model_trigonometric.py`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-01-27T04:21:01.165391Z",
     "start_time": "2022-01-27T04:21:01.158037Z"
    }
   },
   "outputs": [],
   "source": [
    "import model_trigonometric as model\n",
    "import manifold\n",
    "\n",
    "# Define the likelihood object\n",
    "likelihood = profile_likelihood(model.residuals, model.nparams, model.npred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comparison between serial and parallel computing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-01-27T04:21:10.912327Z",
     "start_time": "2022-01-27T04:21:01.169761Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 9.74 s, sys: 0 ns, total: 9.74 s\n",
      "Wall time: 9.73 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "# Serial computing\n",
    "results_all = likelihood.compute(model.best_fit, dt=0.01)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The parallele computing in this computation is as easy as specifying the number of processes to use.\n",
    "Ideally, the number of processes requested would be equal to the number of model's parameters.\n",
    "If fewer processes requested, then there will be queueing. If more processes requested, there will be redundant processes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-01-27T04:21:16.322394Z",
     "start_time": "2022-01-27T04:21:10.915621Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Task for parameter1 is done by Process-3\n",
      "Task for parameter0 is done by Process-2\n",
      "CPU times: user 34.3 ms, sys: 11.2 ms, total: 45.4 ms\n",
      "Wall time: 5.4 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "# Parallel computing\n",
    "results_all = likelihood.compute(model.best_fit, dt=0.01, processes=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, the parallel processing roughly takes close to, though still larger than, 50%. The deviation from 50% is due to internal structure."
   ]
  }
 ],
 "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.9"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
