{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "# 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": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "# 2. Implement the changes in the code\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": "markdown",
   "metadata": {},
   "source": [
    "# What the square next step proposal could look like\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": "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
}
