{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "# How can we break out the next step proposal?\n",
    "\n",
    "- We want a separate module for `next_step_proposals`, living in a separate file\n",
    "    -  a Gaussian one (it's the one currently in the Walker code), called `gaussian_next_step_proposal`\n",
    "    -  a square one (you can find an example below), called `square_next_step_proposal`\n",
    "- As discussed, this can work by passing the fuction for a `next_step_proposal` as well as the arguments for that function to the Walker constructor.\n",
    "\n",
    "# 1. Your Dream Code\n",
    "The following is our current code. Modify it as though you had already written the module as in the previous exercises.\n",
    "-  Modify the imports\n",
    "-  Modify the Walker instantiation to take a `next_step_proposal` function and a `next_step_proposal_arguments` dictionary as an input\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true,
    "execution": {
     "iopub.execute_input": "2024-08-05T15:58:32.267Z",
     "iopub.status.busy": "2024-08-05T15:58:32.261Z",
     "iopub.status.idle": "2024-08-05T15:58:32.274Z",
     "shell.execute_reply": "2024-08-05T15:58:32.278Z"
    },
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "from context_maps import flat_context_map, hills_context_map, labyrinth_context_map\n",
    "from plotting import plot_trajectory, plot_trajectory_hexbin\n",
    "from walker import Walker"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-08-05T15:58:32.842Z",
     "iopub.status.busy": "2024-08-05T15:58:32.840Z",
     "iopub.status.idle": "2024-08-05T15:58:33.445Z",
     "shell.execute_reply": "2024-08-05T15:58:33.449Z"
    },
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 118056 characters]",
      "text/plain": [
       "<Figure size 480x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "context_map = hills_context_map(size=200)\n",
    "walker = Walker(sigma_i=3, sigma_j=4, context_map=context_map)\n",
    "\n",
    "# Sample a next step 1000 times\n",
    "i, j = 100, 50\n",
    "trajectory = []\n",
    "for _ in range(1000):\n",
    "    i, j = walker.sample_next_step(i, j)\n",
    "    trajectory.append((i, j))\n",
    "    \n",
    "plot_trajectory(trajectory, walker.context_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# What the square next step proposal could look like (info)\n",
    "\n",
    "This is an example of what the square next step proposal function could look like.\n",
    "\n",
    "Notice that there are 4 arguments. `current_i`, `current_j`, and `size` are known to the Walker, and can be passed quite easily. `width` is a parameter that is dependent on this kind of next step proposal, and will be passed in the `next_step_proposal_arguments` dictionary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-08-05T15:54:14.653Z",
     "iopub.status.busy": "2024-08-05T15:54:14.646Z",
     "iopub.status.idle": "2024-08-05T15:54:14.749Z",
     "shell.execute_reply": "2024-08-05T15:54:14.762Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.colorbar.Colorbar at 0x1276a54b0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 22156 characters]",
      "text/plain": [
       "<Figure size 480x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def square_next_step_proposal(current_i, current_j, size, width):\n",
    "    \"\"\" Square next step proposal. \"\"\"\n",
    "    grid_ii, grid_jj = np.mgrid[0:size, 0:size]\n",
    "    inside_mask = (np.abs(grid_ii - current_i) <= width // 2) & (np.abs(grid_jj - current_j) <= width // 2)\n",
    "    p_next_step = inside_mask / inside_mask.sum()\n",
    "    return p_next_step\n",
    "\n",
    "p = square_next_step_proposal(100, 50, 200, 14)\n",
    "plt.matshow(p)\n",
    "plt.colorbar()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "# 2. Implement the changes in the code (optional)\n",
    "1. In a new module `next_step_proposals`, write two functions for two different next step proposals: a Gaussian one (it's the one currently in the Walker code) and a square one (you can find an example below)\n",
    "2. Modify the constructor of Walker to take a `next_step_proposal` function and a `next_step_proposal_arguments` dictionary as an input\n",
    "3. See if the dream code you wrote works with your implementation! (Don't forget to restart the kernel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-08-20T06:27:55.307Z",
     "iopub.status.busy": "2022-08-20T06:27:55.303Z",
     "iopub.status.idle": "2022-08-20T06:27:56.162Z",
     "shell.execute_reply": "2022-08-20T06:27:56.165Z"
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.11.3"
  },
  "nteract": {
   "version": "0.28.0"
  },
  "toc": {
   "nav_menu": {
    "height": "12px",
    "width": "252px"
   },
   "navigate_menu": true,
   "number_sections": true,
   "sideBar": true,
   "threshold": 4,
   "toc_cell": false,
   "toc_section_display": "block",
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
