{"id":22443717,"url":"https://github.com/drdeford/mcmc_intro","last_synced_at":"2025-08-01T18:34:25.567Z","repository":{"id":50272291,"uuid":"177181105","full_name":"drdeford/MCMC_Intro","owner":"drdeford","description":"Friendly and interactive introduction to discrete MCMC","archived":false,"fork":false,"pushed_at":"2019-09-18T23:47:55.000Z","size":4099,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-05-11T09:23:31.045Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://people.csail.mit.edu/ddeford/mcmc_intro.php","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drdeford.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-22T17:13:40.000Z","updated_at":"2022-07-28T01:42:10.000Z","dependencies_parsed_at":"2022-08-25T11:10:44.472Z","dependency_job_id":null,"html_url":"https://github.com/drdeford/MCMC_Intro","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drdeford%2FMCMC_Intro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drdeford%2FMCMC_Intro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drdeford%2FMCMC_Intro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drdeford%2FMCMC_Intro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drdeford","download_url":"https://codeload.github.com/drdeford/MCMC_Intro/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228400689,"owners_count":17914013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-06T02:30:14.206Z","updated_at":"2024-12-06T02:30:14.844Z","avatar_url":"https://github.com/drdeford.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A friendly and interactive introduction to discrete MCMC\n\nThis repo contains the source code for the Sage interact widgets that accompany \u003ca href=\"https://people.csail.mit.edu/ddeford/MCMC_Intro_plus.pdf\"\u003emy notes\u003ca/\u003e introducing discrete MCMC to non-mathematical audiences using Scrabble. Polished and embedded versions of these are organized \u003ca href=\"https://people.csail.mit.edu/ddeford/mcmc_intro.php\"\u003eon my academic webpage\u003c/a\u003e with some additional details. \n\nHere is a fun animation of a Markov chain on the letters of the alphabet, formed by moving between adjacent keys on a standard QWERTY keyboard:\n\n![alt text](https://github.com/drdeford/MCMC_Intro/blob/master/keyboard_walk.gif \"Ant walking on a Keyboard\")\n\nYou can run the versions here by copying the code into my Sage cell terminal \u003ca href=\"https://people.csail.mit.edu/ddeford/sage_cell.html\"\u003ehere\u003c/a\u003e.\n\n***\n\n\u003ch2\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eAs MCMC sampling has become an increasingly popular tool for evaluating districting plans, people from a diverse set of backgrounds are encountering these methods for the first time. These notes \nand Sage Widgets represent my attempt at explaining the underlying ideas in a concrete and friendly fashion, with lots of opportunity for interaction and exploration. Throughout the \u003ca href=\"https://people.csail.mit.edu/ddeford/MCMC_Intro.pdf\"\u003e\n.pdf document\u003c/a\u003e\nthere are many links to individual interactive tools for exploring the ideas further. These tools and brief descriptions of their purposes are linked below. The organizational structure of \nthis page follows that of the accompanying text. \u003c/p\u003e\n\u003cp\u003e\n\nIf you are interested in building your own Sage @interact modules, I have prepared some notes and examples at the bottom of \u003ca href=\"https://people.csail.mit.edu/ddeford/ethics.php\"\u003e this page\u003c/a\u003e. I frequently use these tools\nfor both teaching and research and highly recommend them.\n\u003c/p\u003e\n\n\u003ch4\u003e Scrabble \u003c/h4\u003e \n\u003cp\u003e\nI have always thought that Scrabble tiles are a great tool for teaching Markov chains and MCMC. They are familiar to many people, the tiles themselves come in a non-uniform distribution, and each\ntile has an associated point value that leads to an entirely separate distribution. The table below shows the frequency and point distributions for the American English tileset. \u003c/p\u003e\n\n\n\u003ctable border=\"1\" cellpadding=\"5\" cellspacing=\"5\"\u003e\n\u003ctr\u003e\u003ctd\u003eLetter \u003c/td\u003e  \u003ctd\u003e A\u003c/td\u003e\u003ctd\u003eB\u003c/td\u003e\u003ctd\u003eC\u003c/td\u003e\u003ctd\u003eD\u003c/td\u003e\u003ctd\u003eE\u003c/td\u003e\u003ctd\u003eF\u003c/td\u003e\u003ctd\u003eG\u003c/td\u003e\u003ctd\u003eH\u003c/td\u003e\u003ctd\u003eI\u003c/td\u003e\u003ctd\u003eJ\u003c/td\u003e\u003ctd\u003eK\u003c/td\u003e\u003ctd\u003eL\u003c/td\u003e\u003ctd\u003eM\u003c/td\u003e\u003ctd\u003eN \u003c/td\u003e\u003ctd\u003eO\u003c/td\u003e\u003ctd\u003eP\u003c/td\u003e\u003ctd\u003eQ\u003c/td\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003eS\u003c/td\u003e\u003ctd\u003eT\u003c/td\u003e\u003ctd\u003eU\u003c/td\u003e\u003ctd\u003eV\u003c/td\u003e\u003ctd\u003eW\u003c/td\u003e\u003ctd\u003eX\u003c/td\u003e\u003ctd\u003eY\u003c/td\u003e\u003ctd\u003eZ\u003c/td\u003e\u003ctd\u003e \u003c/td\u003e\u003c/tr\u003e\n     \n \u003ctr\u003e\u003ctd\u003e     Frequency\u003c/td\u003e  \u003ctd\u003e 9\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e12\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e9\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e6 \u003c/td\u003e\u003ctd\u003e8\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e6\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e6\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003c/tr\u003e\n     \n\u003ctr\u003e\u003ctd\u003e\t Score \u003c/td\u003e   \u003ctd\u003e 1\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e8\u003c/td\u003e\u003ctd\u003e5\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e1 \u003c/td\u003e\u003ctd\u003e 1\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e10\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e8\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e10\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp\u003e Throughout these interactive programs, we make use of a few specific Markov chains and score functions that are worth highlighting in advance (full descriptions and plots are also in the .pdf):\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e Markov Chains\u003c/li\u003e\n\u003cul\u003e\n\u003cli\u003e \u003cb\u003eUniform\u003c/b\u003e: Each state is drawn from the uniform distribution over the alphabet.  \u003c/li\u003e\n\u003cli\u003e \u003cb\u003eScrabble Count\u003c/b\u003e: Each state is drawn proportionally to the number of occurences in the Scrabble tileset (with replacement). \u003c/li\u003e\n\u003cli\u003e \u003cb\u003eLetter Path\u003c/b\u003e: A random walk on the path graph with each letter connected to the adjacenct letters in the alphabet with [space] after z (\u003ca href=\"https://github.com/drdeford/MCMC_Intro/blob/master/alpha_path.png\"\u003eExample Figure\u003c/a\u003e).\u003c/li\u003e\n\u003cli\u003e \u003cb\u003eLetter Cycle\u003c/b\u003e: A random walk on the cycle  graph with each letter connected to the adjacenct letters in the alphabet with [space] after z and [space] connected to a (\u003ca href=\"https://github.com/drdeford/MCMC_Intro/blob/master/alpha_cycle.png\"\u003eExample Figure\u003c/a\u003e). \u003c/li\u003e\n\u003cli\u003e \u003cb\u003eKeyboard\u003c/b\u003e: A random walk on adjacent keys of a standard QWERTY keyboard (\u003ca href=\"https://github.com/drdeford/MCMC_Intro/blob/master/keyboard_walk.gif\"\u003eExample Figure\u003c/a\u003e).  \u003c/li\u003e\n\u003c/ul\u003e\n\u003cli\u003eScore Function\u003c/li\u003e\n\u003cul\u003e\n\u003cli\u003e \u003cb\u003eUniform\u003c/b\u003e: Each letter has a score of 1.  \u003c/li\u003e\n\u003cli\u003e \u003cb\u003eNumber of Vowels\u003c/b\u003e: Consonants have score 1, vowels have score 100, and y has score 50. \u003c/li\u003e\n\u003cli\u003e \u003cb\u003eScrabble Points\u003c/b\u003e: The point value of the corresponding Scrabble tile. \u003c/li\u003e\n\u003cli\u003e \u003cb\u003eScrabble Count\u003c/b\u003e: The number of times the Scrabble tile appears in the full tileset. \u003c/li\u003e\n\u003cli\u003e \u003cb\u003eAlphabetical\u003c/b\u003e: a=1, b=2, ... ,z=26, [space]=27. \u003c/li\u003e\n\u003c/ul\u003e\n\n\u003c/ul\u003e\n\u003ch2\u003eProbability Background\u003c/h2\u003e\nThis section introduces the ideas of distributions, random variables, and expected values using examples like rolling a die or drawing a Scrabble tile.\n\n\u003cul\u003e\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/die_rolling.html\"\u003eDie Rolling\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This tool simulates rolling a die repeatedly as an example of draws from a probability distribution. You can adjust the number of faces and labels on the die as well as the number\nof times it is rolled. The output is a plot showing the theoretical distribution as well as one showing the distribution of actual rolls. The individual rolls themselves are also reported.  \u003c/li\u003e\n\u003c/ul\u003e\n \u003c/li\u003e\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/die_expected.html\"\u003eDice Expectations\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This tool attempts to estimate the expected value of a die roll by averaging the values of many rolls. As above, you can change the properties of the die in each experiment. The output \nshows the convergence of the expected value as well as the final estimate, distribution, and error. \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/scrabble_expected.html\"\u003eScrabble Expectations\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This tool attempts to estimate the expected point value of a Scrabble tile drawn from a full bag (with replacement).The output \nshows the convergence of the expected value as well as the final estimate, distribution, and error.  \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\u003c/ul\u003e\n\n\u003ch2\u003eMonte Carlo Sampling\u003c/h2\u003e\nThis section introduces the idea of Monte Carlo sampling as an efficient way to estimate numerical values when we can evaluate random samples easily. \n\u003cul\u003e\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/solitaire.html\"\u003eDeterministic Solitaire\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This tool uses Monte Carlo to evaluate the likelihood of winning a simple, deterministic solitaire game. You can vary the parameters of the game to see how the trace and win percentage evolve.   \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/war.html\"\u003eDeterministic War\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This is a simulation of multiplayer deterministic game whose success rate can be evaluated with Monte Carlo sampling. Game rules are provided in \u003ca href=\"http://people.csail.mit.edu/ddeford/Intro_MCMC.pdf\"\u003ethese slides\u003c/a\u003e.  \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\u003cli\u003e \u003ca href=\"https://math.dartmouth.edu/~doyle/docs/four/four.pdf\"\u003ePan Galactic Solitaire\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This isn't mentioned in the text but my first experiences with Monte Carlo sampling occurred while trying to analyze the game of Pan Galactic Solitaire with Peter Doyle. \nThe \u003ca href=\"PGS1.zip\"\u003e Python source\u003c/a\u003e and a \u003ca href=\"PGS_32bit.zip\"\u003eWindows version\u003c/a\u003e for my implementation of the game are freely available.   \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/cube_dist.html\"\u003eDistances in a cube\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This tool uses Monte Carlo to estimate the expected distance between two points drawn uniformly in a cube.  \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/pi_simple.html\"\u003eSimple Pi Estimator\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This tool estimate pi as the area under a circular arc using Monte Carlo sampling of points in the unit square.  \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\n\u003c/ul\u003e\n\n\n\u003ch2\u003eMarkov Chains\u003c/h2\u003e\nThis section introduces Markov chains and the related concept of walks on graphs. \n\n\u003cul\u003e\n\u003cli\u003e \u003ca href=\"https://github.com/drdeford/MCMC_Intro/blob/master/keyboard_walk.gif\"\u003eAnt-on-a-keyboard\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This is not interactive, just a .gif showing the ant walking on a keyboard Markov chain.  \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/graph_sampling.html\"\u003eWalks on Graphs\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e This tool simulates many walks on a given Markov chain in order to approximate the steady state distribution empirically. You select the chain, number of steps, and number of trials and \nthen the output compares the sampled values to the true steady state distribution. \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/walk_distributions.html\"\u003eMarkov Distributions\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e   This visualization shows how the distribution over states evolves as a Markov chain progresses. You select the chain and an initial state and the output shows a heatmap of the probabilities\nof being in a particular state over time. \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/mc_ev.html\"\u003eMarkov Chain Expected Values\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e  This tool calculates uses samples drawn from a Markov chain to estimate the expected value\nof a specified score distribution over the steady state distribution. You select an initial state, the Markov chain, and a score function and the output shows the convergence and error of\nthe estimated expected value to the true answer. \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\n\u003c/ul\u003e\n\n\u003ch2\u003eMarkov Chain Monte Carlo\u003c/h2\u003e\n\nFinally, we reach the main topic of this discussion, actual MCMC sampling. This section introduces the Metropolis--Hastings variant of MCMC and gives several examples, making use of the \npreviously introduced Markov chains and score functions.  There is only one widget in this section but it incorporates many of the previous tools. \n\u003cul\u003e \n\u003cli\u003e \u003ca href=\"https://people.csail.mit.edu/ddeford/mcmc_letter.html\"\u003eMCMC Sampling\u003c/a\u003e\n\u003cul\u003e\u003cli\u003e This widget allows you to select an initial ``word'', proposal distribution, score distribution, and chain length and then performs MCMC with the chosen parameters. The outputs \nshow the theoretical proposal and score steady state distributions as well as the distributions of states that were actually proposed and accepted in the run. The total variation distance\nbetween the empirical and theoretical distributions is also plotted along with the convergence of the expected value under the score distribution. Finally, the traces and accepted states are\nreported.  \u003c/li\u003e \u003c/ul\u003e \u003c/li\u003e\n\u003c/ul\u003e\n\n\n\u003ch2\u003eMixing Times\u003c/h2\u003e\nAlthough much of the literature on mixing times requires mathematical tools that are beyond the scope of this introduction, this section provides some intuition for how the properties\nof the chain and Metropolis-Hastings waiting process can impact the convergence rate. \n\u003cul\u003e \n\u003cli\u003e \u003ca href=\"mcmc_lmixing.html\"\u003eMixing Comparison\u003c/a\u003e\n\u003cul\u003e\u003cli\u003e This visualization shows how the distribution over states evolves as various MCMC chains progress. You select the proposal distribution and MCMC score function as well as an initial distribution over the states. The initial\ndistribution can either be uniform over the letters, a random probability vector, or a pure state with all of the mass concentrated on a single letter.  The output shows a heatmap of the probabilities\nof being in a particular state over time and compares the total variation distance between the target distribution and the distribution after k steps from the given starting point.  \u003c/li\u003e \u003c/ul\u003e \u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch2\u003eLifted Markov Chains\u003c/h2\u003e\n\nOne approach for forming faster mixing Markov chains is the idea of a \"lifted\" walk, where we make use of an auxiliary graph that has a known rapidly mixing chain.  The key idea is that in well-behaved graphs\n(e.g. those with lots of symmetry) we can construct faster mixing chains by lifting to a larger \ngraph with even nicer properties. Although this is unintuitive at first glance, as we are moving\nto a setting with more nodes to try to get more rapid mixing, this example demonstrates the main properties that make this procedure work. \n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"lifted_walks.html\"\u003eLifted Walks\u003c/a\u003e\u003c/li\u003e\n\u003cul\u003e \n\u003cli\u003eThis interactive explores \u003cb\u003eExample 1.1\u003c/b\u003e presented in the paper \n\u003ca href=\"http://www.math.ucla.edu/~pak/papers/stoc2.pdf\"\u003eLifting Markov Chains to Speed up Mixing\n \u003c/a\u003e by Chen, Lovasz, and Pak. The original walk here is on the path graph with n vertices, which is then lifted to the cycle graph on 2n-2 vertices. You can select\nthe size of the path and how many steps to evaluate and then the simple walk is compared to the lifted one. More theoretical details are provided on the linked page.  \u003c/li\u003e\n\u003c/ul\u003e\n\u003c/ul\u003e\n\n\u003ch2\u003eMCMC for Redistricting\u003c/h2\u003e\n\nThe last section of the notes focuses on applying MCMC methods to the problem of sampling \nlegislative districting plans. This requires both an additional layer of abstraction, as the states\nin our Markov chain are now partitions of graphs instead of individual nodes, as well as more\nconcrete engagement with the real-world data and laws that govern the process. We see how all \nof the concepts introduced in the previous sections - defining the state space, picking a proposal method, \ncomputing the acceptance function, etc. - have to be modified to work in this applied setting. \nThe section concludes with a discussion of annealing and partitions of grids. \n\n\u003cul\u003e\n\u003cli\u003e \u003ca href=\"https://github.com/mggg/gerrychain\"\u003e GerryChain\u003c/a\u003e\u003c/li\u003e\n\u003cul\u003e\n\u003cli\u003e The ideas presented in this section are implemented in the section are implemented in the GerryChain\nsoftare package, developed by VRDI and MGGG. \u003c/li\u003e\n\u003cli\u003e This \u003ca href=\"people.csail.mit.edu/ddeford/GerryChain_Guide.pdf\"\u003eguide\u003c/a\u003e covers the inner workings of the software\nand supplements the material presented on this page with a computational perspective.  \u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cli\u003e\u003ca href=\"https://people.csail.mit.edu/ddeford/CAPR.php\"\u003eComputational Approaches for Political Redistricting\u003c/a\u003e \u003c/li\u003e\n\n\u003cul\u003e\u003cli\u003e  In January 2019 I developed an IAP course on computational redistricting at MIT.\n The course webpage has many more links to software tools and guides for exploring this\nexciting project.  \u003c/ul\u003e\n\n\u003c/ul\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrdeford%2Fmcmc_intro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrdeford%2Fmcmc_intro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrdeford%2Fmcmc_intro/lists"}