1079 lines
145 KiB
Plaintext
1079 lines
145 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "7711bd97",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Exercise sheet\n",
|
|
"\n",
|
|
"Some general remarks about the exercises:\n",
|
|
"* For your convenience functions from the lecture are included below. Feel free to reuse them without copying to the exercise solution box.\n",
|
|
"* For each part of the exercise a solution box has been added, but you may insert additional boxes. Do not hesitate to add Markdown boxes for textual or LaTeX answers (via `Cell > Cell Type > Markdown`). But make sure to replace any part that says `YOUR CODE HERE` or `YOUR ANSWER HERE` and remove the `raise NotImplementedError()`.\n",
|
|
"* Please make your code readable by humans (and not just by the Python interpreter): choose informative function and variable names and use consistent formatting. Feel free to check the [PEP 8 Style Guide for Python](https://www.python.org/dev/peps/pep-0008/) for the widely adopted coding conventions or [this guide for explanation](https://realpython.com/python-pep8/).\n",
|
|
"* Make sure that the full notebook runs without errors before submitting your work. This you can do by selecting `Kernel > Restart & Run All` in the jupyter menu.\n",
|
|
"* For some exercises test cases have been provided in a separate cell in the form of `assert` statements. When run, a successful test will give no output, whereas a failed test will display an error message.\n",
|
|
"* Each sheet has 100 points worth of exercises. Note that only the grades of sheets number 2, 4, 6, 8 count towards the course examination. Submitting sheets 1, 3, 5, 7 & 9 is voluntary and their grades are just for feedback.\n",
|
|
"\n",
|
|
"Please fill in your name here:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "e39c230e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"NAME = \"Kees van Kempen\"\n",
|
|
"NAMES_OF_COLLABORATORS = \"\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2e7caa84",
|
|
"metadata": {},
|
|
"source": [
|
|
"---"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0c4606a8",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "1ba146ece4effd3e8dcf33fe63ec69dc",
|
|
"grade": false,
|
|
"grade_id": "cell-455926422ebe4f85",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"**Exercise sheet 4**\n",
|
|
"\n",
|
|
"Code from the lectures:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "6d3bb610",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "ac562d84531ae19e1d920c10a8861b8e",
|
|
"grade": false,
|
|
"grade_id": "cell-6b2d0465c2abaaa6",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import matplotlib.pylab as plt\n",
|
|
"import networkx as nx\n",
|
|
"\n",
|
|
"rng = np.random.default_rng()\n",
|
|
"%matplotlib inline\n",
|
|
"\n",
|
|
"def draw_transition_graph(P):\n",
|
|
" # construct a directed graph directly from the matrix\n",
|
|
" graph = nx.DiGraph(P) \n",
|
|
" # draw it in such a way that edges in both directions are visible and have appropriate width\n",
|
|
" nx.draw_networkx(graph,connectionstyle='arc3, rad = 0.15',width=[6*P[u,v] for u,v in graph.edges()])\n",
|
|
"\n",
|
|
"def sample_next(P,current):\n",
|
|
" return rng.choice(len(P),p=P[current])\n",
|
|
"\n",
|
|
"def sample_chain(P,start,n):\n",
|
|
" chain = [start]\n",
|
|
" for _ in range(n):\n",
|
|
" chain.append(sample_next(P,chain[-1]))\n",
|
|
" return chain\n",
|
|
"\n",
|
|
"def stationary_distributions(P):\n",
|
|
" eigenvalues, eigenvectors = np.linalg.eig(np.transpose(P))\n",
|
|
" # make list of normalized eigenvectors for which the eigenvalue is very close to 1\n",
|
|
" return [eigenvectors[:,i]/np.sum(eigenvectors[:,i]) for i in range(len(eigenvalues)) \n",
|
|
" if np.abs(eigenvalues[i]-1) < 1e-10]\n",
|
|
"\n",
|
|
"def markov_sample_mean(P,start,function,n):\n",
|
|
" total = 0\n",
|
|
" state = start\n",
|
|
" for _ in range(n):\n",
|
|
" state = sample_next(P,state)\n",
|
|
" total += function[state]\n",
|
|
" return total/n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2f7814d8",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Markov Chain on a graph\n",
|
|
"\n",
|
|
"**(50 points)**\n",
|
|
"\n",
|
|
"The goal of this exercise is to use Metropolis-Hastings to sample a uniform vertex in a (finite, undirected) connected graph $G$. More precisely, the state space $\\Gamma = \\{0,\\ldots,n-1\\}$ is the set of vertices of a graph and the desired probability mass function is $\\pi(x) = 1/n$ for $x\\in\\Gamma$. The set of edges is denoted $E = \\{ \\{x_1,y_1\\}, \\ldots,\\{x_k,y_k\\}\\}$, $x_i,y_i\\in\\Gamma$, and we assume that there are no edges connecting a vertex with itself ($x_i\\neq y_i$) and there is at most one edge between any pair of vertices. The **neighbors** of a vertex $x$ are the vertices $y\\neq x$ such that $\\{x,y\\}\\in E$. The **degree** $d_x$ of a vertex $x$ is its number of neighbours. An example is the following graph:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"id": "071e5617",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"edges = [(0,1),(1,2),(0,3),(1,4),(2,5),(3,4),(4,5),(3,6),(4,7),(5,8),(6,7),(7,8),(5,7),(0,4)]\n",
|
|
"example_graph = nx.Graph(edges)\n",
|
|
"nx.draw(example_graph,with_labels=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "952c97cd",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "a9ae9f2c0eb7e99b85fd90ae657a9202",
|
|
"grade": false,
|
|
"grade_id": "cell-a8413209ddb70ab0",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"A natural proposal transition matrix is $Q(x \\to y) = \\frac{1}{d_x} \\mathbf{1}_{\\{\\{x,y\\}\\in E\\}}$. In other words, when at $x$ the proposed next state is chosen uniformly among its neighbors.\n",
|
|
"\n",
|
|
"__(a)__ Write a function `sample_proposal` that, given a (networkX) graph and node $x$, samples $y$ according to transition matrix $Q(x \\to y)$. _Hint_: a useful Graph member function is [`neighbors`](https://networkx.org/documentation/stable/reference/classes/generated/networkx.Graph.neighbors.html). **(10 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "449da919",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "db0642dd7c9f53225d13fb9674c89a56",
|
|
"grade": false,
|
|
"grade_id": "cell-df840ef2dee49b9f",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def sample_proposal(graph,x):\n",
|
|
" '''Pick a random node y from the neighbors of x in graph with uniform\n",
|
|
" probability, according to Q.'''\n",
|
|
" y_list = np.fromiter(graph.neighbors(x), dtype=int)\n",
|
|
" return rng.choice(y_list)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "604ce3f4",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "690a774380e6a4383ccb5da2dee8a737",
|
|
"grade": true,
|
|
"grade_id": "cell-c70fec7da167b7be",
|
|
"locked": true,
|
|
"points": 10,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from nose.tools import assert_almost_equal\n",
|
|
"assert sample_proposal(nx.Graph([(0,1)]),0)==1\n",
|
|
"assert_almost_equal([sample_proposal(example_graph,3) for _ in range(1000)].count(4),333,delta=50)\n",
|
|
"assert_almost_equal([sample_proposal(example_graph,8) for _ in range(1000)].count(5),500,delta=60)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f7a2e658",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "99c1e08eed2976f4625452d9eed6a5d5",
|
|
"grade": false,
|
|
"grade_id": "cell-4c74e7dae57e50e3",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"__(b)__ Let us consider the Markov chain corresponding to the transition matrix $Q(x \\to y)$. Produce a histogram of the states visited in the first ~20000 steps. Compare this to the exact stationary distribution found by the function `stationary_distributions` from the lecture applied to the transition matrix $Q$. _Hint_: another useful Graph member function is [`degree`](https://networkx.org/documentation/stable/reference/classes/generated/networkx.Graph.degree.html). **(15 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"id": "f52fcbd5",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "44377fd9fa8cd0c3bc78ab03753db1ce",
|
|
"grade": false,
|
|
"grade_id": "cell-ca4f5c3685b72c8a",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAY4AAAEICAYAAABI7RO5AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAggklEQVR4nO3de5gV1Znv8e9PLhINRsVOglwCyWlBRGhJR0WMdMZjvEbU6ETiheTJiGQkxkwkosk4xnGe48khxjhDIMQwEJN4GdSR5HC8RoJJ1HAJo1xCREVtQUGMeMEL4Hv+2NXMZrN7d1XT1b2hf5/n2c/ee9Vaq94q2/1Sq6pWKSIwMzNLa6+ODsDMzHYvThxmZpaJE4eZmWXixGFmZpk4cZiZWSZdOzqA9nDQQQfFgAEDOjoMM7PdyuLFi1+JiJrS8k6ROAYMGMCiRYs6Ogwzs92KpOfKlXuoyszMMnHiMDOzTJw4zMwsk05xjsPMdl9btmyhsbGRd955p6ND2WP16NGDvn370q1bt1T1nTjMrKo1NjbSs2dPBgwYgKSODmePExFs3LiRxsZGBg4cmKqNh6rMrKq988479OrVy0kjJ5Lo1atXpiM6Jw4zq3pOGvnKun+dOMzMLBMnDjOzCl577TV+9KMfATB//nxOO+20dl3/rFmzWLt27fbvf/d3f8eKFSsy99OWsfvkuFkbuWvVurLlV1/w+Vb1d+0tdza77KxBvVvVp2XXlDj+/u//Prd1bN26la5dy/8cz5o1i6FDh3LwwQcDcPPNN+cWR1o+4jAzq2Dy5Mk8/fTT1NXVMWnSJN58803OPvtsBg8ezHnnnUfTU1QXL17M6NGj+eQnP8mJJ57IunWFf0gsXbqUo48+mmHDhnHmmWfy17/+FYCGhgauuuoqRo8ezQ9/+MOy7efMmcOiRYs477zzqKur4+2336ahoWH7FEr33nsvI0aMYPjw4Rx//PEA/PGPf+SYY47hiCOO4JhjjmHVqlVtvk9yPeKQdBLwQ6ALcHNEXF+yfDDw78AI4NsRMSUpHwTcXlT148DVEXGjpGuAi4ANybKrImJentthtisqHTlY9bv++utZtmwZS5cuZf78+YwZM4bly5dz8MEHM2rUKH7/+99z1FFH8bWvfY177rmHmpoabr/9dr797W8zc+ZMLrzwQv71X/+V0aNHc/XVV/Pd736XG2+8ESgczfz2t79ly5YtjB49umz7f/u3f2PKlCnU19fvENeGDRu46KKLWLBgAQMHDuTVV18FYPDgwSxYsICuXbvy4IMPctVVV3HnnW37N5hb4pDUBZgKnAA0AgslzY2I4sG5V4FLgTOK20bEKqCuqJ8XgbuLqvygKcmYWefV0NDQqnbz589v9TqPPPJI+vbtC0BdXR1r1qxh//33Z9myZZxwwgkAbNu2jd69e7Np0yZee+01Ro8eDcC4ceM455xztvf1hS98AYBVq1aVbV/JY489xnHHHbf93osDDzwQgE2bNjFu3DieeuopJLFly5ZWb2tz8jziOBJYHRHPAEi6DRgDbE8cEbEeWC/p1Ar9HA88HRFlZ2k0M2tPe++99/bPXbp0YevWrUQEhx12GI8++ugOdTdt2lSxr3333Reg2faVRETZy2j/8R//kc985jPcfffdrFmzptXJtZI8E0cf4IWi743AUa3o51zg1pKyiZIuBBYB34yIv5Y2kjQeGA/Qv3//VqzWzKrdrhw5pNWzZ0/eeOONinUGDRrEhg0bePTRRxk5ciRbtmzhL3/5C4cddhgHHHAAjzzyCJ/+9Ke55ZZbth99pG3f3PpHjhzJJZdcwrPPPrt9qOrAAw9k06ZN9OnTByicWM9DnifHy91REpk6kLoDpwP/UVQ8DfgEhaGsdcD3y7WNiBkRUR8R9TU1Oz2HxMwslV69ejFq1CiGDh3KpEmTytbp3r07c+bM4YorrmD48OHU1dXxhz/8AYDZs2czadIkhg0bxtKlS7n66qsztf/Sl77EhAkTtp8cb1JTU8OMGTM466yzGD58+PZhr29961tceeWVjBo1im3btrX17gBATVcEtHnH0kjgmog4Mfl+JUBE/K8yda8B3iw9byFpDHBJRHy2mXUMAH4dEUMrxVJfXx9+kJPlrbnLcfPQmS7HXblyJYceemhHh7HHK7efJS2OiPrSunkecSwEaiUNTI4czgXmZuxjLCXDVJKK/485E1i2S1GamVkmuZ3jiIitkiYC91G4HHdmRCyXNCFZPl3SRymcp9gPeF/SZcCQiHhd0j4Ursi6uKTr70mqozDstabMcjMzy1Gu93Ek91fMKymbXvT5JaBvM203A73KlF/QxmGamVkGvnPczMwyceIwM7NMnDjMzCwTz45rZruVtr7sudoubW5oaCg7N1Vz5s+fz5QpU/j1r3+dc2T/zUccZmaWiROHmVkL3nrrLU499VSGDx/O0KFDuf3227n22mv51Kc+xdChQxk/fvz26dUbGhr4xje+wXHHHcehhx7KwoULOeuss6itreU73/kOAGvWrGHw4MGMGzeOYcOGcfbZZ7N58+ad1nv//fczcuRIRowYwTnnnMObb74JFKZTHzx4MMceeyx33XVX++2IhBOHmVkL7r33Xg4++GD+67/+i2XLlnHSSScxceJEFi5cyLJly3j77bd3GCrq3r07CxYsYMKECYwZM4apU6eybNkyZs2axcaNG4HCjLjjx4/niSeeYL/99tv+lMEmr7zyCtdddx0PPvggS5Ysob6+nhtuuIF33nmHiy66iF/96lc88sgjvPTSS+26L8CJw8ysRYcffjgPPvggV1xxBY888ggf+tCHePjhhznqqKM4/PDD+c1vfsPy5cu31z/99NO3tzvssMPo3bs3e++9Nx//+Md54YXC3K/9+vVj1KhRAJx//vn87ne/22Gdjz32GCtWrGDUqFHU1dUxe/ZsnnvuOf785z8zcOBAamtrkcT555/fTnvhv/nkuJlZCw455BAWL17MvHnzuPLKK/nsZz/L1KlTWbRoEf369eOaa67hnXfe2V6/aer1vfbaa4dp2Pfaay+2bt0KsNOU6KXfI4ITTjiBW2/dcXLwpUuXlp1OvT35iMPMrAVr165ln3324fzzz+fyyy9nyZIlABx00EG8+eabzJkzJ3Ofzz///Pbnb9x6660ce+yxOyw/+uij+f3vf8/q1asB2Lx5M3/5y18YPHgwzz77LE8//fT2tu3NRxxmtlvpiMtnn3zySSZNmsRee+1Ft27dmDZtGv/5n//J4YcfzoABA/jUpz6Vuc9DDz2U2bNnc/HFF1NbW8tXv/rVHZbX1NQwa9Ysxo4dy7vvvgvAddddxyGHHMKMGTM49dRTOeiggzj22GNZtqx953rNbVr1auJp1a09eFr1fOyJ06qvWbOG0047rd1/8CuplmnVzcxsD+TEYWbWzgYMGFBVRxtZOXGYWdXrDEPqHSnr/nXiMLOq1qNHDzZu3OjkkZOIYOPGjfTo0SN1G19VZWZVrW/fvjQ2NrJhw4aODmWP1aNHD/r2LftMvbKcOMysqnXr1o2BAwd2dBhWxENVZmaWSa6JQ9JJklZJWi1pcpnlgyU9KuldSZeXLFsj6UlJSyUtKio/UNIDkp5K3g/IcxvMzGxHuSUOSV2AqcDJwBBgrKQhJdVeBS4FpjTTzWcioq7kBpTJwEMRUQs8lHw3M7N2kucRx5HA6oh4JiLeA24DxhRXiIj1EbEQ2JKh3zHA7OTzbOCMNojVzMxSyjNx9AFeKPremJSlFcD9khZLGl9U/pGIWAeQvH94lyM1M7PU8ryqqty8v1kuxB4VEWslfRh4QNKfI2JB6pUXks14gP79+2dYrZmZVZLnEUcj0K/oe19gbdrGEbE2eV8P3E1h6AvgZUm9AZL39c20nxER9RFRX1NT04rwzcysnDwTx0KgVtJASd2Bc4G5aRpK2ldSz6bPwGeBpold5gLjks/jgHvaNGozM6sot6GqiNgqaSJwH9AFmBkRyyVNSJZPl/RRYBGwH/C+pMsoXIF1EHB38pSrrsAvI+LepOvrgTskfQV4Hjgnr20wM7Od5XrneETMA+aVlE0v+vwShSGsUq8Dw5vpcyNwfBuGaWZmGfjOcTMzy8SJw8zMMvEkh2adSENDQ6vazZ8/v03jaG+VHut79QWfb1Wf195yZ7PL9vRH+zpxmO1hKv1IvrL5vTbvc0//kbSdOXGYdSKV/pXcWXmfZOdzHGZmlokTh5mZZeLEYWZmmThxmJlZJk4cZmaWiROHmZll4sRhZmaZOHGYmVkmThxmZpaJE4eZmWXixGFmZpk4cZiZWSZOHGZmlokTh5mZZeLEYWZmmeSaOCSdJGmVpNWSJpdZPljSo5LelXR5UXk/SQ9LWilpuaSvFy27RtKLkpYmr1Py3AYzM9tRbg9yktQFmAqcADQCCyXNjYgVRdVeBS4FzihpvhX4ZkQskdQTWCzpgaK2P4iIKXnFbmZmzcvziONIYHVEPBMR7wG3AWOKK0TE+ohYCGwpKV8XEUuSz28AK4E+OcZqZmYptZg4JC2SdImkAzL23Qd4oeh7I6348Zc0ADgCeLyoeKKkJyTNbC4uSeOT2Bdt2LAh62rNzKwZaY44zgUOpjDUdJukEyUpRbtydSJLcJI+CNwJXBYRryfF04BPAHXAOuD75dpGxIyIqI+I+pqamiyrNTOzClpMHBGxOiK+DRwC/BKYCTwv6buSDqzQtBHoV/S9L7A2bWCSulFIGr+IiLuK4nk5IrZFxPvATygMiZmZWTtJdY5D0jAK/7L/PxR+zM8GXgd+U6HZQqBW0kBJ3SkcucxNuT4BPwVWRsQNJct6F309E1iWpk8zM2sbLV5VJWkx8BqFH/LJEfFusuhxSaOaaxcRWyVNBO4DugAzI2K5pAnJ8umSPgosAvYD3pd0GTAEGAZcADwpaWnS5VURMQ/4nqQ6CsNea4CLs2ywmZntmjSX454TEc8UF0gaGBHPRsRZlRomP/TzSsqmF31+icIQVqnfUf4cCRFxQYqYzcwsJ2mGquakLDMzs06g2SMOSYOBw4APSSo+stgP6JF3YGZmVp0qDVUNAk4D9gc+V1T+BnBRjjGZmVkVazZxRMQ9wD2SRkbEo+0Yk5mZVbFKQ1XfiojvAV+UNLZ0eURcmmtkZmZWlSoNVa1M3he1RyBmZrZ7qDRU9avkfXZTmaS9gA8WTf9hZmadTJpJDn8paT9J+wIrgFWSJuUfmpmZVaM093EMSY4wzqBwM19/Cnd1m5lZJ5QmcXRLJhw8A7gnIraQcZZbMzPbc6RJHD+mMCfUvsACSR+jMMGhmZl1Qi3OVRURNwE3FRU9J+kz+YVkZmbVLM3suHsDnwcGlNS/NqeYzMysiqWZHfceYBOwGHi3hbpmZraHS5M4+kbESblHUqXuWrWu2WVXX/D5VvV57S13NrvsrEG9m11WSUNDQ6vazZ8/v1XtdgfeJ2b5SJM4/iDp8Ih4MvdozDKqlNhf2fxem/fZ2sRutidJkziOBb4k6VkKQ1UCIiKG5RrZbqDSkUMeKv2gXfrjW9u0zz3hB7K9//uYdRZpEsfJuUdhZma7jRbv44iI54B+wN8knzenaWdmZnumNHNV/RNwBXBlUtQN+HmeQZmZWfVKc+RwJnA68BZARKwFeqbpXNJJklZJWi1pcpnlgyU9KuldSZenaSvpQEkPSHoqeT8gTSxmZtY20iSO9yIiSOanSmbJbZGkLsBUCudIhgBjJQ0pqfYqcCkwJUPbycBDEVELPJR8NzOzdpImcdwh6cfA/pIuAh4EfpKi3ZHA6oh4JiLeA24DxhRXiIj1EbEQ2JKh7Rig6RkhsylMvmhmZu0kzVxVUySdQGFiw0HA1RHxQIq++wAvFH1vBI5KGVelth+JiHVJbOskfbhcB5LGA+MB+vfvn3K1ZmbWkjSX45IkijTJopjKddUObQuVI2YAMwDq6+s9DbyZWRtpNnFIeoMKP9YRsV8LfTdSuIy3SV9gbcq4KrV9WVLv5GijN7A+ZZ9mZtYGKj1zvCeApGuBl4BbKBwJnEe6q6oWArWSBgIvAucCX0wZV6W2c4FxwPXJ+z0p+zQzszaQZqjqxIgoPjcxTdLjwPcqNYqIrZImAvcBXYCZEbFc0oRk+XRJHwUWAfsB70u6jORRteXaJl1fT+GE/VeA54Fz0m6smZntujSJY5uk8yhc2RTAWGBbms4jYh6F55QXl00v+vwShWGoVG2T8o3A8WnWb2ZmbS/N5bhfBP4WeDl5nUP6ISczM9vDpLkcdw0l91+YmVnn5ckKzcwsEycOMzPLxInDzMwyafEch6R/KFO8CVgcEUvbPCIzM6tqaY446oEJFOaP6kNh/qcG4CeSvpVfaGZmVo3S3MfRCxgREW/C9gc7zQGOAxbTwo2AZma2Z0lzxNEfeK/o+xbgYxHxNvBuLlGZmVnVSnPE8UvgMUlNc0J9Drg1eaDTitwiMzOzqpTmBsB/lvT/gFEUJjmcEBGLksXn5RmcmZlVn1TP4wD+RGFa864AkvpHxPO5RWVmZlUrzeW4XwP+icI8VdsoHHUEMCzf0MzMrBqlOeL4OjAomZXWzMw6uTRXVb1A4YY/MzOzVEcczwDzJf1fii6/jYgbcovKzMyqVprE8Xzy6p68zMysE0tzOe532yMQMzPbPTSbOCTdGBGXSfoVhauodhARp+camZmZVaVKRxy3JO9T2iMQMzPbPTR7VVVELE4+1kXEb4tfQF2aziWdJGmVpNWSJpdZLkk3JcufkDQiKR8kaWnR63VJlyXLrpH0YtGyU7JutJmZtV6ay3HHlSn7UkuNJHUBpgInA0OAsZKGlFQ7GahNXuOBaQARsSoi6iKiDvgksBm4u6jdD5qWR8S8FNtgZmZtpNI5jrHAF4GBkuYWLeoJpLkZ8EhgdUQ8k/R3GzCGHSdGHAP8LCKCwkSK+0vqHRHriuocDzwdEc+l2iIzM8tVpXMcfwDWAQcB3y8qfwN4IkXffSjcPNikETgqRZ0+yXqbnAvcWtJuoqQLgUXANyPir6UrlzSewlEM/fv3TxGumZmlUekcx3MRMT8iRpac41gSEVtT9K1y3WapI6k7cDrwH0XLpwGfoHCeZR07JrXi+GdERH1E1NfU1KQI18zM0mg2cUj6XfL+RnJyuun1hqTXU/TdCPQr+t6Xwgy7WeqcDCyJiJebCiLi5YjYFhHvAz+hMCRmZmbtpNmhqog4Nnnv2cq+FwK1kgYCL1IYcvpiSZ25FIadbqMwjLWp5PzGWEqGqUrOgZwJLGtlfJaDhoaGVrWbP39+m8Zh1c9/KzvbXfZJmmnVPwE0RsS7khooTKf+s4h4rVK7iNgqaSJwH9AFmBkRyyVNSJZPB+YBpwCrKVw59eWi9e4DnABcXNL19yTVURjSWlNmuZlZ1bpr1bpml72y+b1ml7W2z7MG9W5Vn5WkmavqTqBe0v8AfkrhKOGXFH7wK0oulZ1XUja96HMAlzTTdjPQq0z5BSlithxV+iO99Mel1zHsep95/OFb+2jPv5U94e/k2lvu7OgQUklzH8f7ycnwM4EbI+IbwO7/X8jMzFolTeLYktzTMQ74dVLWLb+QzMysmqVJHF8GRgL/EhHPJie7f55vWGZmVq3STKu+Ari06PuzwPV5BmVmZtWr0pQjd0TE30p6kvLTqg/LNTIzM6tKlY44vp68n9YegZiZ2e6h0g2ATde8nQXcEREvtk9IZmZWzdKcHN8PuF/SI5IukfSRvIMyM7Pq1WLiiIjvRsRhFG7UOxj4raQHc4/MzMyqUpojjibrgZcoPIvjw/mEY2Zm1a7FxCHpq5LmAw9ReDbHRb6iysys80ozV9XHgMsiYmnOsZiZ2W4gzQ2Ak9sjEDMz2z1kOcdhZmbmxGFmZtk4cZiZWSZOHGZmlokTh5mZZeLEYWZmmThxmJlZJrkmDkknSVolabWkne4HUcFNyfInJI0oWrZG0pOSlkpaVFR+oKQHJD2VvB+Q5zaYmdmOcksckroAU4GTgSHAWElDSqqdDNQmr/HAtJLln4mIuoioLyqbDDwUEbUUpkHxDYpmZu0ozyOOI4HVEfFMRLwH3AaMKakzBvhZFDwG7C+pdwv9jgFmJ59nA2e0YcxmZtaCPBNHH+CFou+NSVnaOkHhOSCLJY0vqvORpodMJe9lZ+qVNF7SIkmLNmzYsAubYWZmxfJMHCpTVvrs8kp1RkXECArDWZdIOi7LyiNiRkTUR0R9TU1NlqZmZlZBnomjEehX9L0vsDZtnYhoel8P3E1h6Avg5abhrOR9fZtHbmZmzcozcSwEaiUNlNQdOBeYW1JnLnBhcnXV0cCmiFgnaV9JPQEk7Qt8FlhW1GZc8nkccE+O22BmZiXSPI+jVSJiq6SJwH1AF2BmRCyXNCFZPh2YB5wCrAY2A19Omn8EuFtSU4y/jIh7k2XXA3dI+grwPHBOXttgZmY7yy1xAETEPArJobhsetHnoPAs89J2zwDDm+lzI3B820ZqZmZp+c5xMzPLxInDzMwyceIwM7NMnDjMzCwTJw4zM8vEicPMzDJx4jAzs0ycOMzMLBMnDjMzy8SJw8zMMnHiMDOzTJw4zMwsEycOMzPLxInDzMwyceIwM7NMnDjMzCwTJw4zM8vEicPMzDJx4jAzs0ycOMzMLJNcE4ekkyStkrRa0uQyyyXppmT5E5JGJOX9JD0saaWk5ZK+XtTmGkkvSlqavE7JcxvMzGxHXfPqWFIXYCpwAtAILJQ0NyJWFFU7GahNXkcB05L3rcA3I2KJpJ7AYkkPFLX9QURMySt2MzNrXp5HHEcCqyPimYh4D7gNGFNSZwzwsyh4DNhfUu+IWBcRSwAi4g1gJdAnx1jNzCylPBNHH+CFou+N7Pzj32IdSQOAI4DHi4onJkNbMyUdUG7lksZLWiRp0YYNG1q5CWZmVirPxKEyZZGljqQPAncCl0XE60nxNOATQB2wDvh+uZVHxIyIqI+I+pqamoyhm5lZc/JMHI1Av6LvfYG1aetI6kYhafwiIu5qqhARL0fEtoh4H/gJhSExMzNrJ3kmjoVAraSBkroD5wJzS+rMBS5Mrq46GtgUEeskCfgpsDIibihuIKl30dczgWX5bYKZmZXK7aqqiNgqaSJwH9AFmBkRyyVNSJZPB+YBpwCrgc3Al5Pmo4ALgCclLU3KroqIecD3JNVRGNJaA1yc1zaYmdnOckscAMkP/bySsulFnwO4pEy731H+/AcRcUEbh2lmZhn4znEzM8vEicPMzDJx4jAzs0ycOMzMLBMnDjMzy8SJw8zMMnHiMDOzTJw4zMwsEycOMzPLxInDzMwyceIwM7NMnDjMzCwTJw4zM8vEicPMzDJx4jAzs0ycOMzMLBMnDjMzy8SJw8zMMnHiMDOzTJw4zMwsk1wTh6STJK2StFrS5DLLJemmZPkTkka01FbSgZIekPRU8n5AnttgZmY7yi1xSOoCTAVOBoYAYyUNKal2MlCbvMYD01K0nQw8FBG1wEPJdzMzayd5HnEcCayOiGci4j3gNmBMSZ0xwM+i4DFgf0m9W2g7BpidfJ4NnJHjNpiZWYmuOfbdB3ih6HsjcFSKOn1aaPuRiFgHEBHrJH243MoljadwFAPwpqRVrdmIXXAQ8Eo7r7PaeZ/szPukPO+XnXXEPvlYucI8E4fKlEXKOmnaVhQRM4AZWdq0JUmLIqK+o9ZfjbxPduZ9Up73y86qaZ/kOVTVCPQr+t4XWJuyTqW2LyfDWSTv69swZjMza0GeiWMhUCtpoKTuwLnA3JI6c4ELk6urjgY2JcNQldrOBcYln8cB9+S4DWZmViK3oaqI2CppInAf0AWYGRHLJU1Ilk8H5gGnAKuBzcCXK7VNur4euEPSV4DngXPy2oZd1GHDZFXM+2Rn3ifleb/srGr2iSIynTowM7NOzneOm5lZJk4cZmaWiRNHG2tpmpXOSFI/SQ9LWilpuaSvd3RM1UJSF0l/kvTrjo6lGkjaX9IcSX9O/l5GdnRMHU3SN5L/b5ZJulVSj46OyYmjDaWcZqUz2gp8MyIOBY4GLvF+2e7rwMqODqKK/BC4NyIGA8Pp5PtGUh/gUqA+IoZSuFjo3I6NyomjraWZZqXTiYh1EbEk+fwGhR+DPh0bVceT1Bc4Fbi5o2OpBpL2A44DfgoQEe9FxGsdGlR16Ap8QFJXYB92vh+u3TlxtK3mplCxhKQBwBHA4x0cSjW4EfgW8H4Hx1EtPg5sAP49Gb67WdK+HR1UR4qIF4EpFG49WEfhXrf7OzYqJ462tstTpezJJH0QuBO4LCJe7+h4OpKk04D1EbG4o2OpIl2BEcC0iDgCeItOPvt18tiIMcBA4GBgX0nnd2xUThxtLc00K52SpG4UksYvIuKujo6nCowCTpe0hsKQ5t9I+nnHhtThGoHGiGg6Gp1DIZF0Zv8TeDYiNkTEFuAu4JgOjsmJo42lmWal05EkCuPWKyPiho6OpxpExJUR0TciBlD4O/lNRHT4vyQ7UkS8BLwgaVBSdDywogNDqgbPA0dL2if5/+h4quCCgTxnx+10WpgqpTMbBVwAPClpaVJ2VUTM67iQrEp9DfhF8g+vZ0imIeqsIuJxSXOAJRSuTvwTVTD1iKccMTOzTDxUZWZmmThxmJlZJk4cZmaWiROHmZll4sRhZmaZOHGYmVkmThxmZpaJE4dZB5F0jaTLOzoOs6ycOMzMLBMnDrNWkjQgeUrdT5IntN0v6QPJsn9Inti2TNJlRW2+nTwh8kFgUFH5+ZL+KGmppB8nDwUrt86HJZ2QfL5O0k35bqXZzjxXldmuqQXGRsRFku4APi9pJYU5lo6iMNX+45J+S+EfaudSeB5JVwrzDy2WdCjwBWBURGyR9CPgPOBnZdb3T8C1kj6c9HN6vptntjMnDrNd82xELE0+LwYGAL2AuyPiLQBJdwGfppA47o6IzUl508zJxwOfBBYWJkDlA8D6ciuLiAXJLKn/ADRExLYctsmsIicOs13zbtHnbRR+9Ms90KtJuVlFBcyOiCtbWpmkw4HewCvJY3jN2p3PcZi1vQXAGckzFPYFzgQeScrPlPQBST2BzyX1HwLOToafkHSgpI+VdiqpN/ALCk+Ee0vSie2wLWY78RGHWRuLiCWSZgF/TIpujog/AUi6HVgKPEchmRARKyR9B7hf0l7AFuCSpA5Ju30oPP3tmxGxUtI/A/+bwrNfzNqVn8dhZmaZeKjKzMwyceIwM7NMnDjMzCwTJw4zM8vEicPMzDJx4jAzs0ycOMzMLJP/D09NwKv+FVKfAAAAAElFTkSuQmCC\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"needs_background": "light"
|
|
},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"def chain_Q_histogram(graph,start,k):\n",
|
|
" '''Produce a histogram (a Numpy array of length equal to the number of \n",
|
|
" nodes of graph) of the states visited (excluding initial state) by the \n",
|
|
" Q Markov chain in the first k steps when started at start.'''\n",
|
|
" n = graph.number_of_nodes()\n",
|
|
" number_of_visits = np.zeros(n)\n",
|
|
" x = start\n",
|
|
" \n",
|
|
" for _ in range(k):\n",
|
|
" x = sample_proposal(graph, x)\n",
|
|
" number_of_visits[x] += 1\n",
|
|
" \n",
|
|
" return number_of_visits\n",
|
|
"\n",
|
|
"def transition_matrix_Q(graph):\n",
|
|
" '''Construct transition matrix Q from graph as two-dimensional Numpy array.'''\n",
|
|
" n = example_graph.number_of_nodes()\n",
|
|
" Q = np.zeros((n, n))\n",
|
|
" for x in range(n): \n",
|
|
" for k in example_graph.neighbors(x):\n",
|
|
" Q[x, k] = 1/example_graph.degree(x)\n",
|
|
" return Q\n",
|
|
"\n",
|
|
"# Compare histogram and stationary distribution in a plot\n",
|
|
"x_start = 1\n",
|
|
"k = 100000\n",
|
|
"\n",
|
|
"plt.figure()\n",
|
|
"x_list = list(range(example_graph.number_of_nodes()))\n",
|
|
"plt.bar(x_list, chain_Q_histogram(example_graph, x_start, k)/k, color=\"lightblue\", label=\"sampled\")\n",
|
|
"plt.scatter(x_list, stationary_distributions(transition_matrix_Q(example_graph)), s=200, marker=\"_\", color=\"black\", label=\"theoretical\")\n",
|
|
"plt.ylabel(\"visiting density\")\n",
|
|
"plt.xlabel(\"node $x$\")\n",
|
|
"plt.legend()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"id": "812cd2ef",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "c3e08e0577c953ca68fe8159cadc0634",
|
|
"grade": true,
|
|
"grade_id": "cell-bdea40714e10d0e8",
|
|
"locked": true,
|
|
"points": 15,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert_almost_equal(transition_matrix_Q(example_graph)[3,4],1/3,delta=1e-9)\n",
|
|
"assert_almost_equal(transition_matrix_Q(example_graph)[3,7],0.0,delta=1e-9)\n",
|
|
"assert_almost_equal(transition_matrix_Q(example_graph)[2,2],0.0,delta=1e-9)\n",
|
|
"assert_almost_equal(np.sum(transition_matrix_Q(example_graph)[7]),1.0,delta=1e-9)\n",
|
|
"assert chain_Q_histogram(nx.Graph([(0,1)]),0,100)[1] == 50\n",
|
|
"assert len(chain_Q_histogram(example_graph,0,100)) == example_graph.number_of_nodes()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "8ebe4946",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "f4338397c60be0fc0069e30bec121faa",
|
|
"grade": false,
|
|
"grade_id": "cell-5a9debbf863b9e3b",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"__(c)__ Determine the appropriate Metropolis-Hastings acceptance probability $A(x \\to y)$ for $x\\neq y$\n",
|
|
"and write a function that, given a graph and $x$, samples the next state with $y$ according to the Metropolis-Hastings transition matrix $P(x \\to y)$. **(10 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"id": "37804448",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "639522f9ff68136165c0d9daa174b4ba",
|
|
"grade": false,
|
|
"grade_id": "cell-92e3b11a3af7eb99",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def acceptance_probability(graph,x,y):\n",
|
|
" '''Compute A(x -> y) for the supplied graph (assuming x!=y).'''\n",
|
|
" assert x != y\n",
|
|
" \n",
|
|
" Q = transition_matrix_Q(graph)\n",
|
|
" n = graph.number_of_nodes()\n",
|
|
" # We want to sample a uniform mass distribution pi:\n",
|
|
" pi = np.ones(n)/n\n",
|
|
" \n",
|
|
" if Q[x, y] == 0:\n",
|
|
" return 0\n",
|
|
" else:\n",
|
|
" A = pi[y]*Q[y, x]/( pi[x]*Q[x, y] )\n",
|
|
" return np.min([1., A])\n",
|
|
"\n",
|
|
"def sample_next_state(graph,x):\n",
|
|
" '''Return next random state y according to MH transition matrix P(x -> y).'''\n",
|
|
" y = sample_proposal(graph, x)\n",
|
|
" return y if rng.random() < acceptance_probability(graph, x, y) else x"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"id": "058d3728",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "6bf922f8787f02c80681390ce8a8f84c",
|
|
"grade": true,
|
|
"grade_id": "cell-fbfc2607999d0c99",
|
|
"locked": true,
|
|
"points": 10,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert_almost_equal(acceptance_probability(example_graph,3,4),0.6,delta=1e-9)\n",
|
|
"assert_almost_equal(acceptance_probability(example_graph,8,7),0.5,delta=1e-9)\n",
|
|
"assert_almost_equal(acceptance_probability(example_graph,7,8),1.0,delta=1e-9)\n",
|
|
"assert_almost_equal(acceptance_probability(nx.Graph([(0,1)]),0,1),1,delta=1e-9)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "cbf205bf",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "da69b710a3b1986ac9f9997235c1a472",
|
|
"grade": false,
|
|
"grade_id": "cell-97f7d289177acf39",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"__(d)__ Do the same as in part (b) but now for the Markov chain corresponding to $P$. Verify that the histogram of the Markov chain approaches a flat distribution and corroborate this by calculating the explicit matrix $P$ and applying `stationary_distributions` to it. _Hint_: for determining the explicit matrix $P(x\\to y)$, remember that the formula $P(x\\to y) = Q(x\\to y)A(x\\to y)$ only holds for $x\\neq y$. What is $P(x\\to x)$? **(15 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"id": "5de68351",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "bd25c9f6b39133973fd2d1594e210b30",
|
|
"grade": false,
|
|
"grade_id": "cell-3b7fde395331916d",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEICAYAAABF82P+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAfl0lEQVR4nO3dfZyVc/7H8denW0WJGiuVZnYlwm406XbbKDe5y22KRLsrIYRdi0Wkxe4Pm3bTjZv1E9ZNWLFZN5GkpIlQjZhfRbOypmgqU2ry+f1xrtozc66ZrqauOafp/Xw85jHnXN/v9zqfc5rmPdfd9zJ3R0REpLxa6S5AREQykwJCRERCKSBERCSUAkJEREIpIEREJFSddBewMzVr1syzs7PTXYaIyC5j3rx5K909K6ytRgVEdnY2eXl56S5DRGSXYWafV9SmXUwiIhJKASEiIqEUECIiEkoBISIioRQQIiISSgEhIiKhFBAiIhJKASEiIqEUECIiEqpGXUktsjt5bvGKanutM9s2r7bXqgmq898G4vv3UUCISI1RU34xZ4oaFRCLFy+mZ8+eZZb169ePyy67jJKSEk466aSUMRdddBEXXXQRK1eu5Oyzz05pv/TSSzn33HNZvnw5F1xwQUr7tddey6mnnsrixYu55JJLUtpvuukmevfuzfz58xk+fHhK+x133EHXrl2ZNWsWN954Y0r76NGjad++Pa+//jqjRo1KaZ8wYQJt27blxRdf5J577klpnzRpEq1ateKpp55i3LhxKe2TJ0+mWbNmPPLIIzzyyCMp7VOnTqVhw4bcf//9PP300ynt06dPB+Duu+/mpZdeKtPWoEEDXn75ZQBuv/12pk2bVqa9adOmPPvsswDccMMNzJ49u0x7y5YteeyxxwAYPnw48+fPL9N+8MEHM3HiRACGDBnCp59+Wqa9ffv2jB49GoCBAwdSWFhYpr1Lly7ceeedAJx11lmsWrWqTHuvXr24+eabAejTpw/r169nZcnGre0devam768uBeCWC84q/9HQtc+pnHjeRXy/voQ/DEn92el5Rj+OPfNc1ny7iruvHJLSfsKAQdxz9dAKf/a6nDuYjscez7+XFDBhxO9S2s+69Cp+1rUHS/MX8Lc7RqS0n3f19RxyVEc+eX8uT/z5rpT2wTfeRs6hh/PhrBmMuST1ZycTf/a2/PvU22MPbnrgcQCeuf/PfDx7ZpmxezXZh+v+8iAAj91zB5/On1emven+zbnqf/4KwMN33MKy/IVl2ptn/5hLb/8fIPxnb6/WbfjljSMBuO+3w1j1VdngOrh9BwZem/j//qcrfs261d+WaT+iS3fOuexqAEZdfD4bN2wo017+Z29Mw3pl2rfn915lalRArFu3jrfeeguA1q1bo5ldd8zKko288OkK6jdoyPz/FJf55bjFlr/YPv56TUp7vR9qbW1ftHJtSvuGehu2ti9eta7SWgq+/S5lfN3VJVvHL11dktJe8O13W9uXr1nPqnLti1et29r+77UbWBe0Nyv3n02kpvnHP/7B4MGDtzztUFE/c/fqqaga5ObmumZz3XkyaXM9U/a36zPJbJny75MpdURhZvPcPTesrUZtQYhI9duVfhnK9lFABPTXmIhIWboOQkREQmkLIsNoc11EMoW2IEREJJQCQkREQikgREQklAJCRERCKSBERCSUAkJEREIpIEREJJQCQkREQikgREQklAJCRERCKSBERCRUrAFhZiea2WIzKzCz60PaDzGz2Wb2vZn9ZnvGiohIvGILCDOrDYwF+gDtgAFm1q5ct2+AK4G7qzBWRERiFOcWxNFAgbsvcfeNwJNA3+QO7v61u88FNm3vWBERiVecAdECWJ70vDBYtlPHmtkQM8szs7yioqIqFSoiIqniDAgLWRb1BtiRx7r7RHfPdffcrKysyMWJiEjl4gyIQqBV0vOWwJfVMFZERHaCOANiLtDGzHLMrB7QH5hSDWNFRGQniO2Wo+5eambDgFeA2sDD7r7QzIYG7ePNbH8gD2gM/GBmw4F27r4mbGxctYqISKpY70nt7lOBqeWWjU96/BWJ3UeRxoqISPXRldQiIhJKASEiIqEUECIiEkoBISIioRQQIiISSgEhIiKhFBAiIhJKASEiIqEUECIiEkoBISIioRQQIiISSgEhIiKhFBAiIhJKASEiIqEUECIiEkoBISIioRQQIiISSgEhIiKhFBAiIhJKASEiIqEUECIiEkoBISIioRQQIiISSgEhIiKhFBAiIhJKASEiIqEUECIiEkoBISIioWINCDM70cwWm1mBmV0f0m5mNiZo/8jMjkpqu9rMFprZAjP7u5ntEWetIiJSVmwBYWa1gbFAH6AdMMDM2pXr1gdoE3wNAcYFY1sAVwK57n44UBvoH1et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\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"needs_background": "light"
|
|
},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"def chain_P_histogram(graph,start,k):\n",
|
|
" '''Produce a histogram of the states visited (excluding initial state) \n",
|
|
" by the P Markov chain in the first n steps when started at start.'''\n",
|
|
" n = graph.number_of_nodes()\n",
|
|
" number_of_visits = np.zeros(n)\n",
|
|
" x = start\n",
|
|
" \n",
|
|
" for _ in range(k):\n",
|
|
" x = sample_next_state(graph, x)\n",
|
|
" number_of_visits[x] += 1\n",
|
|
" \n",
|
|
" return number_of_visits\n",
|
|
"\n",
|
|
"def transition_matrix_P(graph):\n",
|
|
" '''Construct transition matrix Q from graph as numpy array.'''\n",
|
|
" n = graph.number_of_nodes()\n",
|
|
" P = np.zeros((n, n))\n",
|
|
" Q = transition_matrix_Q(graph)\n",
|
|
" \n",
|
|
" for x in range(n):\n",
|
|
" for y in range(n):\n",
|
|
" if x != y:\n",
|
|
" P[y, x] = Q[x, y]*acceptance_probability(graph, x, y)\n",
|
|
" # Finally, we have to calculate P(x -> x):\n",
|
|
" P[x, x] = 1 - np.sum(P[:, x])\n",
|
|
" return P\n",
|
|
"\n",
|
|
"# plotting\n",
|
|
"x_start = 1\n",
|
|
"k = 40000\n",
|
|
"\n",
|
|
"plt.figure()\n",
|
|
"x_list = list(range(example_graph.number_of_nodes()))\n",
|
|
"plt.bar(x_list, chain_P_histogram(example_graph, x_start, k)/k, color=\"lightblue\", label=\"sampled\")\n",
|
|
"plt.axhline(y = 1/example_graph.number_of_nodes(), marker=\"_\", linestyle = \"dashed\", color=\"black\", label=\"theoretical\")\n",
|
|
"plt.ylabel(\"visiting density\")\n",
|
|
"plt.xlabel(\"node $x$\")\n",
|
|
"plt.legend()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"id": "4b5cc504",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "1b756f8dff589048e791db63f89d8624",
|
|
"grade": true,
|
|
"grade_id": "cell-8c4b6c60ee96f037",
|
|
"locked": true,
|
|
"points": 10,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert_almost_equal(transition_matrix_P(example_graph)[3,4],1/5,delta=1e-9)\n",
|
|
"assert_almost_equal(transition_matrix_P(example_graph)[3,7],0.0,delta=1e-9)\n",
|
|
"assert_almost_equal(transition_matrix_P(example_graph)[2,2],0.41666666,delta=1e-5)\n",
|
|
"assert_almost_equal(np.sum(transition_matrix_P(example_graph)[7]),1.0,delta=1e-9)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"id": "f4e9d8aa",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "22ff259ba7ad6066040f3417cc8d4483",
|
|
"grade": true,
|
|
"grade_id": "cell-a63274314d1b2a2d",
|
|
"locked": true,
|
|
"points": 5,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert len(chain_P_histogram(example_graph,0,100)) == example_graph.number_of_nodes()\n",
|
|
"assert_almost_equal(chain_P_histogram(example_graph,0,20000)[8],2222,delta=180)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "89f65139",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "9b277d17c7b55bb15e5708e6ca90c4f9",
|
|
"grade": false,
|
|
"grade_id": "cell-da50533d4d46c293",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"## MCMC simulation of disk model\n",
|
|
"\n",
|
|
"**(50 points)**\n",
|
|
"\n",
|
|
"Recall that in the disk model with we would like to sample the positions $x = (x_1,y_1,\\ldots,x_N,y_N)\\in [0,L)^{2N}$ of $N$ disks of radius $1$ in the torus $[0,L)^2$ with uniform density $\\pi(x) = \\mathbf{1}_{\\{\\text{all pairwise distance }\\geq 2\\}}(x) / Z$, where $Z$ is the unknown partition function of the model. We will assume $L > 2$ and $N\\geq 1$. For the purposes of this simulation we will store the state $x$ in a `np.array` of dimension $(N,2)$ with values in $[0,L)$. Such a configuration can be conveniently plotted using the following function:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"id": "683d2de3",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "4c7cb2d90103cd790145cae15d46e99e",
|
|
"grade": false,
|
|
"grade_id": "cell-d661f575ab9f80ea",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"def plot_disk_configuration(positions,L):\n",
|
|
" fig,ax = plt.subplots()\n",
|
|
" ax.set_aspect('equal')\n",
|
|
" ax.set_ylim(0,L)\n",
|
|
" ax.set_xlim(0,L)\n",
|
|
" ax.set_yticklabels([])\n",
|
|
" ax.set_xticklabels([])\n",
|
|
" ax.set_yticks([])\n",
|
|
" ax.set_xticks([])\n",
|
|
" for x,y in positions:\n",
|
|
" # consider all horizontal and vertical copies that may be visible\n",
|
|
" for x_shift in [z for z in x + [-L,0,L] if -1<z<L+1]:\n",
|
|
" for y_shift in [z for z in y + [-L,0,L] if -1<z<L+1]:\n",
|
|
" ax.add_patch(plt.Circle((x_shift,y_shift),1))\n",
|
|
" plt.show()\n",
|
|
" \n",
|
|
"# Example with N=3 and L=5\n",
|
|
"positions = np.array([[0.1,0.5],[2.1,1.5],[3.2,3.4]])\n",
|
|
"plot_disk_configuration(positions,5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "efa2f1c9",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "d29e40f9d0e8d304d266f016150aeab7",
|
|
"grade": false,
|
|
"grade_id": "cell-527056f298dedf7c",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"__(a)__ Write a function `two_disks_overlap` that tests whether disks at position $\\mathbf{x}_1 \\in [0,L)^{2}$ and position $\\mathbf{x}_2 \\in [0,L)^{2}$ overlap and a function `disk_config_valid` that checks whether a full configuration is valid (non-overlapping and non-touching). _Hint:_ The minimal separation in the $x$-direction can be expressed as a function of `x1[0]-x2[0]` and the minimal separation in the y-direction as a function of `x1[1]-x2[1]`. Then use pythagoras. **(15 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"id": "19c010eb",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "bbf8ae650d9d4a66a3e4ac4722a3f60e",
|
|
"grade": false,
|
|
"grade_id": "cell-1b2a61bf719003e0",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def two_disks_overlap(x1,x2,L):\n",
|
|
" '''Return True if the disks centered at x1 and x2 (represented as 2-element arrays) overlap in [0,L)^2.'''\n",
|
|
" # To take into account all overlap with the boundaries, we will also\n",
|
|
" # test shifted disks. As d(x1 + d, x2) = d(x1, x2 - d), we do not have\n",
|
|
" # to shift both disks explicitly.\n",
|
|
" for dx in [0, -L, L]:\n",
|
|
" for dy in [0, -L, L]:\n",
|
|
" if (x1[0] - x2[0] + dx)**2 + (x1[1] - x2[1] + dy)**2 <= 4:\n",
|
|
" return True\n",
|
|
" return False\n",
|
|
" \n",
|
|
"def disk_config_valid(x,L):\n",
|
|
" '''Return True if the configuration x (as two-dimensional array) is non-overlapping in [0,L)^2.'''\n",
|
|
" n = len(x)\n",
|
|
" for idx_x1 in range(n):\n",
|
|
" # We should not compare x1 with itself, and the previous disks have\n",
|
|
" # already been compared.\n",
|
|
" for idx_x2 in range(idx_x1 + 1, n):\n",
|
|
" if two_disks_overlap(x[idx_x1], x[idx_x2], L):\n",
|
|
" return False\n",
|
|
" return True"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"id": "e0f2024a",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "05fc821fed0690aabc13fd66da800694",
|
|
"grade": true,
|
|
"grade_id": "cell-9f544deda0526691",
|
|
"locked": true,
|
|
"points": 10,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert two_disks_overlap(np.array([1,1]),np.array([1,1]),5)\n",
|
|
"assert two_disks_overlap(np.array([0.6,0.6]),np.array([4.1,0.5]),5)\n",
|
|
"assert two_disks_overlap(np.array([0.3,0.3]),np.array([4.6,4.6]),5)\n",
|
|
"assert not two_disks_overlap(np.array([1,1]),np.array([3.1,1]),7)\n",
|
|
"assert not two_disks_overlap(np.array([1,1]),np.array([1,3.1]),7)\n",
|
|
"assert not two_disks_overlap(np.array([1,1]),np.array([1.01+np.sqrt(2),1.01+np.sqrt(2)]),6)\n",
|
|
"assert two_disks_overlap(np.array([1,1]),np.array([0.99+np.sqrt(2),0.99+np.sqrt(2)]),6)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"id": "68e57e57",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "8705cb3a08fc636963fe61806348d093",
|
|
"grade": true,
|
|
"grade_id": "cell-699454de327d56d5",
|
|
"locked": true,
|
|
"points": 5,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert disk_config_valid(np.array([[0.1,0.5],[2.1,1.5],[3.2,3.4]]),5)\n",
|
|
"assert not disk_config_valid(np.array([[0.1,0.5],[2.1,1.5],[3.2,3.4],[4.1,2.3]]),5)\n",
|
|
"assert disk_config_valid(np.array([[1,1],[3.1,1],[1,3.1]]),6)\n",
|
|
"assert not disk_config_valid(np.array([[1,1],[3.1,1],[1,3.1],[2.5,2.5]]),6)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "fe7c5736",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "db023e65fc2613d624f29977a82bf1f1",
|
|
"grade": false,
|
|
"grade_id": "cell-b0e00f11b0f85525",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"__(b)__ Assuming $N \\leq \\lceil \\frac12 L -1 \\rceil^2$ where $\\lceil r\\rceil$ is the smallest integer larger or equal to $r$, write a function `generate_initial_positions` that produces an arbitrary non-overlapping (and non-touching) initial condition given $N$ and $L$. The layout need not be random, any deterministic layout is ok (e.g. grid). **(10 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"id": "f86a04ed",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "b17579d74c8ff8572d81f18997b49c90",
|
|
"grade": false,
|
|
"grade_id": "cell-53c1bd894d6fe27d",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"def generate_initial_positions(N,L):\n",
|
|
" '''Return array of positions of N disks in non-overlapping positions.'''\n",
|
|
" assert N <= np.ceil( (.5*L**2 - 1)**2 )\n",
|
|
" \n",
|
|
" disks = np.zeros((N, 2))\n",
|
|
" i = 0\n",
|
|
" # To have the disks non-touchting, we have them 2.0001 apart instead of 2.\n",
|
|
" for x in np.arange(1, L - 1, 2.0001):\n",
|
|
" for y in np.arange(1, L - 1, 2.0001):\n",
|
|
" if i + 1 > N: return disks\n",
|
|
" disks[i] = x, y\n",
|
|
" i += 1\n",
|
|
" return disks\n",
|
|
" \n",
|
|
"plot_disk_configuration(generate_initial_positions(33,14.5),14.5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"id": "3d3dc3db",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "fa73c21133aa2b913b931b266e7782f0",
|
|
"grade": true,
|
|
"grade_id": "cell-e1c80d8b59301b93",
|
|
"locked": true,
|
|
"points": 10,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"for l in [4,9.2,14.5]:\n",
|
|
" for n in range(1,int(np.ceil(l/2-1)**2)+1):\n",
|
|
" assert disk_config_valid(generate_initial_positions(n,l),l), \"Failed for n = {}, l = {}\".format(n,l)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "eb5dbe07",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "b4bb37c92263c95c89055362336f894a",
|
|
"grade": false,
|
|
"grade_id": "cell-1bd76964ec9620ce",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"__(c)__ Write a function `remains_valid_after_move` that determines whether in a non-overlapping configuration $x$ moving the $i$th disk to `next_position` results in a valid non-overlapping configuration. **(10 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"id": "56252046",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "04ff82e1b0e3386f2cb15412695c1864",
|
|
"grade": false,
|
|
"grade_id": "cell-d54b4fa9b2f8eb92",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def remains_valid_after_move(x,i,next_position,L):\n",
|
|
" '''Returns True if replacing x[i] by next_position would yield a valid configuration,\n",
|
|
" otherwise False.'''\n",
|
|
" # TODO: Do I need to operate on a copy?\n",
|
|
" copy_x = np.copy(x)\n",
|
|
" copy_x[i] = next_position\n",
|
|
" return disk_config_valid(copy_x, L)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"id": "167bdc3e",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "37fe75b415d4e31369d6b6bb1041609b",
|
|
"grade": true,
|
|
"grade_id": "cell-e4902309b9869f3d",
|
|
"locked": true,
|
|
"points": 10,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert remains_valid_after_move([[0.1,0.5],[2.1,1.5],[3.2,3.4]],0,[4.5,0.5],5)\n",
|
|
"assert not remains_valid_after_move([[0.1,0.5],[2.1,1.5],[3.2,3.4]],1,[4.5,0.5],5)\n",
|
|
"assert not remains_valid_after_move([[0.1,0.5],[2.1,1.5],[3.2,3.4]],2,[3.2,2.5],5)\n",
|
|
"assert remains_valid_after_move([[0.1,0.5],[2.1,1.5],[3.2,3.4]],2,[3.2,3.8],5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "a8cd0c44",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "markdown",
|
|
"checksum": "8e0cfe7c5bce12cc34e939c5c151ed65",
|
|
"grade": false,
|
|
"grade_id": "cell-582ca3e158908e6c",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"source": [
|
|
"__(d)__ Implement the Metropolis-Hastings transition by selecting a uniformly chosen disk and displacing it by $ (\\delta\\,\\mathcal{N}_1,\\delta\\,\\mathcal{N}_2)$ where $\\delta>0$ is a parameter and $\\mathcal{N}_i$ are independent normal random variables (make sure to keep positions within $[0,L)^2$ by taking the new position modulo $L$). Test run your simulation for $L=11.3$ and $N=20$ and $\\delta = 0.3$ and about $10000$ Markov chain steps and plot the final state. **(15 pts)**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"id": "ccaa8f9f",
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "24f09b7137c0184ddb872ef558f756a9",
|
|
"grade": true,
|
|
"grade_id": "cell-e180b99ca699c610",
|
|
"locked": false,
|
|
"points": 15,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Of 10000 proposed moves, 5019 were taken (50.2%).\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def MH_disk_move(x,L,delta):\n",
|
|
" '''Perform random MH move on configuration x, thus changing the array x (if accepted). \n",
|
|
" Return True if move was accepted, False otherwise.'''\n",
|
|
" \n",
|
|
" # Although it is tempting to use the wacky method of pulling two independent\n",
|
|
" # normal RVs using the method developed two weeks ago, let's just use Numpy.\n",
|
|
" N1, N2 = rng.normal(), rng.normal()\n",
|
|
" n = len(x)\n",
|
|
" i = np.floor(rng.random()*n).astype(int)\n",
|
|
" new_position = x[i] + delta*np.array([N1, N2])\n",
|
|
" new_position %= L\n",
|
|
" \n",
|
|
" if remains_valid_after_move(x, i, new_position, L):\n",
|
|
" x[i] = new_position\n",
|
|
" return True\n",
|
|
" return False\n",
|
|
" \n",
|
|
"# Test run and plot resulting configuration\n",
|
|
"steps = 10000\n",
|
|
"num_moves = 0\n",
|
|
"\n",
|
|
"L = 11.3\n",
|
|
"N = 20\n",
|
|
"delta = .3\n",
|
|
"\n",
|
|
"x = generate_initial_positions(N, L)\n",
|
|
"plot_disk_configuration(x, L)\n",
|
|
"\n",
|
|
"for _ in range(steps):\n",
|
|
" num_moves += MH_disk_move(x, L, delta)\n",
|
|
"\n",
|
|
"plot_disk_configuration(x, L)\n",
|
|
"print(\"Of {} proposed moves, {} were taken ({:.1f}%).\".format(steps, num_moves, num_moves/steps*100))"
|
|
]
|
|
}
|
|
],
|
|
"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.9.12"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|