934 lines
66 KiB
Plaintext
934 lines
66 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.'''\n",
|
|
" y_list = np.fromiter(graph.neighbors(x), dtype=int)\n",
|
|
" return np.random.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": "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dmvzyJEjy45N1ZS2GOrdRxxmZpaJE4eZWTPefvttjjvuOD7xiU9wwAEHcMstt3DZZZfx6U9/mgMOOIBx48ax6WHqkSNH8t3vfpfDDz+c/fffn/nz53PSSSdRW1vLj3/8YwCWL1/OoEGDGDt2LAcddBAnn3wy69at22q99957L8OHD+fggw/mlFNO4a233gLg7rvvZtCgQRx22GHccccdrbcjEk4cZmbNuPvuu9lrr734xz/+QUNDA8cccwwTJkxg/vz5NDQ08M4772xxqqhz58489NBDjB8/ntGjRzNlyhQaGhqYOXMma9asAQoj4o4bN47HH3+cHj16bPWyqFdffZXLL7+c+++/n4ULF1JXV8eVV17Ju+++y9lnn80f//hHHn74YV5++eVW3RfgxGFm1qwDDzyQ+++/nx/+8Ic8/PDDfPSjH+XBBx9k2LBhHHjggfz5z39m8eJ/jaZ0/PHHb243ZMgQevfuzc4778w+++zDiy8WBg3v168fI0aMAOCMM87gr3/96xbrfPTRR3nyyScZMWIEQ4cOZdasWTz//PP885//ZMCAAdTW1iKJM844o5X2wr/44riZWTP2228/FixYwJw5c7jwwgs5+uijmTJlCvX19fTr149LLrmEd999d3P9TUOv77TTTlsMw77TTjttfk1s6ZDopfMRwVFHHcVNN235VolFixaVHU69NfmIw8ysGStWrGCXXXbhjDPO4IILLmDhwoUA9OrVi7feeovbbrstc58vvPDC5tFub7rpJg477LAtlh966KE88sgjLFu2DIB169bx1FNPMWjQIJ577jmeeeaZzW1bm484zGy70ha3zz7xxBN8//vfZ6eddqJTp05MnTqVP/zhDxx44IH079+fT3/605n73H///Zk1axbnnHMOtbW1fPOb39xieU1NDTNnzmTMmDG89957AFx++eXst99+TJ8+neOOO45evXpx2GGH0dDQ0CLbmVZuw6pXEw+rbq3Bw6rnY0ccVn358uV88YtfbPUf/EqyDKvuU1VmZpaJE4eZWSvr379/VR1tZOXEYWZVrz2cUm9LWfevE4eZVbUuXbqwZs0aJ4+cRARr1qyhS5cuqdv4riozq2p9+/alsbGR1atXt3UoO6wuXbrQt2/Zl7GW5cRhZlWtU6dODBgwoK3DsCI+VWVmZpnkmjgkHSNpqaRlkiaVWT5I0jxJ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\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 = [i + 1 for i in 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": null,
|
|
"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",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()\n",
|
|
"\n",
|
|
"def sample_next_state(graph,x):\n",
|
|
" '''Return next random state y according to MH transition matrix P(x -> y).'''\n",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"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": null,
|
|
"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": [],
|
|
"source": [
|
|
"def chain_P_histogram(graph,start,n):\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",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()\n",
|
|
"\n",
|
|
"def transition_matrix_P(graph):\n",
|
|
" '''Construct transition matrix Q from graph as numpy array.'''\n",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()\n",
|
|
"\n",
|
|
"# plotting\n",
|
|
"# YOUR CODE HERE\n",
|
|
"raise NotImplementedError()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"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": null,
|
|
"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": null,
|
|
"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": [],
|
|
"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": null,
|
|
"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",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()\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",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"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": null,
|
|
"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": null,
|
|
"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": [],
|
|
"source": [
|
|
"def generate_initial_positions(N,L):\n",
|
|
" '''Return array of positions of N disks in non-overlapping positions.'''\n",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()\n",
|
|
" \n",
|
|
"plot_disk_configuration(generate_initial_positions(33,14.5),14.5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"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": null,
|
|
"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",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"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": null,
|
|
"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": [],
|
|
"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",
|
|
" # YOUR CODE HERE\n",
|
|
" raise NotImplementedError()\n",
|
|
"\n",
|
|
"# Test run and plot resulting configuration\n",
|
|
"# YOUR CODE HERE\n",
|
|
"raise NotImplementedError()"
|
|
]
|
|
}
|
|
],
|
|
"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
|
|
}
|