<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://damiandailisan.com/feed.xml" rel="self" type="application/atom+xml"/><link href="https://damiandailisan.com/" rel="alternate" type="text/html" hreflang="en"/><updated>2026-04-02T12:36:56+00:00</updated><id>https://damiandailisan.com/feed.xml</id><title type="html">blank</title><subtitle>&quot;A cornucopia of code used for physics classes.&quot; </subtitle><entry><title type="html">Is complexity science… science?</title><link href="https://damiandailisan.com/blog/2016/complexity-science/" rel="alternate" type="text/html" title="Is complexity science… science?"/><published>2016-06-03T00:00:00+00:00</published><updated>2016-06-03T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/complexity-science</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/complexity-science/"><![CDATA[<h1 id="more-is-really-different">More is really different</h1> <p>The authors used Ising lattices to encode the behavior of a Cellular Automata. In order to do this, they used layers of <em>designer Ising blocks</em>, which would map ground state configurations into corresponding states of the CA. I feel however that in their discussion, the Ising model only served as a sufficiently large state vector in generating just as many different configurations of CAs.</p> <p>That aside, the authors also invoke the use of a Turing machine that interacts with an Ising lattice, such that complete knowledge of the lattice implies complete knowledge of the machine. By arguing that decidability or predictability of $P$, which is dependent on the output of the Turing machine, implies knowledge of the resulting configuration of the CA, but with the contradiction that this can only happen for certain configurations of the CA, they say that $P$ is not decidable, and thus, knowledge of the microscopic states (the Ising lattice underneath) cannot generally predict the macroscopic behavior (Cellular Automata). Thus their claim that complexity is indeed a phenomenon underivable from even a reductionist’s <em>Theory of Everything</em>.</p> <p>Although I agree with the conclusion of the authors, I do believe that the way they presented their argument was a little lackluster. The physicist in me is more used to seeing plots of measurements of their system for different variables, and the many unfamiliar concepts they used in the layering of their model was highly unintuitive and difficult to follow. I believe that the weakness of the argument is it was constructed in more of a <em>tell</em> fashion. Again, I think it would be nice if there was also some <em>showing</em> of actual simulations and plots which could support their claims.</p> <h1 id="from-complexity-to-perplexity">From Complexity to Perplexity</h1> <p>The author tackles some leading ideas in the field of complexity science, particularly among its proponents at the Santa Fe Institute. The first concept he criticizes is the vision of <em>complexologists</em> of a unifying theory of complexity: a bold claim that suggests that a single theory of complexity could explain complex phenomena in different fields. He then proceeds to question how can a field gun for a unifying theory of complexity, when complexologist themselves cannot agree on a proper definition of complexity. While I cannot deny the fact that <strong>there are several ground breaking and interesting insights</strong> resulting from complexity science, I personally agree that it might be too farfetched to claim a unified theory. After all, seeing how difficulty a unifying theory is using the reductionist approach (which by definition I guess means these laws will indeed be common to everything in the universe), it might be much more difficult to find a unifying theory among totally different emergent systems.</p> <p>The author then proceeds to critique <em>Artificial life</em>; computer simulations that use agents following a simple set of rules as a toy model to mimic biological systems. Naomi Oreskes points out one major <em>problem</em> with Artificial life:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"Verification and validation of models of natural systems is impossible."
</code></pre></div></div> <p>True, automata models can never capture the full picture of real systems, nor can we definitely say that we have <em>verified</em> the model even if it fits really well with actual data. Verification is best done when you have knowledge of all relevant variables, and have a way to control and isolate the dependent and independent variables. However, I also believe that the author misses the point: complexity science gives us a tool to simplify a physical system, turn it into a model in which we now have control over some parameters, and see how the system behaves in response to these parameters. In the context of traffic systems, <strong>this is an invaluable tool</strong> since it allows a researcher to <em>mess with traffic</em> without actually screwing over millions of citizens and the economy of a country.</p> <p>Lastly, the author proceeds to tackle the concept of self-organized criticality (SOC) as a defining feature of complexity. Bak, the proponent of SOC, discovered that his sandpile model organizes itself in such a way that when you look at the distribution of avalanche sizes, a power law distribution would emerge. He then went on to note that other real world phenomenon such as the stock market, earthquakes, extinction of species and even human brain waves also exhibit this power law distribution. According to Bak, this power law distribution was the defining feature of SOC, and thus, complexity. This was criticized by Crutchfield, saying the following:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"If a theory applies to everything, it may really to nothing."
"You need not only statistics but also mechanisms."
</code></pre></div></div> <p>Crutchfield is correct in saying that statistics (power law) alone is not enough as a theory for a phenomenon. However, my personal experience working in other complex systems research such as traffic also involves defining mechanisms for the model. These mechanisms limit the validity of predictions that can be obtained from the model itself. In conjunction with statistics, the insights obtained from the model are much more meaningful and insightful.</p> <h1 id="complex-systems-science-dreams-of-universality-reality-of-interdisciplinarity">Complex Systems Science: Dreams of Universality, Reality of Interdisciplinarity</h1> <p>This last paper attempts to deal the crushing blow to complex systems science’s <em>dreams of universality</em>. The authors show that while complex systems science claims that it has found a universal theory for real world systems, the universal trend in the field is the use of computers and computational techniques. They criticize the fact that methodology, rather than theory, is the central denominator to the field of complex systems. Ironically, they arrived at this conclusion using tools that complex systems scientists use: the network.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"To try to become universal, theoretical approaches have to be “translated” into other disciplines."
</code></pre></div></div> <p>Collaboration between disciplines manifested as <em>trading zones</em> shows that the collaboration appeared to one-way rather than mutual. Interestingly, interdisciplinarity of the field suffers from the fact that no experimentalists (to the author’s or my knowledge) actually refer to the results of the theorists of complexity science. It may be that despite its attempts at unifying different fields, the different approach at solving problems may have alienated and discouraged collaboration as well.</p> <p>The take away from all of this is that complex science is far of from being a universal theory, but it has taken some steps in the right direction. Strong interdisciplinarity is key to discovering the possibility (or lack) of a unifying theme for real world systems. As a relatively young science trying to tackle a really large problem (as if reductionism already wasn’t hard enough…), it is reasonable tools and skill building would play a large role in its development. Science shouldn’t really be trigger happy at dismissing emerging theories that show promise, but at the same time, criticisms like this show shortcomings in the approach of a field, and actually provide feedback that can be used to actually improve.</p> <h1 id="final-thoughts">Final thoughts</h1> <p>It is interesting to read all three papers, which actively criticized/supported the field of complexity science. Since my research field somewhat falls within complexity science, I have a rough idea of how the criticisms presented may or may not have merit. I wouldn’t actually say that it was very offensive to me as a researcher, but rather, enlightening that while scientists criticize some claims of complexity science, they also recognize its merits. I see all these articles as a challenge for all complex scientists to up their game, and show that world the impact of this new paradigm of science. Who knows, we might find a universal theory one way or another.</p> <p>So is complexity science a science? <em>Definitely</em>.</p>]]></content><author><name></name></author><category term="Complex Systems"/><summary type="html"><![CDATA[More is really different]]></summary></entry><entry><title type="html">Evolution of a network</title><link href="https://damiandailisan.com/blog/2016/evolution-of-a-network/" rel="alternate" type="text/html" title="Evolution of a network"/><published>2016-05-01T00:00:00+00:00</published><updated>2016-05-01T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/evolution-of-a-network</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/evolution-of-a-network/"><![CDATA[<h2 id="netdimes-project">Netdimes project</h2> <p>We want to look at the growth of Autonomous Server (AS) networks found in the <a href="http://www.netdimes.org/new/?q=node/65">netdimes project</a> to see how a network grows over time. In particular, we are looking at nodes in the year 2011. First, let us load the data we have downloaded:</p> <p><strong>In [8]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="o">%</span><span class="n">config</span> <span class="n">InlineBackend</span><span class="p">.</span><span class="n">figure_format</span> <span class="o">=</span> <span class="sh">'</span><span class="s">svg</span><span class="sh">'</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="kn">import</span> <span class="n">networkx</span> <span class="k">as</span> <span class="n">nx</span>
<span class="kn">from</span> <span class="n">statsmodels.distributions.empirical_distribution</span> <span class="kn">import</span> <span class="n">ECDF</span>
<span class="kn">import</span> <span class="n">seaborn</span> <span class="k">as</span> <span class="n">sns</span>
<span class="n">sns</span><span class="p">.</span><span class="nf">set_style</span><span class="p">(</span><span class="sh">'</span><span class="s">whitegrid</span><span class="sh">'</span><span class="p">)</span>
<span class="n">color</span> <span class="o">=</span> <span class="n">sns</span><span class="p">.</span><span class="nf">color_palette</span><span class="p">(</span><span class="sh">'</span><span class="s">bright</span><span class="sh">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">month</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">Jan</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Feb</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Mar</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Apr</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">May</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Jun</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Jul</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Aug</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Sept</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Oct</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Nov</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Dec</span><span class="sh">'</span><span class="p">]</span>
<span class="n">edges</span> <span class="o">=</span> <span class="n">glob</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="sh">'</span><span class="s">ASEdge*</span><span class="sh">'</span><span class="p">)</span>
<span class="n">nodes</span> <span class="o">=</span> <span class="n">glob</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="sh">'</span><span class="s">ASNode*</span><span class="sh">'</span><span class="p">)</span>
<span class="n">edgelist</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="n">edges</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">header</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
<span class="n">nodelist</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="n">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">header</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span></code></pre></figure> <h2 id="size">Size</h2> <p>Easy stuff first: let’s look at how the size of the network grows over time. Note that this time period is just one year.</p> <p><strong>In [9]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">size_nodes</span> <span class="o">=</span> <span class="p">[</span><span class="nf">len</span><span class="p">(</span><span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="sh">'</span><span class="s">ASNodes%s_2011.csv.gz</span><span class="sh">'</span><span class="o">%</span><span class="n">i</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="bp">None</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">11</span><span class="p">)]</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sh">"</span><span class="s">2011</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Nodes</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="n">size_nodes</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="sh">'</span><span class="s">-</span><span class="sh">'</span><span class="p">,</span> <span class="n">marker</span><span class="o">=</span><span class="sh">'</span><span class="s">o</span><span class="sh">'</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="sh">"</span><span class="s">Magnitude</span><span class="sh">"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xticklabels</span><span class="p">(</span><span class="n">month</span><span class="p">[:</span><span class="mi">10</span><span class="p">])</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">legend</span><span class="p">()</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.legend.Legend at 0xd21c518&gt;
</code></pre></div></div> <p><img src="/assets/posts/evolution-of-a-network_files/evolution-of-a-network_3_1.svg" alt="svg"/></p> <p>So it appears as if the size of the AS network id more or less decreasing throughout the year. This is interesting, as I’d expect 2011 to be a year of strong growth of the internet. Nonetheless, this is server networks we are looking at, and 10 months is also a short timeframe.</p> <h2 id="degree-distributions">Degree Distributions</h2> <p>We are going to use <code class="language-plaintext highlighter-rouge">networkx</code> to assemble the internet network. We will do this first for one month of the dataset:</p> <p><strong>In [10]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="n">edgelist</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="sh">'</span><span class="s">ASEdges%s_2011.csv.gz</span><span class="sh">'</span><span class="o">%</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">),</span> <span class="n">header</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
<span class="n">nodelist</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="sh">'</span><span class="s">ASNodes%s_2011.csv.gz</span><span class="sh">'</span><span class="o">%</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">),</span> <span class="n">header</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
<span class="n">g</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nc">Graph</span><span class="p">()</span>
<span class="n">g</span><span class="p">.</span><span class="nf">add_nodes_from</span><span class="p">(</span><span class="n">nodelist</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">g</span><span class="p">.</span><span class="nf">add_edges_from</span><span class="p">(</span><span class="nf">tuple</span><span class="p">(</span><span class="nf">zip</span><span class="p">(</span><span class="n">edgelist</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">values</span><span class="p">,</span> <span class="n">edgelist</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">values</span><span class="p">)))</span>
<span class="n">degree</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nf">degree</span><span class="p">(</span><span class="n">g</span><span class="p">).</span><span class="nf">values</span><span class="p">()</span>
<span class="n">ecdf_deg</span> <span class="o">=</span> <span class="nc">ECDF</span><span class="p">(</span><span class="n">degree</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="n">ecdf_deg</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">1</span><span class="o">-</span><span class="n">ecdf_deg</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">month</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">color</span><span class="o">=</span><span class="n">color</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_yscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Degree</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sh">"</span><span class="s">CCDF</span><span class="sh">"</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">legend</span><span class="p">()</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.legend.Legend at 0x1209d7f0&gt;
</code></pre></div></div> <p><img src="/assets/posts/evolution-of-a-network_files/evolution-of-a-network_6_1.svg" alt="svg"/></p> <p>We can zoom in at the middle part:</p> <p><strong>In [11]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">ax</span><span class="p">.</span><span class="nf">set_xlim</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">1000</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylim</span><span class="p">(</span><span class="mf">1e-3</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">)</span>
<span class="n">fig</span></code></pre></figure> <p><img src="/assets/posts/evolution-of-a-network_files/evolution-of-a-network_8_0.svg" alt="svg"/></p> <p>The graphs show that there is a general shift towards the lower left part of the curve as the months go by. This is consistent with the observed decrease in size of the networks. At the same time, the degree distributions of the networks still exhibit power law behavior, which is expected: the degree distribution of the network is a manifestation of the real world behavior of how servers connect to each other.</p> <h2 id="clustering-coefficient">Clustering coefficient</h2> <p>Let us look at the clustering coefficient. This metric will give us an idea how interconnected nodes are as the year progresses.</p> <p><strong>In [12]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">config</span> <span class="n">InlineBackend</span><span class="p">.</span><span class="n">figure_format</span> <span class="o">=</span> <span class="sh">'</span><span class="s">jpg</span><span class="sh">'</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="n">edgelist</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="sh">'</span><span class="s">ASEdges%s_2011.csv.gz</span><span class="sh">'</span><span class="o">%</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">),</span> <span class="n">header</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
<span class="n">nodelist</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="sh">'</span><span class="s">ASNodes%s_2011.csv.gz</span><span class="sh">'</span><span class="o">%</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">),</span> <span class="n">header</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
<span class="n">g</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nc">Graph</span><span class="p">()</span>
<span class="n">g</span><span class="p">.</span><span class="nf">add_nodes_from</span><span class="p">(</span><span class="n">nodelist</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">g</span><span class="p">.</span><span class="nf">add_edges_from</span><span class="p">(</span><span class="nf">tuple</span><span class="p">(</span><span class="nf">zip</span><span class="p">(</span><span class="n">edgelist</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">values</span><span class="p">,</span> <span class="n">edgelist</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">values</span><span class="p">)))</span>
<span class="n">cluster</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nf">clustering</span><span class="p">(</span><span class="n">g</span><span class="p">).</span><span class="nf">values</span><span class="p">()</span>
<span class="n">ecdf_clust</span> <span class="o">=</span> <span class="nc">ECDF</span><span class="p">(</span><span class="n">cluster</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="n">ecdf_clust</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">1</span><span class="o">-</span><span class="n">ecdf_clust</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">month</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">color</span><span class="o">=</span><span class="n">color</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Clustering Coefficient</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sh">"</span><span class="s">CCDF</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylim</span><span class="p">(</span><span class="mf">0.1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">legend</span><span class="p">()</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.legend.Legend at 0xa7c1748&gt;
</code></pre></div></div> <p><img src="/assets/posts/evolution-of-a-network_files/evolution-of-a-network_11_1.jpe" alt="jpeg"/></p> <p>Once again, there is a decreasing trend. Since this is a CCDF, we can say that there are a lot more nodes with low clustering coefficients although nodes are decreasing. This might imply that the nodes being removed are those which have a low tendency to form clusters. It makes sense, as you can think of important nodes have a higher tendency to be a part of clusters, and thus servers that are removed in the network are those that are less important.</p>]]></content><author><name></name></author><category term="Python"/><category term="Complex Systems"/><summary type="html"><![CDATA[Netdimes project]]></summary></entry><entry><title type="html">Earthquake Networks</title><link href="https://damiandailisan.com/blog/2016/earthquake-networks/" rel="alternate" type="text/html" title="Earthquake Networks"/><published>2016-04-13T00:00:00+00:00</published><updated>2016-04-13T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/earthquake-networks</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/earthquake-networks/"><![CDATA[<h2 id="earthquake-data">Earthquake Data</h2> <p>I got the earthquake data from <a href="http://www.phivolcs.dost.gov.ph/html/update_SOEPD/EQLatest.html">Phivolcs</a> website for earthquake that occured between March 1-9, 2016. The data was saved to a <code class="language-plaintext highlighter-rouge">csv</code> file to be processed by <code class="language-plaintext highlighter-rouge">python</code>. As is, the data did not need that much cleaning. I also used <code class="language-plaintext highlighter-rouge">pandas</code> to manage the data.</p> <p><strong>In [2]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">from</span> <span class="o">**</span><span class="n">future</span><span class="o">**</span> <span class="kn">import</span> <span class="n">division</span><span class="p">,</span> <span class="n">print_function</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">networkx</span> <span class="k">as</span> <span class="n">nx</span>
<span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>

<span class="n">earthquake_df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="sh">'</span><span class="s">seismic.csv</span><span class="sh">'</span><span class="p">)</span>

<span class="n">earthquake_df</span><span class="p">[</span><span class="sh">'</span><span class="s">Datetime</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">pd</span><span class="p">.</span><span class="nf">to_datetime</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">earthquake_df</span><span class="p">[</span><span class="sh">'</span><span class="s">Date - Time</span><span class="sh">'</span><span class="p">]]</span>
<span class="n">earthquake_df</span> <span class="o">=</span> <span class="n">earthquake_df</span><span class="p">.</span><span class="nf">sort_values</span><span class="p">(</span><span class="sh">'</span><span class="s">Datetime</span><span class="sh">'</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">kind</span><span class="o">=</span><span class="sh">'</span><span class="s">quicksort</span><span class="sh">'</span><span class="p">)</span>
<span class="n">earthquake_df</span><span class="p">.</span><span class="nf">reset_index</span><span class="p">(</span><span class="n">drop</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">inplace</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">earthquake_df</span> <span class="o">=</span> <span class="n">earthquake_df</span><span class="p">.</span><span class="nf">drop</span><span class="p">([</span><span class="sh">'</span><span class="s">Date - Time</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Location</span><span class="sh">'</span><span class="p">],</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span></code></pre></figure> <p>In creating the network, we will need information about the distance between two earthquake epicentres. The euclidean distance is inappropriate for this as the distances are on the surface of the Earth, which is not a flat plane. Instead, we will use the great circle distance or <code class="language-plaintext highlighter-rouge">haversine</code> formula, defined as follows:</p> <p><strong>In [3]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">haversine</span><span class="p">(</span><span class="n">loc1</span><span class="p">,</span> <span class="n">loc2</span><span class="p">):</span>
<span class="sh">"""</span><span class="s">
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
</span><span class="sh">"""</span>
<span class="n">lon1</span><span class="p">,</span> <span class="n">lat1</span> <span class="o">=</span> <span class="n">loc1</span><span class="p">[</span><span class="sh">'</span><span class="s">Longitude</span><span class="sh">'</span><span class="p">],</span> <span class="n">loc1</span><span class="p">[</span><span class="sh">'</span><span class="s">Latitude</span><span class="sh">'</span><span class="p">]</span>
<span class="n">lon2</span><span class="p">,</span> <span class="n">lat2</span> <span class="o">=</span> <span class="n">loc2</span><span class="p">[</span><span class="sh">'</span><span class="s">Longitude</span><span class="sh">'</span><span class="p">],</span> <span class="n">loc2</span><span class="p">[</span><span class="sh">'</span><span class="s">Latitude</span><span class="sh">'</span><span class="p">]</span> <span class="c1"># convert decimal degrees to radians
</span><span class="n">lon1</span><span class="p">,</span> <span class="n">lat1</span><span class="p">,</span> <span class="n">lon2</span><span class="p">,</span> <span class="n">lat2</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">radians</span><span class="p">([</span><span class="n">lon1</span><span class="p">,</span> <span class="n">lat1</span><span class="p">,</span> <span class="n">lon2</span><span class="p">,</span> <span class="n">lat2</span><span class="p">])</span> <span class="c1"># haversine formula
</span><span class="n">dlon</span> <span class="o">=</span> <span class="n">lon2</span> <span class="o">-</span> <span class="n">lon1</span>
<span class="n">dlat</span> <span class="o">=</span> <span class="n">lat2</span> <span class="o">-</span> <span class="n">lat1</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="n">dlat</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">np</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="n">lat1</span><span class="p">)</span> <span class="n">_</span> <span class="n">np</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="n">lat2</span><span class="p">)</span> <span class="n">_</span> <span class="n">np</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="n">dlon</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span>
<span class="n">c</span> <span class="o">=</span> <span class="mi">2</span> <span class="n">_</span> <span class="n">np</span><span class="p">.</span><span class="nf">arcsin</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
<span class="n">km</span> <span class="o">=</span> <span class="mi">6367</span> <span class="n">_</span> <span class="n">c</span>
<span class="k">return</span> <span class="n">km</span></code></pre></figure> <h2 id="network-construction">Network construction</h2> <p>We will construct the earthquake network using locations of the earthquakes as nodes. The edges between the nodes will depend on the <em>Nearest record breaking</em> criterion which has the following rules:</p> <ol> <li>Two earthquakes $i$ and $j$ are connected if the occur consecutively in time.</li> <li>An earthquake $k$ is connected to past earthquakes $i$ if the new earthquake breaks the record $R_{ij}$ of previous earthquake pairs.</li> </ol> <p>An earthquake record of a earthquake $i$ is the current shortest distance between all other earthquake $j$. Thus a new earthquake $k$ is connected to an older earthquake $i$ if $R_{ik}&lt;R_{ij}$.</p> <p><strong>In [4]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="o">%</span><span class="n">config</span> <span class="n">InlineBackend</span><span class="p">.</span><span class="n">figure_format</span> <span class="o">=</span> <span class="sh">'</span><span class="s">svg</span><span class="sh">'</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">import</span> <span class="n">networkx</span> <span class="k">as</span> <span class="n">nx</span>

<span class="n">loc</span> <span class="o">=</span> <span class="n">earthquake_df</span><span class="p">[[</span><span class="sh">'</span><span class="s">Longitude</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Latitude</span><span class="sh">'</span><span class="p">]]</span>

<span class="n">G</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nc">DiGraph</span><span class="p">()</span>

<span class="n">nodes</span> <span class="o">=</span> <span class="n">earthquake_df</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">values</span>
<span class="n">G</span><span class="p">.</span><span class="nf">add_nodes_from</span><span class="p">(</span><span class="n">nodes</span><span class="p">)</span>
<span class="n">magnitude</span> <span class="o">=</span> <span class="p">[</span><span class="n">earthquake_df</span><span class="p">[</span><span class="sh">'</span><span class="s">Mag</span><span class="sh">'</span><span class="p">][</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">nodes</span><span class="p">]</span>
<span class="n">nx</span><span class="p">.</span><span class="nf">set_node_attributes</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="sh">'</span><span class="s">datetime</span><span class="sh">'</span><span class="p">,</span> <span class="n">earthquake_df</span><span class="p">[</span><span class="sh">'</span><span class="s">Datetime</span><span class="sh">'</span><span class="p">].</span><span class="nf">tolist</span><span class="p">())</span>
<span class="n">nx</span><span class="p">.</span><span class="nf">set_node_attributes</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="sh">'</span><span class="s">record</span><span class="sh">'</span><span class="p">,</span> <span class="mf">1e10</span><span class="p">)</span>

<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="nf">len</span><span class="p">(</span><span class="n">earthquake_df</span><span class="p">[</span><span class="sh">'</span><span class="s">Datetime</span><span class="sh">'</span><span class="p">])):</span>
<span class="n">distance</span> <span class="o">=</span> <span class="nf">haversine</span><span class="p">(</span><span class="n">loc</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">loc</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">G</span><span class="p">.</span><span class="nf">add_edge</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">i</span><span class="p">,</span> <span class="p">{</span><span class="sh">'</span><span class="s">distance</span><span class="sh">'</span><span class="p">:</span><span class="n">distance</span><span class="p">})</span>
<span class="n">G</span><span class="p">.</span><span class="n">node</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="sh">'</span><span class="s">record</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="n">distance</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">i</span><span class="p">):</span>
<span class="n">node_dist</span> <span class="o">=</span> <span class="nf">haversine</span><span class="p">(</span><span class="n">loc</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">loc</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
<span class="k">if</span> <span class="n">node_dist</span> <span class="o">&lt;</span> <span class="n">G</span><span class="p">.</span><span class="n">node</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="sh">'</span><span class="s">record</span><span class="sh">'</span><span class="p">]:</span>
<span class="n">G</span><span class="p">.</span><span class="n">node</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="sh">'</span><span class="s">record</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="n">node_dist</span>
<span class="n">G</span><span class="p">.</span><span class="nf">add_edge</span><span class="p">(</span><span class="n">j</span><span class="p">,</span><span class="n">i</span><span class="p">,</span> <span class="p">{</span><span class="sh">'</span><span class="s">distance</span><span class="sh">'</span><span class="p">:</span><span class="n">node_dist</span><span class="p">})</span></code></pre></figure> <p><strong>In [5]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">import</span> <span class="n">mplleaflet</span>
<span class="kn">from</span> <span class="n">mpl_toolkits.basemap</span> <span class="kn">import</span> <span class="n">Basemap</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">m</span> <span class="o">=</span> <span class="nc">Basemap</span><span class="p">(</span><span class="n">projection</span><span class="o">=</span><span class="sh">'</span><span class="s">merc</span><span class="sh">'</span><span class="p">,</span><span class="n">llcrnrlat</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span><span class="n">urcrnrlat</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">resolution</span><span class="o">=</span><span class="sh">'</span><span class="s">i</span><span class="sh">'</span><span class="p">,</span>
<span class="n">llcrnrlon</span><span class="o">=</span><span class="mi">117</span><span class="p">,</span><span class="n">urcrnrlon</span><span class="o">=</span><span class="mi">128</span><span class="p">,</span> <span class="n">lat_ts</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">ellps</span><span class="o">=</span><span class="sh">'</span><span class="s">WGS84</span><span class="sh">'</span><span class="p">)</span>
<span class="n">m</span><span class="p">.</span><span class="nf">drawcountries</span><span class="p">(</span><span class="n">zorder</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="n">m</span><span class="p">.</span><span class="nf">fillcontinents</span><span class="p">(</span><span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">#555555</span><span class="sh">'</span><span class="p">)</span>
<span class="n">m</span><span class="p">.</span><span class="nf">drawmapboundary</span><span class="p">(</span><span class="n">fill_color</span><span class="o">=</span><span class="sh">'</span><span class="s">#111111</span><span class="sh">'</span><span class="p">)</span>

<span class="c1"># positions = {i:tuple(loc.iloc[i].values) for i in nodes}
</span>
<span class="n">positions</span> <span class="o">=</span> <span class="p">{</span><span class="n">i</span><span class="p">:</span><span class="nf">m</span><span class="p">(</span>\<span class="o">*</span><span class="n">loc</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">values</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">nodes</span><span class="p">}</span>

<span class="n">s</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nf">draw_networkx_nodes</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="n">ax</span><span class="o">=</span><span class="n">ax</span><span class="p">,</span> <span class="n">pos</span><span class="o">=</span><span class="n">positions</span><span class="p">,</span> <span class="n">node_color</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">(</span><span class="n">magnitude</span><span class="p">),</span>
<span class="n">alpha</span><span class="o">=</span><span class="mf">0.7</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">'</span><span class="s">YlOrRd</span><span class="sh">'</span><span class="p">,</span> <span class="n">with_labels</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">s</span><span class="p">.</span><span class="nf">set_zorder</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">edges</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nf">draw_networkx_edges</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="n">ax</span><span class="o">=</span><span class="n">ax</span><span class="p">,</span> <span class="n">pos</span><span class="o">=</span><span class="n">positions</span><span class="p">,</span> <span class="n">edge_color</span><span class="o">=</span><span class="sh">"</span><span class="s">#aaaaaa</span><span class="sh">"</span><span class="p">,</span> <span class="n">arrows</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">edges</span><span class="p">.</span><span class="nf">set_zorder</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span></code></pre></figure> <p><img src="/assets/posts/earthquake-networks_files/earthquake-networks_6_0.svg" alt="svg"/></p> <p>Connections in this network are directed. The directionality of links actually implies some possible causal relation, hence, the directionality also tells us the relative sequence of events. Future events do not point to past events, but past events can point to future events.</p> <h2 id="degree-distributions">Degree distributions</h2> <p>The degree distribution is one of the usual metrics by which networks are characterized. The earthquake network created in this entry is a directed graph, wherein the directionality of links is important. Thus, we characterize the in and out degree distributions of the network.</p> <p><strong>In [6]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">from</span> <span class="n">statsmodels.distributions.empirical_distribution</span> <span class="kn">import</span> <span class="n">ECDF</span>
<span class="n">out_deg</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sort</span><span class="p">(</span><span class="n">G</span><span class="p">.</span><span class="nf">out_degree</span><span class="p">().</span><span class="nf">values</span><span class="p">())</span>
<span class="n">in_deg</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sort</span><span class="p">(</span><span class="n">G</span><span class="p">.</span><span class="nf">in_degree</span><span class="p">().</span><span class="nf">values</span><span class="p">())</span>

<span class="k">def</span> <span class="nf">degree_distribution</span><span class="p">(</span><span class="n">degree</span><span class="p">):</span>

    <span class="n">frequency</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">degree</span><span class="p">))</span><span class="o">/</span><span class="nf">float</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">degree</span><span class="p">))</span>
    <span class="n">ecdf</span> <span class="o">=</span> <span class="nc">ECDF</span><span class="p">(</span><span class="n">degree</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">ecdf</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">1</span><span class="o">-</span><span class="n">ecdf</span><span class="p">.</span><span class="n">y</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>

<span class="c1"># ax.scatter(degree, 1-frequency)
</span>
<span class="c1"># ax.step(ecdf.x, 1-ecdf.y)
</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_yscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Degree</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sh">"</span><span class="s">CCDF</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="o">*</span><span class="nf">degree_distribution</span><span class="p">(</span><span class="n">out_deg</span><span class="p">),</span> <span class="n">label</span><span class="o">=</span><span class="sh">"</span><span class="s">Out Degree</span><span class="sh">"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="o">*</span><span class="nf">degree_distribution</span><span class="p">(</span><span class="n">in_deg</span><span class="p">),</span> <span class="n">label</span><span class="o">=</span><span class="sh">"</span><span class="s">In Degree</span><span class="sh">"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">b</span><span class="sh">'</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">legend</span><span class="p">()</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.legend.Legend at 0xa258a20&gt;
</code></pre></div></div> <p><img src="/assets/posts/earthquake-networks_files/earthquake-networks_9_1.svg" alt="svg"/></p> <p>Unfortunately the dataset only contained 69 earthquakes, which is too small to one order of magnitude.</p> <p>At first glance, it appears that there are more high out-degree nodes than in- degree ones. This tells us that we can link more previous quakes to many different subsequent quakes. On the other hand, there are less connections that can be made as to which previous earthquakes are connected to a future earthquake.</p> <p>I believe that a possible insight we can get from this small dataset is that a single earthquake can cascade into more earthquakes. This is a reasonable claim since we have an idea of the concept of aftershocks produced by earthquakes. However, the size of the dataset is insufficient to back up any claims we draw from the data.</p> <h2 id="magnitude-distribution">Magnitude distribution</h2> <p>Finally, we’ll look into the magnitude distribution of the Earthquakes in the recorded period. This analysis is a purely statistical one, independent of the network structure of the earthquakes. Let’s start by plotting the CCDF of the earthquakes.</p> <p><strong>In [7]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">magnitude</span> <span class="o">=</span> <span class="n">earthquake_df</span><span class="p">[</span><span class="sh">'</span><span class="s">Mag</span><span class="sh">'</span><span class="p">]</span>

<span class="n">frequency</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">magnitude</span><span class="p">))</span><span class="o">/</span><span class="nf">float</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">magnitude</span><span class="p">))</span>
<span class="n">ecdf</span> <span class="o">=</span> <span class="nc">ECDF</span><span class="p">(</span><span class="n">magnitude</span><span class="p">)</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_yscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Magnitude</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sh">"</span><span class="s">CCDF</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="n">ecdf</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">1</span><span class="o">-</span><span class="n">ecdf</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">legend</span><span class="p">()</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.legend.Legend at 0x8a4feb8&gt;
</code></pre></div></div> <p><img src="/assets/posts/earthquake-networks_files/earthquake-networks_12_1.svg" alt="svg"/></p> <p>At first glance, we cannot characterize the distribution that results as a power law. the low slope at low magnitudes means that there are only a few low magnitude earthquakes recorded. This can most likely be attributed to the data gathering of Phivolcs, wherein not all earthquakes are recorded. It would appear that their cutoff is less than magnitude 1.9.</p> <p>The sharp slope around 3 indicates that most earthquakes that occur are within this magnitude. Unfortunately, as is with the degree distributions, the size of the dataset is not significant enough to draw meaningful analysis from the distribution of data.</p> <h2 id="clustering-coefficient-distribution">Clustering coefficient distribution</h2> <p><strong>In [12]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">cluster</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nf">clustering</span><span class="p">(</span><span class="n">G</span><span class="p">.</span><span class="nf">to_undirected</span><span class="p">()).</span><span class="nf">values</span><span class="p">()</span>

<span class="n">ecdf_clust</span> <span class="o">=</span> <span class="nc">ECDF</span><span class="p">(</span><span class="n">cluster</span><span class="p">)</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>

<span class="c1"># ax.set_xscale('log')
</span>
<span class="c1"># ax.set_yscale('log')
</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Clustering coefficient</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sh">"</span><span class="s">CDF</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="n">ecdf_clust</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">ecdf_clust</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="sh">'</span><span class="s">best</span><span class="sh">'</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>E:\Applications\Anaconda\lib\site-packages\matplotlib\axes\_axes.py:519: UserWarning: No labelled objects found. Use label='...' kwarg on individual plots.
  warnings.warn("No labelled objects found. "
</code></pre></div></div> <p><img src="/assets/posts/earthquake-networks_files/earthquake-networks_15_1.svg" alt="svg"/></p> <p>The clustering coefficient distribution has a sharp increase at the center, flattening out at the extreme values. The form of this CDF appears to be <a href="https://en.wikipedia.org/wiki/Norm al_distribution#Cumulative_distribution_function">gaussian</a>, shifted to the lower clustering coefficients. The clustering coefficients obtained are indeed larger than a <a href="https://en.wikipedia.org/wiki/Network_science#Erd.C5.91s.E2.8 0.93R.C3.A9nyi_Random_Graph_model">randomly connected network</a>, implying the fact that there is an underlying structure in the network. Naturally, we’d expect that this is a consequence of the network construct</p>]]></content><author><name></name></author><category term="Python"/><category term="Complex Systems"/><summary type="html"><![CDATA[Earthquake Data]]></summary></entry><entry><title type="html">Erdos-Renyi Network Metrics</title><link href="https://damiandailisan.com/blog/2016/erdos-renyi-network-metrics/" rel="alternate" type="text/html" title="Erdos-Renyi Network Metrics"/><published>2016-04-05T00:00:00+00:00</published><updated>2016-04-05T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/erdos-renyi-network-metrics</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/erdos-renyi-network-metrics/"><![CDATA[<p>The Erdos Renyi networks consist of nodes that have a probability $p$ to be connected to other nodes. This is otherwise known as a random network, and its statistical properties and characteristics are well studied. In this entry, we will be looking at the following:</p> <h2 id="table-of-contents">Table of Contents</h2> <ol> <li><a href="#creating-an-adjacency-matrix">Creating an Adjacency Matrix</a></li> <li><a href="#average-degree">Average Degree</a></li> <li><a href="#average-clustering-coefficient">Average Clustering Coefficient</a></li> <li><a href="#average-shortest-path-length">Average Shortest Path Length</a></li> <li><a href="#references">References</a></li> </ol> <h2 id="creating-an-adjacency-matrix">Creating an Adjacency Matrix</h2> <p>Before the days of <code class="language-plaintext highlighter-rouge">networkx</code>, networks were defined using adjacency matrices. The values of the adjacency matrix $A$ are given by \begin{equation} A<em>{ij} = 1 \end{equation} when node $i$ is connected to node $j$. In undirected networks, $A</em>{ij}=A_{ji}$, while this is not necessarily the case for directed networks.</p> <p><strong>In [1]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="o">%</span><span class="n">config</span> <span class="n">InlineBackend</span><span class="p">.</span><span class="n">figure_format</span> <span class="o">=</span> <span class="sh">'</span><span class="s">svg</span><span class="sh">'</span>
<span class="k">from</span> <span class="o">**</span><span class="n">future</span><span class="o">**</span> <span class="kn">import</span> <span class="n">division</span><span class="p">,</span> <span class="n">print_function</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">import</span> <span class="n">seaborn</span> <span class="k">as</span> <span class="n">sns</span>

<span class="k">def</span> <span class="nf">erdos_renyi</span><span class="p">(</span><span class="n">N</span><span class="o">=</span><span class="mi">10000</span><span class="p">,</span><span class="n">p</span><span class="o">=</span><span class="mf">0.3</span><span class="p">):</span>
<span class="n">adj</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">((</span><span class="n">N</span><span class="p">,</span><span class="n">N</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">bool</span><span class="p">)</span>

    <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
        <span class="n">adj</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">k</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="nf">random</span><span class="p">(</span><span class="n">N</span><span class="o">-</span><span class="p">(</span><span class="n">k</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span><span class="o">&lt;</span><span class="n">p</span>

    <span class="n">adj</span> <span class="o">+=</span> <span class="n">adj</span><span class="p">.</span><span class="nf">transpose</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">adj</span>

<span class="k">def</span> <span class="nf">degree</span><span class="p">(</span><span class="n">adj</span><span class="p">):</span>
<span class="n">k</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">adj</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="k">return</span> <span class="n">k</span></code></pre></figure> <h2 id="average-degree">Average Degree</h2> <p>The degree of a node is defined to be the number of edges that node is a part of. For an Erdos-Renyi network, we expect the average degree to be \begin{equation}\langle k \rangle = Np, \end{equation} for large networks $N$.</p> <p><strong>In [2]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">k</span> <span class="o">=</span> <span class="nf">degree</span><span class="p">(</span><span class="nf">erdos_renyi</span><span class="p">())</span>
<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">histogram</span> <span class="o">=</span> <span class="n">ax</span><span class="p">.</span><span class="nf">hist</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">histtype</span><span class="o">=</span><span class="sh">'</span><span class="s">stepfilled</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Degree</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sh">"</span><span class="s">Frequency</span><span class="sh">"</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.text.Text at 0x9cce7f0&gt;
</code></pre></div></div> <p><img src="/assets/posts/erdos-renyi-network-metrics_files/erdos-renyi-network-metrics_4_1.svg" alt="svg"/></p> <p><strong>In [3]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">N</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mf">0.1</span><span class="p">)</span>
<span class="n">degrees</span> <span class="o">=</span> <span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="nf">average</span><span class="p">(</span><span class="nf">degree</span><span class="p">(</span><span class="nf">erdos_renyi</span><span class="p">(</span><span class="nf">int</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">n</span><span class="p">))))</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">N</span><span class="p">]</span></code></pre></figure> <p><strong>In [4]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">from</span> <span class="n">scipy</span> <span class="kn">import</span> <span class="n">stats</span>

<span class="n">slope</span><span class="p">,</span> <span class="n">intercept</span><span class="p">,</span> <span class="n">r_value</span><span class="p">,</span> <span class="n">p_value</span><span class="p">,</span> <span class="n">std_err</span> <span class="o">=</span> <span class="n">stats</span><span class="p">.</span><span class="nf">linregress</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">N</span><span class="p">,</span><span class="n">degrees</span><span class="p">)</span>
<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">N</span><span class="p">,</span> <span class="mi">10</span><span class="o">**</span><span class="n">N</span>\<span class="o">*</span><span class="n">slope</span><span class="o">+</span><span class="n">intercept</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="sh">"</span><span class="s">--</span><span class="sh">"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">scatter</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">N</span><span class="p">,</span> <span class="n">degrees</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$N$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$\langle k \rangle$</span><span class="sh">"</span><span class="p">)</span>

<span class="nf">print</span><span class="p">(</span><span class="sa">r</span><span class="sh">'</span><span class="s">$\langle k \rangle = %s $</span><span class="sh">'</span> <span class="o">%</span> <span class="n">slope</span><span class="p">,</span> <span class="sh">"</span><span class="s">, p=</span><span class="sh">"</span><span class="p">,</span> <span class="n">p_value</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$\langle k \rangle = 0.300024590071 $ , p= 1.69578686191e-114
</code></pre></div></div> <p><img src="/assets/posts/erdos-renyi-network-metrics_files/erdos-renyi-network-metrics_6_1.svg" alt="svg"/></p> <h2 id="average-clustering-coefficient">Average Clustering Coefficient</h2> <p>The clustering coefficient $C_i$ of a node $i$ is defined by the equation \begin{equation} C_i = \frac{2t_i}{k_i(k_i-1)}, \end{equation} where $t_i$ is the number of triangles that contain the node, and $k_i$ is the degree of the node.</p> <p>For an Erdos-Renyi network, the average clustering coefficient for large $N$ reduces to \begin{equation}\langle C \rangle = p. \end{equation}</p> <p>Counting the number of triangles is not a trivial task, therefore, we will <em>cheat</em> and use <code class="language-plaintext highlighter-rouge">networkx</code> to calculate the clustering coefficient of our networks.</p> <p><strong>In [5]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">clustering</span><span class="p">(</span><span class="n">adj</span><span class="p">):</span>
<span class="kn">import</span> <span class="n">networkx</span> <span class="k">as</span> <span class="n">nx</span>
<span class="n">G</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nc">Graph</span><span class="p">(</span><span class="n">adj</span><span class="p">)</span>
<span class="n">clust</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nf">clustering</span><span class="p">(</span><span class="n">G</span><span class="p">).</span><span class="nf">values</span><span class="p">()</span>
<span class="k">return</span> <span class="n">clust</span>

<span class="n">N</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mf">0.1</span><span class="p">)</span>
<span class="n">clust_co</span> <span class="o">=</span> <span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="nf">average</span><span class="p">(</span><span class="nf">clustering</span><span class="p">(</span><span class="nf">erdos_renyi</span><span class="p">(</span><span class="nf">int</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">n</span><span class="p">))))</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">N</span><span class="p">]</span></code></pre></figure> <p><strong>In [6]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">from</span> <span class="n">scipy</span> <span class="kn">import</span> <span class="n">stats</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">slope</span><span class="p">,</span> <span class="n">intercept</span><span class="p">,</span> <span class="n">r_value</span><span class="p">,</span> <span class="n">p_value</span><span class="p">,</span> <span class="n">std_err</span> <span class="o">=</span> <span class="n">stats</span><span class="p">.</span><span class="nf">linregress</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">N</span><span class="p">[</span><span class="o">-</span><span class="mi">6</span><span class="p">:],</span> <span class="n">clust_co</span><span class="p">[</span><span class="o">-</span><span class="mi">6</span><span class="p">:])</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">N</span><span class="p">,</span> <span class="mi">10</span><span class="o">**</span><span class="n">N</span>\<span class="o">*</span><span class="n">slope</span><span class="o">+</span><span class="n">intercept</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="sh">"</span><span class="s">--</span><span class="sh">"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">scatter</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">N</span><span class="p">,</span> <span class="n">clust_co</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$N$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$\langle C \rangle$</span><span class="sh">"</span><span class="p">)</span>

<span class="nf">print</span><span class="p">(</span><span class="sa">r</span><span class="sh">'</span><span class="s">$p = %s $</span><span class="sh">'</span> <span class="o">%</span> <span class="n">intercept</span><span class="p">,</span> <span class="sh">"</span><span class="s">, p=</span><span class="sh">"</span><span class="p">,</span> <span class="n">p_value</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$p = 0.299735616273 $ , p= 0.743566602627
</code></pre></div></div> <p><img src="/assets/posts/erdos-renyi-network-metrics_files/erdos-renyi-network-metrics_9_1.svg" alt="svg"/></p> <p>Note: obtaining the clustering coefficient can be really slow, with the naive implementation having computational complexity $\mathcal{O}(n^3)$ . This is a resource intensive process and for the sake of brevity, I calculated the clustering coefficient for a smaller network. I obtained a result of $\langle C \rangle = 0.3003$ which is close to $p=0.3$.</p> <h2 id="average-shortest-path-length">Average Shortest Path Length</h2> <p>The shortest path length between two nodes $i$ and $j$ is the path with the least number of edges connecting the two nodes. For an Erdos-Renyi network, the average shortest path length $\langle l \rangle$ is given by</p> <p>\begin{equation}\langle l \rangle = \frac{\ln{N}}{\ln{\langle k \rangle}}. \end{equation}</p> <p><strong>In [7]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">N</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="nf">int</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mf">0.1</span><span class="p">)])</span>
<span class="n">degrees</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="n">np</span><span class="p">.</span><span class="nf">average</span><span class="p">(</span><span class="nf">degree</span><span class="p">(</span><span class="nf">erdos_renyi</span><span class="p">(</span><span class="n">n</span><span class="p">)))</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">N</span><span class="p">])</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">slope</span><span class="p">,</span> <span class="n">intercept</span><span class="p">,</span> <span class="n">r_value</span><span class="p">,</span> <span class="n">p_value</span><span class="p">,</span> <span class="n">std_err</span> <span class="o">=</span> <span class="n">stats</span><span class="p">.</span><span class="nf">linregress</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">degrees</span><span class="p">[</span><span class="o">-</span><span class="mi">10</span><span class="p">:]),</span> <span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="o">-</span><span class="mi">10</span><span class="p">:]))</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="n">degrees</span><span class="p">,</span> <span class="n">degrees</span>\<span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="n">slope</span><span class="p">),</span> <span class="n">linestyle</span><span class="o">=</span><span class="sh">"</span><span class="s">--</span><span class="sh">"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">scatter</span><span class="p">(</span><span class="n">degrees</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$N$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$\langle k \rangle$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_yscale</span><span class="p">(</span><span class="sh">'</span><span class="s">log</span><span class="sh">'</span><span class="p">)</span>

<span class="nf">print</span><span class="p">(</span><span class="sa">r</span><span class="sh">'</span><span class="s">$&lt;l&gt; = %s $</span><span class="sh">'</span> <span class="o">%</span> <span class="n">slope</span><span class="p">,</span> <span class="sh">"</span><span class="s">, p=</span><span class="sh">"</span><span class="p">,</span> <span class="n">p_value</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$&lt;l&gt; = 1.00407716536 $ , p= 5.62192309984e-18
</code></pre></div></div> <p><img src="/assets/posts/erdos-renyi-network-metrics_files/erdos-renyi-network-metrics_12_1.svg" alt="svg"/></p> <p>It’s clear form the figure that there is an exponential relationship between $\langle k \rangle$ and $N$. The slope of the log-log plot obtained corresponds to $\langle l \rangle =1.004$. To verify if the slope of the logarithmic plots is indeed $\langle l \rangle$, we can use the built-in <code class="language-plaintext highlighter-rouge">nx.average_shortest_path_length</code>.</p> <p><strong>In [8]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">import</span> <span class="n">networkx</span> <span class="k">as</span> <span class="n">nx</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>

<span class="k">def</span> <span class="nf">get_spl</span><span class="p">(</span><span class="n">N</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span> <span class="n">p</span><span class="o">=</span><span class="mf">0.3</span><span class="p">):</span>
<span class="n">G</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nc">Graph</span><span class="p">(</span><span class="n">nx</span><span class="p">.</span><span class="nf">erdos_renyi_graph</span><span class="p">(</span><span class="n">N</span><span class="p">,</span><span class="n">p</span><span class="p">))</span>
<span class="n">spl</span> <span class="o">=</span> <span class="n">nx</span><span class="p">.</span><span class="nf">average_shortest_path_length</span><span class="p">(</span><span class="n">G</span><span class="p">)</span>
<span class="n">k</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">average</span><span class="p">(</span><span class="n">G</span><span class="p">.</span><span class="nf">degree</span><span class="p">().</span><span class="nf">values</span><span class="p">())</span>
<span class="k">return</span> <span class="n">spl</span><span class="p">,</span> <span class="n">k</span>

<span class="n">N_nodes</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="nf">int</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mf">1.5</span><span class="p">,</span><span class="mf">3.1</span><span class="p">,</span><span class="mf">0.1</span><span class="p">)])</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="nf">get_spl</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">N_nodes</span><span class="p">])</span>
<span class="n">spl</span> <span class="o">=</span> <span class="n">results</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span>
<span class="n">k</span> <span class="o">=</span> <span class="n">results</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">]</span></code></pre></figure> <p><strong>In [9]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">slope</span><span class="p">,</span> <span class="n">intercept</span><span class="p">,</span> <span class="n">r_value</span><span class="p">,</span> <span class="n">p_value</span><span class="p">,</span> <span class="n">std_err</span> <span class="o">=</span> <span class="n">stats</span><span class="p">.</span><span class="nf">linregress</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">N_nodes</span><span class="p">)</span><span class="o">/</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">k</span><span class="p">),</span> <span class="n">spl</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">N_nodes</span><span class="p">)</span><span class="o">/</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">k</span><span class="p">),</span> <span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">N_nodes</span><span class="p">)</span><span class="o">/</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>\<span class="o">*</span><span class="n">slope</span><span class="o">+</span><span class="n">intercept</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="sh">"</span><span class="s">--</span><span class="sh">"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">r</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">scatter</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">N_nodes</span><span class="p">)</span><span class="o">/</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">k</span><span class="p">),</span> <span class="n">spl</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$N$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$\langle l \rangle$</span><span class="sh">"</span><span class="p">)</span>

<span class="c1"># ax.set_xscale('log')</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.text.Text at 0xd05ca90&gt;
</code></pre></div></div> <p><img src="/assets/posts/erdos-renyi-network-metrics_files/erdos-renyi-network-metrics_15_1.svg" alt="svg"/></p> <p>The obtained result isn’t quite what we are expecting. However, it should be noted that $N=1000$ used is quite small, and the analytical trend was derived for a large random network. It is quite possible that we are unable to replicate the results since the networks sizes used are too small, due to limitations in the memory inefficient implementation of <code class="language-plaintext highlighter-rouge">networkx</code>.</p> <h2 id="references">References</h2> <ol> <li>http://dx.doi.org/10.1103/PhysRevE.75.027105</li> <li>http://people.seas.harvard.edu/~babis/tsourICDM08.pdf</li> </ol>]]></content><author><name></name></author><category term="Python"/><category term="Complex Systems"/><summary type="html"><![CDATA[The Erdos Renyi networks consist of nodes that have a probability $p$ to be connected to other nodes. This is otherwise known as a random network, and its statistical properties and characteristics are well studied. In this entry, we will be looking at the following:]]></summary></entry><entry><title type="html">Agent Based Models</title><link href="https://damiandailisan.com/blog/2016/agent-based-models/" rel="alternate" type="text/html" title="Agent Based Models"/><published>2016-03-13T00:00:00+00:00</published><updated>2016-03-13T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/agent-based-models</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/agent-based-models/"><![CDATA[<h2 id="schelling-model">Schelling model</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>This work was made together with Alfred Abella
</code></pre></div></div> <p>The Schelling model is one of the early agent-based automata models used to study the formation of black and white communities. As racist as it may sound, it does make sense that a population would naturally segregate into a community with common traits. A more general treatment would probably consider multiple layers such as proximity to a workplace, nationality.</p> <p>In this model, cells on an $n\times n$ lattice would represent space on the map. A cell may be <code class="language-plaintext highlighter-rouge">EMPTY</code> or occupied. When occupied, it can take on two values, <code class="language-plaintext highlighter-rouge">BLACK</code> or <code class="language-plaintext highlighter-rouge">WHITE</code>, representing the race of agents. We initialize the lattice <code class="language-plaintext highlighter-rouge">grids</code> with <code class="language-plaintext highlighter-rouge">percent_empty</code> <code class="language-plaintext highlighter-rouge">EMPTY</code> cells and <code class="language-plaintext highlighter-rouge">percent_white</code> <code class="language-plaintext highlighter-rouge">WHITE</code> cells.</p> <p><strong>In [1]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">from</span> <span class="o">**</span><span class="n">future</span><span class="o">**</span> <span class="kn">import</span> <span class="n">division</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="n">numba</span> <span class="kn">import</span> <span class="n">jit</span>
<span class="kn">from</span> <span class="n">matplotlib</span> <span class="kn">import</span> <span class="n">animation</span>

<span class="n">EMPTY</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">BLACK</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">WHITE</span> <span class="o">=</span> <span class="mi">2</span>

<span class="n">n</span> <span class="o">=</span> <span class="mi">128</span>
<span class="n">percent_empty</span> <span class="o">=</span> <span class="mf">33.3</span>
<span class="n">percent_white</span> <span class="o">=</span> <span class="mf">33.3</span>
<span class="n">percent_thres</span> <span class="o">=</span> <span class="mi">50</span>
<span class="n">n2</span> <span class="o">=</span> <span class="n">n</span><span class="o">**</span><span class="mi">2</span>
<span class="n">grids</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">((</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">))</span>
<span class="n">emp</span> <span class="o">=</span> <span class="nf">int</span><span class="p">((</span><span class="n">percent_empty</span> <span class="o">/</span> <span class="mi">100</span><span class="p">)</span> \<span class="o">*</span> <span class="n">n</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="n">two</span> <span class="o">=</span> <span class="nf">int</span><span class="p">((</span><span class="n">percent_white</span> <span class="o">/</span> <span class="mi">100</span><span class="p">)</span> \<span class="o">*</span> <span class="n">n</span>\<span class="o">*</span>\<span class="o">*</span><span class="mi">2</span><span class="p">)</span>
<span class="n">tot</span> <span class="o">=</span> <span class="n">emp</span> <span class="o">+</span> <span class="n">two</span>
<span class="n">rand_loc</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="nf">permutation</span><span class="p">(</span><span class="n">n2</span><span class="p">)</span>
<span class="n">init_emp</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="nf">unravel_index</span><span class="p">(</span><span class="n">rand_loc</span><span class="p">[:</span><span class="n">emp</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">))</span>
<span class="n">init_two</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="nf">unravel_index</span><span class="p">(</span><span class="n">rand_loc</span><span class="p">[</span><span class="n">emp</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:</span><span class="n">tot</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">))</span>
<span class="n">init_one</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="nf">unravel_index</span><span class="p">(</span><span class="n">rand_loc</span><span class="p">[</span><span class="n">tot</span><span class="o">+</span><span class="mi">1</span><span class="p">:],</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">))</span>
<span class="n">grids</span><span class="p">[</span><span class="n">init_emp</span><span class="p">]</span><span class="o">=</span><span class="mi">3</span>
<span class="n">grids</span><span class="p">[</span><span class="n">init_two</span><span class="p">]</span><span class="o">=</span><span class="mi">2</span>
<span class="n">grids</span><span class="p">[</span><span class="n">init_one</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span>

<span class="n">grid2</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">((</span><span class="n">n</span><span class="o">+</span><span class="mi">2</span><span class="p">,</span> <span class="n">n</span><span class="o">+</span><span class="mi">2</span><span class="p">))</span>
<span class="n">grid2</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">grids</span></code></pre></figure> <p>All agents moves along the grid until it comes within contact of other agents. The agent looks at its neighborhood (in this case, a Moore neighborhood), and if the number of similar neighbors exceeds a threshold, the agent will settle down and stop moving. The rules stated are contained and executed within the function <code class="language-plaintext highlighter-rouge">place_indiv()</code>.</p> <p><strong>In [2]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">place_indiv</span><span class="p">(</span><span class="n">grid2</span><span class="p">):</span>
<span class="n">num_unsat</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">j</span> <span class="ow">in</span> <span class="p">[(</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)]:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">grid2</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">!=</span> <span class="n">EMPTY</span><span class="p">:</span>
<span class="n">block</span> <span class="o">=</span> <span class="n">grid2</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span><span class="n">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span><span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span><span class="n">j</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span>
<span class="n">cnzero</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">block</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">cnvalue</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">block</span> <span class="o">==</span> <span class="n">value</span><span class="p">)</span>
<span class="n">thres</span> <span class="o">=</span> <span class="nf">round</span><span class="p">((</span><span class="n">percent_thres</span> <span class="o">/</span> <span class="mi">100</span><span class="p">)</span> \<span class="o">*</span> <span class="n">cnzero</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cnvalue</span> <span class="o">&lt;</span> <span class="n">thres</span><span class="p">:</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">BLACK</span><span class="p">:</span>
<span class="n">num_unsat</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="n">WHITE</span><span class="p">:</span>
<span class="n">num_unsat</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span><span class="mi">1</span>
<span class="n">grid2</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">EMPTY</span>
<span class="k">return</span> <span class="n">grid2</span><span class="p">,</span> <span class="n">num_unsat</span></code></pre></figure> <p>We will run this code for all agents at every timestep until all agents settle down. At the same time, we are going to save a snapshot of the state of the lattice after every 3 timesteps. This is to save on memory since there will be a lot of timesteps before all agents settle down.</p> <p><strong>In [3]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">FFMpegWriter</span> <span class="o">=</span> <span class="n">animation</span><span class="p">.</span><span class="n">writers</span><span class="p">[</span><span class="sh">'</span><span class="s">ffmpeg</span><span class="sh">'</span><span class="p">]</span>
<span class="n">writer</span> <span class="o">=</span> <span class="nc">FFMpegWriter</span><span class="p">(</span><span class="n">fps</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">extra_args</span><span class="o">=</span><span class="p">[</span><span class="sh">'</span><span class="s">-vcodec</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">libx264</span><span class="sh">'</span><span class="p">])</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">fig</span><span class="p">.</span><span class="nf">subplots_adjust</span><span class="p">(</span><span class="n">left</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">bottom</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">top</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">wspace</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">hspace</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">axis</span><span class="p">(</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">)</span>
<span class="n">cmap</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">get_cmap</span><span class="p">(</span><span class="sh">'</span><span class="s">bone</span><span class="sh">'</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">im</span> <span class="o">=</span> <span class="n">ax</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">grids</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="n">cmap</span><span class="p">,</span> <span class="n">interpolation</span><span class="o">=</span><span class="sh">'</span><span class="s">nearest</span><span class="sh">'</span><span class="p">)</span>
<span class="n">count</span><span class="o">=</span><span class="mi">0</span>
<span class="k">with</span> <span class="n">writer</span><span class="p">.</span><span class="nf">saving</span><span class="p">(</span><span class="n">fig</span><span class="p">,</span> <span class="sh">"</span><span class="s">writer_test.mp4</span><span class="sh">"</span><span class="p">,</span> <span class="mi">64</span><span class="p">):</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">grid2</span><span class="p">,</span> <span class="n">num_unsat</span> <span class="o">=</span> <span class="nf">place_indiv</span><span class="p">(</span><span class="n">grid2</span><span class="p">)</span>
<span class="n">empty_y</span><span class="p">,</span> <span class="n">empty_x</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="n">grid2</span> <span class="o">==</span> <span class="n">EMPTY</span><span class="p">)</span>
<span class="n">perm</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="nf">permutation</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">empty_y</span><span class="p">))</span> <span class="c1"># perm determines which empty cells are filled
</span><span class="n">grid2</span><span class="p">[</span><span class="n">empty_y</span><span class="p">[</span><span class="n">perm</span><span class="p">[:</span><span class="n">num_unsat</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="p">]</span> <span class="p">],</span> <span class="n">empty_x</span><span class="p">[</span><span class="n">perm</span><span class="p">[:</span><span class="n">num_unsat</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="p">]</span> <span class="p">]</span> <span class="p">]</span> <span class="o">=</span> <span class="n">BLACK</span>
<span class="n">grid2</span><span class="p">[</span><span class="n">empty_y</span><span class="p">[</span><span class="n">perm</span><span class="p">[</span><span class="n">num_unsat</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span><span class="nf">sum</span><span class="p">(</span><span class="n">num_unsat</span><span class="p">)]</span> <span class="p">],</span> <span class="n">empty_x</span><span class="p">[</span><span class="n">perm</span><span class="p">[</span><span class="n">num_unsat</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span><span class="nf">sum</span><span class="p">(</span><span class="n">num_unsat</span><span class="p">)]</span> <span class="p">]</span> <span class="p">]</span> <span class="o">=</span> <span class="n">WHITE</span>
<span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">grids</span><span class="o">!=</span><span class="n">grid2</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span> <span class="mi">1</span><span class="p">])</span><span class="o">==</span><span class="mi">0</span> <span class="ow">or</span> <span class="n">count</span><span class="o">&gt;=</span><span class="mi">1000</span><span class="p">:</span>

<span class="c1"># print count
</span>
            <span class="k">break</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">grids</span> <span class="o">=</span> <span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">copy</span><span class="p">(</span><span class="n">grid2</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span> <span class="mi">1</span><span class="p">]))</span> <span class="c1"># remove pad and store to im
</span>            <span class="k">if</span> <span class="n">count</span><span class="o">%</span><span class="mi">3</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span>
                <span class="n">im</span><span class="p">.</span><span class="nf">set_data</span><span class="p">(</span><span class="n">grids</span><span class="p">)</span>
                <span class="n">writer</span><span class="p">.</span><span class="nf">grab_frame</span><span class="p">()</span></code></pre></figure> <p>The video below shows the evolution of the Schelling model through time. We can clearly see that from a randomly arranged lattice of <code class="language-plaintext highlighter-rouge">BLACK</code> and <code class="language-plaintext highlighter-rouge">WHITE</code> agents, communities are formed. It would probably be interesting to characterize the size distributions of these communities.</p> <video id="videoId" width="100%" autoplay="" controls=""> <source src="/vid/writer_test.mp4" type="video/mp4"/> Your browser does not support the video tag. </video>]]></content><author><name></name></author><category term="Python"/><category term="Complex Systems"/><summary type="html"><![CDATA[Schelling model]]></summary></entry><entry><title type="html">Fractals</title><link href="https://damiandailisan.com/blog/2016/fractals/" rel="alternate" type="text/html" title="Fractals"/><published>2016-03-01T00:00:00+00:00</published><updated>2016-03-01T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/fractals</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/fractals/"><![CDATA[<h1 id="fractal-dimension">Fractal Dimension</h1> <p>Fractals are geometric features in which structures are similar when viewed at small localized regions, or the entirety of the structure itself. Fractals are said to be naturally occurring in nature, which is the motivation of applying concepts of fractals in modelling physical systems.</p> <p>One way to look at fractals is by their fractal dimension, given by \(D = \lim\_{\epsilon \to 0} \dfrac{\log{N}}{\log{1/\epsilon}},\) where $N$ is the number of boxes that contains the structure, and $\epsilon$ is the size of the box. As such, this method is called the box counting method. This is useful for looking at the fractal dimensionality of two dimensional images.</p> <p>Suppose we want to look at the fractal dimension of this image:</p> <p><img src="/assets/posts/fractals_files/lightning-fractal.jpg" alt="alt text"/></p> <p><strong>In [1]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="o">%</span><span class="n">config</span> <span class="n">InlineBackend</span><span class="p">.</span><span class="n">figure_format</span> <span class="o">=</span> <span class="sh">'</span><span class="s">svg</span><span class="sh">'</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="n">skimage</span> <span class="kn">import</span> <span class="n">color</span>

<span class="c1"># img = color.rgb2gray(plt.imread('lightning-fractal.jpg'))
</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">imread</span><span class="p">(</span><span class="sh">'</span><span class="s">lightning-fractal.jpg</span><span class="sh">'</span><span class="p">)[:,:,</span><span class="mi">0</span><span class="p">]</span><span class="o">/</span><span class="mf">255.</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">img</span><span class="o">&gt;</span><span class="mf">0.4</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">"</span><span class="s">gray</span><span class="sh">"</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.image.AxesImage at 0x6d2ecf8&gt;
</code></pre></div></div> <p><img src="/assets/posts/fractals_files/fractals_1_1.svg" alt="svg"/></p> <p>The following lines of code will count the number of blocks containing the structure $N$ for a given input of $\epsilon$.</p> <p><strong>In [2]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">count_N</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="n">epsilon</span><span class="p">):</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">img</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">epsilon</span><span class="p">):</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">img</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">epsilon</span><span class="p">):</span>
<span class="k">if</span> <span class="n">i</span><span class="o">==</span><span class="n">img</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
<span class="n">N</span> <span class="o">+=</span> <span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">img</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">j</span><span class="p">:</span><span class="n">j</span><span class="o">+</span><span class="n">epsilon</span><span class="p">])</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">j</span><span class="o">==</span><span class="n">img</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
<span class="n">N</span> <span class="o">+=</span> <span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">img</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="n">epsilon</span><span class="p">,</span> <span class="n">j</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">N</span> <span class="o">+=</span> <span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">img</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="n">epsilon</span><span class="p">,</span> <span class="n">j</span><span class="p">:</span><span class="n">j</span><span class="o">+</span><span class="n">epsilon</span><span class="p">])</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span>

<span class="c1"># print np.sum(img[i:i+epsilon, j:j+epsilon])&gt;0
</span>
    <span class="k">return</span> <span class="n">N</span></code></pre></figure> <p>We will then plot $\log{N}$ with $\log{1/\epsilon}$ and if the slope of the resulting plot, representing $D$ appoaches some finite value.</p> <p><strong>In [3]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">epsilon_values</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">N</span> <span class="o">=</span> <span class="p">[</span><span class="nf">count_N</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="n">epsilon</span><span class="p">)</span> <span class="k">for</span> <span class="n">epsilon</span> <span class="ow">in</span> <span class="n">epsilon_values</span><span class="p">]</span>

<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">()</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="mf">1.</span><span class="o">/</span><span class="n">epsilon_values</span><span class="p">)</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">N</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">scatter</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$\log{N}$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$\log{1/\epsilon}$</span><span class="sh">"</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.text.Text at 0x6f50ba8&gt;
</code></pre></div></div> <p><img src="/assets/posts/fractals_files/fractals_5_1.svg" alt="svg"/></p> <h1 id="getting-the-fractal-dimension">Getting the fractal dimension</h1> <p>From the definition of the fractal dimension, we can see that it is simply the slope of $\log{N}$ vs $\log{1/\epsilon}$ for large values of $1/\epsilon$. To obtain this, it is best to fit a line at the end of the plot. In this case, we will fit a line to the last 50 points, the slope of which is our fractal dimension.</p> <p><strong>In [4]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">from</span> <span class="n">scipy</span> <span class="kn">import</span> <span class="n">stats</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>

<span class="n">slope</span><span class="p">,</span> <span class="n">intercept</span><span class="p">,</span> <span class="n">r_value</span><span class="p">,</span> <span class="n">p_value</span><span class="p">,</span> <span class="n">std_err</span> <span class="o">=</span> <span class="n">stats</span><span class="p">.</span><span class="nf">linregress</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="o">-</span><span class="mi">50</span><span class="p">:],</span><span class="n">y</span><span class="p">[</span><span class="o">-</span><span class="mi">50</span><span class="p">:])</span>

<span class="k">print</span> <span class="sh">'</span><span class="s">D = %s</span><span class="sh">'</span> <span class="o">%</span> <span class="n">slope</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>D = 1.93467964091
</code></pre></div></div> <p>Hence, the fractal dimension of the image is $D=1.935$.</p>]]></content><author><name></name></author><category term="Python"/><category term="Complex Systems"/><summary type="html"><![CDATA[Fractal Dimension]]></summary></entry><entry><title type="html">Elementary Cellular Automata</title><link href="https://damiandailisan.com/blog/2016/elementary-cellular-automata/" rel="alternate" type="text/html" title="Elementary Cellular Automata"/><published>2016-02-15T00:00:00+00:00</published><updated>2016-02-15T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/elementary-cellular-automata</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/elementary-cellular-automata/"><![CDATA[<p>Elementary Cellular Automata (ECA) was a toy model initially created by Von Neumann and later on studied extensively by Stephen Wolfram, probably since he was really bored. ECA is a simple model wherein you have cells with binary states (1 or 0) that evolve through iterations. The evolution rules are defined by the state at the previous timestep of the cells within the neighborhood the the cell to be evaluated.</p> <p>For this implementation, I defined functions that turn binary strings to decimals and vice versa. This will facilitate the general creation of lookup tables associated with the rules.</p> <p><strong>In [1]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="o">%</span><span class="n">config</span> <span class="n">InlineBackend</span><span class="p">.</span><span class="n">figure_format</span> <span class="o">=</span> <span class="sh">'</span><span class="s">svg</span><span class="sh">'</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="k">from</span> <span class="o">**</span><span class="n">future</span><span class="o">**</span> <span class="kn">import</span> <span class="n">division</span><span class="p">,</span> <span class="n">print_function</span>
<span class="kn">from</span> <span class="n">numba</span> <span class="kn">import</span> <span class="n">jit</span>
<span class="kn">import</span> <span class="n">seaborn</span> <span class="k">as</span> <span class="n">sns</span>

<span class="nd">@jit</span>
<span class="k">def</span> <span class="nf">binary_str</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
<span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">):</span>
<span class="k">if</span> <span class="n">num</span><span class="o">//</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="n">i</span><span class="p">)</span><span class="o">==</span><span class="mi">1</span><span class="p">:</span>
<span class="n">res</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">num</span> <span class="o">-=</span> <span class="mi">2</span><span class="o">**</span><span class="n">i</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">res</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">return</span> <span class="n">res</span>

<span class="nd">@jit</span>
<span class="k">def</span> <span class="nf">binary_dec</span><span class="p">(</span><span class="n">arr</span><span class="p">):</span>
<span class="n">dec</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">arr</span><span class="p">)):</span>
<span class="n">dec</span> <span class="o">+=</span> <span class="n">arr</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="o">-</span><span class="n">i</span><span class="p">]</span>\<span class="o">*</span><span class="mi">2</span>\<span class="o">*</span>\<span class="o">*</span><span class="n">i</span>
<span class="k">return</span> <span class="n">dec</span></code></pre></figure> <p>I then initialized an empty array, and initialized the first row a 50-50 percent chance of being 1 or 0 for each cell in the first row.</p> <p><strong>In [2]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">SIZE</span> <span class="o">=</span> <span class="mi">50</span>

<span class="n">ECA</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">((</span><span class="n">SIZE</span><span class="p">,</span><span class="n">SIZE</span><span class="p">))</span>
<span class="n">ECA</span><span class="p">[</span><span class="mi">0</span><span class="p">,:]</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">ECA</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">SIZE</span><span class="o">//</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span></code></pre></figure> <p>I then allowed the system to follow the rules (Rule 30 in particular) and wait for the resulting image…</p> <p><strong>In [3]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">SIZE</span><span class="p">):</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">SIZE</span><span class="p">):</span>
<span class="n">pattern</span> <span class="o">=</span> <span class="p">[</span><span class="n">ECA</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">k</span><span class="o">%</span><span class="n">SIZE</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="p">[</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]]</span>
<span class="n">index</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">binary_dec</span><span class="p">(</span><span class="n">pattern</span><span class="p">))</span>
<span class="n">ECA</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="nf">binary_str</span><span class="p">(</span><span class="mi">26</span><span class="p">)[</span><span class="mi">7</span><span class="o">-</span><span class="n">index</span><span class="p">]</span>

<span class="k">with</span> <span class="n">sns</span><span class="p">.</span><span class="nf">axes_style</span><span class="p">(</span><span class="sh">'</span><span class="s">white</span><span class="sh">'</span><span class="p">):</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mi">5</span><span class="p">))</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">ECA</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">'</span><span class="s">gray</span><span class="sh">'</span><span class="p">,</span> <span class="n">interpolation</span><span class="o">=</span><span class="sh">'</span><span class="s">nearest</span><span class="sh">'</span><span class="p">)</span></code></pre></figure> <p><img src="/assets/posts/elementary-cellular-automata_files/elementary-cellular-automata_5_0.svg" alt="svg"/></p> <h1 id="characterizing-eca-rules">Characterizing ECA Rules</h1> <h2 id="space-entropy">Space: Entropy</h2> <p>Measure the Shannon Entropy \(H = \dfrac{1}{H*{max}} \sum*{i=0}^7 p*i\log{p_i}\) where $p_i$ is the frequency of all configurations resulting in the microstate $i$, where $H*{max}$ is the value of $H$ whenn all $p_i=\dfrac{1}{N}$ are equal.</p> <p>$ \langle H \rangle$ is obtained after disregarding the transient period (roughly half of the cell length in space).</p> <p><strong>In [4]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">SIZE</span><span class="o">=</span><span class="mi">128</span>

<span class="k">def</span> <span class="nf">p_i</span><span class="p">(</span><span class="n">space_arr</span><span class="p">,</span><span class="n">N</span><span class="p">):</span>
<span class="n">p_vals</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="nb">bool</span><span class="p">)</span>
<span class="n">states</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="nf">binary_dec</span><span class="p">(</span><span class="n">space_arr</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="mi">2</span><span class="p">])</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="nf">len</span><span class="p">(</span><span class="n">space_arr</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">)])</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
<span class="n">p_vals</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">states</span><span class="o">==</span><span class="n">i</span><span class="p">)</span>
<span class="k">return</span> <span class="n">p_vals</span><span class="o">/</span><span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">p_vals</span><span class="p">)</span>

<span class="n">N</span> <span class="o">=</span> <span class="mi">8</span>
<span class="n">H_max</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">([</span><span class="mf">1.</span><span class="o">/</span><span class="n">N</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="mf">1.</span><span class="o">/</span><span class="n">N</span><span class="p">)</span> <span class="k">for</span> <span class="n">state_num</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">N</span><span class="p">)])</span>
<span class="n">H</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">timestep</span><span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">([</span><span class="n">p</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">p</span><span class="o">+</span><span class="mf">1e-10</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nf">p_i</span><span class="p">(</span><span class="n">timestep</span><span class="p">,</span><span class="n">N</span><span class="p">)])</span><span class="o">/</span><span class="n">H_max</span>

<span class="n">H_ave</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">ECA</span><span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="nf">mean</span><span class="p">([</span><span class="nc">H</span><span class="p">(</span><span class="n">timestep</span><span class="p">)</span> <span class="k">for</span> <span class="n">timestep</span> <span class="ow">in</span> <span class="n">ECA</span><span class="p">[</span><span class="n">SIZE</span><span class="o">//</span><span class="mi">2</span><span class="p">:,:]])</span></code></pre></figure> <h2 id="time-kinetic-energy">Time: Kinetic Energy</h2> <p>\(\langle K \rangle*t = \langle |s*{i+1}-s_i|^2\rangle_t\) This essentially counts the number of times states are flipped averaged across space and time.</p> <p><strong>In [5]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">K</span><span class="p">(</span><span class="n">evolution</span><span class="p">):</span>
<span class="n">SIZE</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">evolution</span><span class="p">)</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="nf">mean</span><span class="p">([</span><span class="n">np</span><span class="p">.</span><span class="nf">mean</span><span class="p">((</span><span class="n">evolution</span><span class="p">[</span><span class="n">time</span><span class="p">]</span><span class="o">-</span><span class="n">evolution</span><span class="p">[</span><span class="n">time</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>\<span class="o">*</span>\<span class="o">*</span><span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">time</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">SIZE</span><span class="o">//</span><span class="mi">2</span><span class="p">,</span><span class="n">SIZE</span><span class="p">)])</span></code></pre></figure> <p>An interesting observation is when you generate all ECA rules, measure their respective $K$ and $H$ values, we will observe clustering for similarly classed rules.</p> <p><strong>In [6]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">create_ECA</span><span class="p">(</span><span class="n">rule</span><span class="p">,</span> <span class="n">SIZE</span><span class="p">):</span>
<span class="n">ECA</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">((</span><span class="n">SIZE</span><span class="p">,</span><span class="n">SIZE</span><span class="p">))</span>
<span class="n">ECA</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="n">SIZE</span><span class="o">//</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>

<span class="c1"># ECA[0,:] = 1\*(np.random.random(SIZE)&gt;0.5)
</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">SIZE</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">SIZE</span><span class="p">):</span>
            <span class="n">pattern</span> <span class="o">=</span> <span class="p">[</span><span class="n">ECA</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">k</span><span class="o">%</span><span class="n">SIZE</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="p">[</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]]</span>
            <span class="n">index</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">binary_dec</span><span class="p">(</span><span class="n">pattern</span><span class="p">))</span>
            <span class="n">ECA</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="nf">binary_str</span><span class="p">(</span><span class="n">rule</span><span class="p">)[</span><span class="mi">7</span><span class="o">-</span><span class="n">index</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">ECA</span>

<span class="nf">print</span><span class="p">(</span><span class="n">SIZE</span><span class="p">)</span>
<span class="n">SIZE</span> <span class="o">=</span> <span class="mi">128</span>
<span class="o">%</span><span class="n">time</span> <span class="n">all_ECA</span> <span class="o">=</span> <span class="p">[</span><span class="nf">create_ECA</span><span class="p">(</span><span class="n">rule</span><span class="p">,</span> <span class="n">SIZE</span><span class="p">)</span> <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">SIZE</span><span class="p">)]</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>128
Wall time: 46.3 s
</code></pre></div></div> <p><strong>In [7]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">CA1</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="mi">36</span><span class="p">,</span> <span class="mi">48</span><span class="p">,</span> <span class="mi">54</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">62</span><span class="p">]</span>
<span class="n">CA2</span> <span class="o">=</span> <span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">56</span><span class="p">,</span> <span class="mi">58</span><span class="p">]</span>
<span class="n">CA3</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">28</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">38</span><span class="p">,</span> <span class="mi">42</span><span class="p">,</span> <span class="mi">44</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mi">50</span><span class="p">]</span>
<span class="n">CA4</span> <span class="o">=</span> <span class="p">[</span><span class="mi">52</span><span class="p">,</span> <span class="mi">110</span><span class="p">]</span>
<span class="n">colors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
<span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">CA1</span><span class="p">:</span>
<span class="n">colors</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="sh">'</span><span class="s">m</span><span class="sh">'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">CA2</span><span class="p">:</span>
<span class="n">colors</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="sa">u</span><span class="sh">'</span><span class="s">g</span><span class="sh">'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">CA3</span><span class="p">:</span>
<span class="n">colors</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="sa">u</span><span class="sh">'</span><span class="s">y</span><span class="sh">'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">CA4</span><span class="p">:</span>
<span class="n">colors</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="sa">u</span><span class="sh">'</span><span class="s">b</span><span class="sh">'</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">colors</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="sa">u</span><span class="sh">'</span><span class="s">None</span><span class="sh">'</span><span class="p">)</span></code></pre></figure> <p><strong>In [8]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">time</span> <span class="n">K_list</span> <span class="o">=</span> <span class="p">[</span><span class="nc">K</span><span class="p">(</span><span class="n">ECA</span><span class="p">)</span> <span class="k">for</span> <span class="n">ECA</span> <span class="ow">in</span> <span class="n">all_ECA</span><span class="p">]</span>
<span class="o">%</span><span class="n">time</span> <span class="n">H_list</span> <span class="o">=</span> <span class="p">[</span><span class="nc">H_ave</span><span class="p">(</span><span class="n">ECA</span><span class="p">)</span> <span class="k">for</span> <span class="n">ECA</span> <span class="ow">in</span> <span class="n">all_ECA</span><span class="p">]</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Wall time: 130 ms
Wall time: 1.46 s
</code></pre></div></div> <p><strong>In [9]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">plt</span><span class="p">.</span><span class="nf">scatter</span><span class="p">(</span><span class="n">K_list</span><span class="p">,</span><span class="n">H_list</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="n">colors</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">linewidths</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">ylabel</span><span class="p">(</span><span class="sh">'</span><span class="s">$H$</span><span class="sh">'</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">xlabel</span><span class="p">(</span><span class="sh">'</span><span class="s">$K$</span><span class="sh">'</span><span class="p">)</span></code></pre></figure> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;matplotlib.text.Text at 0xd2d9fd0&gt;
</code></pre></div></div> <p><img src="/assets/posts/elementary-cellular-automata_files/elementary-cellular-automata_14_1.svg" alt="svg"/></p> <h3 id="clustering-of-eca">Clustering of ECA</h3> <p>Some form of clustering can be observed using the Entropy and Kinetic Energy descriptors. However, this clustering cannot be traced back to the types of ECA rules.</p>]]></content><author><name></name></author><category term="Python"/><category term="Complex Systems"/><summary type="html"><![CDATA[Elementary Cellular Automata (ECA) was a toy model initially created by Von Neumann and later on studied extensively by Stephen Wolfram, probably since he was really bored. ECA is a simple model wherein you have cells with binary states (1 or 0) that evolve through iterations. The evolution rules are defined by the state at the previous timestep of the cells within the neighborhood the the cell to be evaluated.]]></summary></entry><entry><title type="html">Chaos in Biological Populations</title><link href="https://damiandailisan.com/blog/2016/chaos-in-biological-populations/" rel="alternate" type="text/html" title="Chaos in Biological Populations"/><published>2016-02-02T00:00:00+00:00</published><updated>2016-02-02T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2016/chaos-in-biological-populations</id><content type="html" xml:base="https://damiandailisan.com/blog/2016/chaos-in-biological-populations/"><![CDATA[<h2 id="single-species-model">Single species model</h2> <p>Consider the non-linear equation \begin{equation} N_{t+1} = N_t\exp{[r(1-N_t/K)]}, \end{equation} where $r$ and $K$ are the growth rate and carrying capacity, respectively. This is a simple model for the population growth of a single species.</p> <p>We can plot this equation for different values of $r$.</p> <p><strong>In [1]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="o">%</span><span class="n">config</span> <span class="n">InlineBackend</span><span class="p">.</span><span class="n">figure_format</span> <span class="o">=</span> <span class="sh">'</span><span class="s">svg</span><span class="sh">'</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">import</span> <span class="n">seaborn</span> <span class="k">as</span> <span class="n">sns</span>

<span class="k">def</span> <span class="nf">subplotaxis_off</span><span class="p">(</span><span class="n">ax</span><span class="p">):</span> <span class="c1"># Turn off axis lines and ticks of the big subplot
</span><span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="sh">'</span><span class="s">top</span><span class="sh">'</span><span class="p">].</span><span class="nf">set_color</span><span class="p">(</span><span class="sh">'</span><span class="s">none</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="sh">'</span><span class="s">bottom</span><span class="sh">'</span><span class="p">].</span><span class="nf">set_color</span><span class="p">(</span><span class="sh">'</span><span class="s">none</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="sh">'</span><span class="s">left</span><span class="sh">'</span><span class="p">].</span><span class="nf">set_color</span><span class="p">(</span><span class="sh">'</span><span class="s">none</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="sh">'</span><span class="s">right</span><span class="sh">'</span><span class="p">].</span><span class="nf">set_color</span><span class="p">(</span><span class="sh">'</span><span class="s">none</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">tick_params</span><span class="p">(</span><span class="n">labelcolor</span><span class="o">=</span><span class="sh">'</span><span class="s">w</span><span class="sh">'</span><span class="p">,</span> <span class="n">top</span><span class="o">=</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">,</span> <span class="n">bottom</span><span class="o">=</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">)</span>

<span class="n">N_0</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">K</span> <span class="o">=</span> <span class="mi">1000</span>
<span class="n">eq1</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">r</span><span class="p">,</span> <span class="n">N_0</span><span class="p">,</span> <span class="n">K</span><span class="p">:</span> <span class="n">N_0</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="n">r</span><span class="o">*</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">N_0</span><span class="o">/</span><span class="n">K</span><span class="p">))</span>

<span class="k">def</span> <span class="nf">population_growth</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">timesteps</span><span class="p">,</span> <span class="n">N_0</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">K</span><span class="o">=</span><span class="mi">1000</span><span class="p">):</span>
<span class="n">N</span> <span class="o">=</span> <span class="p">[</span><span class="n">N_0</span><span class="p">]</span>
<span class="k">for</span> <span class="n">time</span> <span class="ow">in</span> <span class="n">timesteps</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
<span class="n">N</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nf">eq1</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">N</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">K</span><span class="p">))</span>
<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">(</span><span class="n">N</span><span class="p">)</span>

<span class="n">timesteps</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span>
<span class="n">r_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1.8</span><span class="p">,</span> <span class="mf">2.3</span><span class="p">,</span> <span class="mf">2.6</span><span class="p">]</span>
<span class="n">population</span> <span class="o">=</span> <span class="p">[</span><span class="nf">population_growth</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">timesteps</span><span class="p">)</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">r_list</span><span class="p">]</span>

<span class="n">fig</span><span class="p">,</span> <span class="n">axes</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">subplots</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span> <span class="n">sharex</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">dpi</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
<span class="k">with</span> <span class="n">sns</span><span class="p">.</span><span class="nf">axes_style</span><span class="p">(</span><span class="sh">"</span><span class="s">whitegrid</span><span class="sh">"</span><span class="p">):</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">grid</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">r_list</span><span class="p">):</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">plot</span><span class="p">(</span><span class="n">timesteps</span><span class="p">,</span> <span class="n">population</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">/</span><span class="n">K</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="sh">'</span><span class="s">y</span><span class="sh">'</span><span class="p">,</span> <span class="n">nbins</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">set_ylim</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">text</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.99</span><span class="p">,</span><span class="sa">r</span><span class="sh">'</span><span class="s">$r=%.2f$</span><span class="sh">'</span> <span class="o">%</span> <span class="n">r</span><span class="p">,</span> <span class="n">horizontalalignment</span><span class="o">=</span><span class="sh">'</span><span class="s">center</span><span class="sh">'</span><span class="p">,</span>
<span class="n">verticalalignment</span><span class="o">=</span><span class="sh">'</span><span class="s">top</span><span class="sh">'</span><span class="p">,</span> <span class="n">transform</span> <span class="o">=</span> <span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">transAxes</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$N/K$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">time, $t$</span><span class="sh">"</span><span class="p">)</span>
<span class="nf">subplotaxis_off</span><span class="p">(</span><span class="n">ax</span><span class="p">)</span></code></pre></figure> <p><img src="/assets/posts/chaos-in-biological-populations_files/chaos-in-biological-populations_1_0.svg" alt="svg"/></p> <p>In the above examples, we observe stable equilibrium ($r=1.8$), and stable cycles with 2 points ($r=2.3$) or 4 points ($r=2.6$). Although not explicitly shown, this stable behavior can be seen for any initial value of $N_0$ and $K$.</p> <p>On the other hand, setting $r=3.3$, we will observe that the behavior of the population depends on the initial value $N_0/K$. The code to produce the plots is as follows:</p> <p><strong>In [2]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">timesteps</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span>
<span class="n">r_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">3.3</span><span class="p">,</span> <span class="mf">3.3</span><span class="p">,</span> <span class="mf">3.3</span><span class="p">]</span>
<span class="n">NK_ratio</span> <span class="o">=</span> <span class="p">[</span><span class="mf">0.075</span><span class="p">,</span> <span class="mf">1.5</span><span class="p">,</span> <span class="mf">0.02</span><span class="p">]</span>
<span class="n">population</span> <span class="o">=</span> <span class="p">[</span><span class="nf">population_growth</span><span class="p">(</span><span class="n">r_list</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">timesteps</span><span class="p">,</span> <span class="n">N_0</span><span class="o">=</span><span class="n">K</span>\<span class="o">*</span><span class="n">NK</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">NK</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">NK_ratio</span><span class="p">)]</span>

<span class="n">fig</span><span class="p">,</span> <span class="n">axes</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">subplots</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span> <span class="n">sharex</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">dpi</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
<span class="k">with</span> <span class="n">sns</span><span class="p">.</span><span class="nf">axes_style</span><span class="p">(</span><span class="sh">"</span><span class="s">whitegrid</span><span class="sh">"</span><span class="p">):</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">grid</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">r_list</span><span class="p">):</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">plot</span><span class="p">(</span><span class="n">timesteps</span><span class="p">,</span> <span class="n">population</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">/</span><span class="n">K</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="sh">'</span><span class="s">y</span><span class="sh">'</span><span class="p">,</span> <span class="n">nbins</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">set_ylim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mf">3.8</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">text</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.99</span><span class="p">,</span><span class="sa">r</span><span class="sh">'</span><span class="s">$r=%.2f$</span><span class="sh">'</span> <span class="o">%</span> <span class="n">r</span><span class="p">,</span> <span class="n">horizontalalignment</span><span class="o">=</span><span class="sh">'</span><span class="s">center</span><span class="sh">'</span><span class="p">,</span>
<span class="n">verticalalignment</span><span class="o">=</span><span class="sh">'</span><span class="s">top</span><span class="sh">'</span><span class="p">,</span> <span class="n">transform</span> <span class="o">=</span> <span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">transAxes</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$N/K$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">time, $t$</span><span class="sh">"</span><span class="p">)</span>
<span class="nf">subplotaxis_off</span><span class="p">(</span><span class="n">ax</span><span class="p">)</span></code></pre></figure> <p><img src="/assets/posts/chaos-in-biological-populations_files/chaos-in-biological-populations_3_0.svg" alt="svg"/></p> <p>The behavior seen above heavily depends on the initial seed value of $N_0$, and we can see that although the 3 graphs have the same $r$ value, no two graphs exhibit the same bahavior. This strong dependence on the inital values indicates that the value of the growth rate $r$ is in the chaotic regime.</p> <p>It is interesting to see that the equation we are modelling appears as a very simple and deterministic population growth model, and yes it exhibits deterministic, as well a arbitrarily dynamic behavior for large enough values of the growth rate ($r&gt;2.692$).</p> <h2 id="two-competing-species">Two competing species</h2> <p>We can also model the competition of two species using two coupled deterministic equations similar to the single species case,</p> \[N_1(t+1) = N_1(t)\exp{\{r_1[K_1 - \alpha_{11}N_1(t) - \alpha_{12}N_2(t)]/K_1\}}\] \[N_2(t+1) = N_2(t)\exp{\{r_2[K_2 - \alpha_{21}N_1(t) - \alpha_{22}N_2(t)]/K_2\}}\] <p><strong>In [3]:</strong></p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">N1_0</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">N2_0</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">K_1</span> <span class="o">=</span> <span class="mi">1000</span>
<span class="n">K_2</span> <span class="o">=</span> <span class="mi">1000</span>
<span class="n">alpha</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span><span class="mf">0.5</span><span class="p">],</span> <span class="p">[</span><span class="mf">0.5</span><span class="p">,</span><span class="mi">1</span><span class="p">]])</span>
<span class="n">species1</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">r_1</span><span class="p">,</span> <span class="n">N_1</span><span class="p">,</span> <span class="n">N_2</span><span class="p">,</span> <span class="n">K_1</span><span class="o">=</span><span class="n">K_1</span><span class="p">,</span> <span class="n">K_2</span><span class="o">=</span><span class="n">K_2</span><span class="p">:</span> <span class="n">N_1</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="n">r_1</span><span class="o">*</span><span class="p">(</span><span class="n">K_2</span> <span class="o">-</span> <span class="n">alpha</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="n">N_1</span> <span class="o">-</span> <span class="n">alpha</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span><span class="o">*</span><span class="n">N_2</span><span class="p">)</span><span class="o">/</span><span class="n">K_2</span><span class="p">)</span>
<span class="n">species2</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">r_2</span><span class="p">,</span> <span class="n">N_1</span><span class="p">,</span> <span class="n">N_2</span><span class="p">,</span> <span class="n">K_1</span><span class="o">=</span><span class="n">K_1</span><span class="p">,</span> <span class="n">K_2</span><span class="o">=</span><span class="n">K_2</span><span class="p">:</span> <span class="n">N_2</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="nf">exp</span><span class="p">(</span><span class="n">r_2</span><span class="o">*</span><span class="p">(</span><span class="n">K_2</span> <span class="o">-</span> <span class="n">alpha</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="n">N_1</span> <span class="o">-</span> <span class="n">alpha</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span><span class="o">*</span><span class="n">N_2</span><span class="p">)</span><span class="o">/</span><span class="n">K_2</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">competition_growth</span><span class="p">(</span><span class="n">r_1</span><span class="p">,</span> <span class="n">r_2</span><span class="p">,</span> <span class="n">timesteps</span><span class="p">,</span> <span class="n">N1_0</span><span class="o">=</span><span class="n">N1_0</span><span class="p">,</span> <span class="n">N2_0</span><span class="o">=</span><span class="n">N2_0</span><span class="p">,</span> <span class="n">K_1</span><span class="o">=</span><span class="n">K_1</span><span class="p">,</span> <span class="n">K_2</span><span class="o">=</span><span class="n">K_2</span><span class="p">):</span>
<span class="n">N</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">([</span><span class="nf">len</span><span class="p">(</span><span class="n">timesteps</span><span class="p">),</span> <span class="mi">2</span><span class="p">])</span>
<span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">,:]</span> <span class="o">=</span> <span class="p">[</span><span class="n">N1_0</span><span class="p">,</span> <span class="n">N2_0</span><span class="p">]</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">time</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">timesteps</span><span class="p">):</span>
<span class="k">if</span> <span class="n">i</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">:</span>
<span class="n">N</span><span class="p">[</span><span class="n">i</span><span class="p">,:]</span> <span class="o">=</span> <span class="p">[</span><span class="nf">species1</span><span class="p">(</span><span class="n">r_1</span><span class="p">,</span> <span class="n">N</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">]),</span> <span class="nf">species2</span><span class="p">(</span><span class="n">r_2</span><span class="p">,</span> <span class="n">N</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">])]</span>
<span class="k">return</span> <span class="n">N</span>

<span class="n">timesteps</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span>
<span class="n">r_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1.1</span><span class="p">,</span> <span class="mf">1.5</span><span class="p">,</span> <span class="mf">2.5</span><span class="p">,</span> <span class="mi">4</span><span class="p">]</span>
<span class="n">population</span> <span class="o">=</span> <span class="p">[</span><span class="nf">competition_growth</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="mi">2</span>\<span class="o">*</span><span class="n">r</span><span class="p">,</span> <span class="n">timesteps</span><span class="p">)[:,</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">r_list</span><span class="p">]</span>

<span class="n">fig</span><span class="p">,</span> <span class="n">axes</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">subplots</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">r_list</span><span class="p">),</span> <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span> <span class="n">sharex</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">dpi</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
<span class="k">with</span> <span class="n">sns</span><span class="p">.</span><span class="nf">axes_style</span><span class="p">(</span><span class="sh">"</span><span class="s">whitegrid</span><span class="sh">"</span><span class="p">):</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="p">.</span><span class="nf">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">grid</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">r_list</span><span class="p">):</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">plot</span><span class="p">(</span><span class="n">timesteps</span><span class="p">,</span> <span class="n">population</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">/</span><span class="n">K</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="sh">'</span><span class="s">y</span><span class="sh">'</span><span class="p">,</span> <span class="n">nbins</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">set_ylim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">np</span><span class="p">.</span><span class="nf">max</span><span class="p">(</span><span class="n">population</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">/</span><span class="n">K</span><span class="p">)</span><span class="o">+</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">text</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.99</span><span class="p">,</span><span class="sa">r</span><span class="sh">'</span><span class="s">$r=%.2f$</span><span class="sh">'</span> <span class="o">%</span> <span class="n">r</span><span class="p">,</span> <span class="n">horizontalalignment</span><span class="o">=</span><span class="sh">'</span><span class="s">center</span><span class="sh">'</span><span class="p">,</span>
<span class="n">verticalalignment</span><span class="o">=</span><span class="sh">'</span><span class="s">top</span><span class="sh">'</span><span class="p">,</span> <span class="n">transform</span> <span class="o">=</span> <span class="n">axes</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">transAxes</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">$N_1/K$</span><span class="sh">"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">"</span><span class="s">time, $t$</span><span class="sh">"</span><span class="p">)</span>
<span class="nf">subplotaxis_off</span><span class="p">(</span><span class="n">ax</span><span class="p">)</span></code></pre></figure> <p><img src="/assets/posts/chaos-in-biological-populations_files/chaos-in-biological-populations_6_0.svg" alt="svg"/></p>]]></content><author><name></name></author><category term="Python"/><category term="Complex Systems"/><summary type="html"><![CDATA[Single species model]]></summary></entry><entry><title type="html">Project: Car Tracking for velocity measurement</title><link href="https://damiandailisan.com/blog/2014/project-car-tracking-for-velocity/" rel="alternate" type="text/html" title="Project: Car Tracking for velocity measurement"/><published>2014-10-28T00:00:00+00:00</published><updated>2014-10-28T00:00:00+00:00</updated><id>https://damiandailisan.com/blog/2014/project-car-tracking-for-velocity</id><content type="html" xml:base="https://damiandailisan.com/blog/2014/project-car-tracking-for-velocity/"><![CDATA[<p>For my project, I want to try tracking cars in a video to determine velocities of vehicle on the road. Just a simple code with a rough estimate of velocity is what I need for now, I don’t need to match velocities to specific cars yet. But first, I need to be able to track an object across a video, which is simply a series of still images.</p> <h2 id="tracking-based-on-image-segmentation">Tracking based on Image Segmentation</h2> <p><img src="http://1.bp.blogspot.com/-37kpVVTX3VA/VFg19D7w6XI/AAAAAAAAAXA/gd51pcGPTLU/s1600/0092.png" alt=""/></p> <p>We can start things of by tracking a ping-pong ball undergoing projectile motion to calculate the acceleration due to gravity. We simply converted the video to a series of images using ffmpeg as a decoder. Then we took a set of images which corresponds to one projectile motion.</p> <p><img src="http://3.bp.blogspot.com/-EExvBGS2Xws/VFg19C1VTlI/AAAAAAAAAW8/ud53uNSHDWw/s1600/roi.jpg" alt=""/></p> <p>We select the ROI by color, just crop the pingpong ball. And then use Image segmentation using <a href="/blog/2014/image-segmentation/">histogram back projection</a>.</p> <p><img src="http://2.bp.blogspot.com/-712CpDx7Hns/VFg19AFXHbI/AAAAAAAAAXE/DvmFW3yeizE/s1600/back.jpg" alt=""/></p> <p>Now we have a collection of points which represent the ball. We can improve the quality of our collection of points using morphological operations to clean it as well. We can get the centroid using this following snippet of code:</p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">IsCalculated</span> <span class="o">=</span> <span class="nc">CreateFeatureStruct</span><span class="p">(</span><span class="o">%</span><span class="n">f</span><span class="p">);</span>
<span class="n">IsCalculated</span><span class="p">.</span><span class="n">Centroid</span> <span class="o">=</span> <span class="o">%</span><span class="n">t</span><span class="p">;</span>
<span class="n">C</span> <span class="o">=</span> <span class="nc">AnalyzeBlobs</span><span class="p">(</span><span class="n">im</span><span class="p">,</span> <span class="n">IsCalculated</span><span class="p">);</span>
<span class="n">Centroid</span> <span class="o">=</span> <span class="nc">C</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="n">Centroid</span><span class="p">;</span>
<span class="n">y</span> <span class="o">=</span> <span class="p">[</span><span class="n">y</span> <span class="nc">Centroid</span><span class="p">(</span><span class="mi">2</span><span class="p">)];</span>
<span class="n">x</span> <span class="o">=</span> <span class="p">[</span><span class="n">x</span> <span class="nc">Centroid</span><span class="p">(</span><span class="mi">1</span><span class="p">)];</span></code></pre></figure> <p>Doing this for the rest of the images, we will get a collection of x and y positions, which we can plot using excel. Of course, these x and y positions need to be scaled properly, using</p> <figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">yscale</span> <span class="o">=</span> <span class="p">.</span><span class="mi">05</span><span class="o">/</span><span class="mi">20</span> <span class="o">//</span> <span class="n">meters</span> <span class="n">to</span> <span class="n">pixels</span>
<span class="n">xscale</span> <span class="o">=</span> <span class="p">.</span><span class="mi">05</span><span class="o">/</span><span class="mi">14</span> <span class="o">//</span> <span class="n">meters</span> <span class="n">to</span> <span class="n">pixels</span>
<span class="n">Y</span> <span class="o">=</span> <span class="o">-</span><span class="n">yscale</span><span class="o">*</span><span class="p">(</span><span class="n">y</span><span class="o">-</span><span class="mi">240</span><span class="p">);</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">xscale</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="p">);</span></code></pre></figure> <p>If we fit a second order polynomial to the y positions and time, we should get</p> <p><img src="http://1.bp.blogspot.com/-84kfWpIKTwA/VFg6UgfC0HI/AAAAAAAAAXY/eew52qeaFlM/s1600/color.png" alt=""/></p> <p>The term $-4.8871$ is actually $-\frac{g}{2}$. Hence, we have $g=9.77\,\frac{m}{s^2}$.</p> <h2 id="tracking-based-on-image-difference">Tracking Based on Image Difference</h2> <p>Vehicles will not always have the same color on the road. The method of image segmentation is good, but we need something more robust if we want to be able to make a generic car velocity estimator just by video processing. A possible alternative method is using image difference. We need an image of just the background.</p> <p><img src="http://4.bp.blogspot.com/-OgHTmJvfy7M/VFg7v5kP7oI/AAAAAAAAAXk/smnZ2krxTJ8/s1600/bg.jpg" alt=""/></p> <p>Then we take the difference of every frame with this frame. To binarize the difference , we set a threshold value, which will determine if pixels in the difference will be black or white.</p> <p>We’ll get another blob, from which we can get its position using centroids. We can get the following graph below:</p> <p><img src="http://1.bp.blogspot.com/-0eZgnGVw4lQ/VGq-yLZQyFI/AAAAAAAAAX0/zWEYFrxgEyk/s1600/graph.png" alt=""/></p> <p>The term $-4.8871$ is actually $-\frac{g}{2}$. Hence, we have $g=9.78\,\frac{m}{s^2}$. This is a similar result as with using image segmentation by color. We are now ready to track car videos.</p> <h2 id="tracking-cars-from-a-video">Tracking cars from a video</h2> <p><img src="http://2.bp.blogspot.com/-X21Eu_daJbo/VGq-6Rx6FKI/AAAAAAAAAYA/INZwQLRsO44/s1600/fig1.jpg" alt=""/></p> <p>A video frame would look like the image shown above. Since we are working with a video captured by a different person, we do not have a background that we can readily use as a reference. Instead, we utilize the difference of subsequent frames, and hope to find the outlines of the vehicles on the road. However, as shown in the next two figures, this is not as straightforward as the previous methodology of subtracting a reference background.</p> <p><img src="http://2.bp.blogspot.com/-tcvLrTyL9sU/VGq-6Az9ewI/AAAAAAAAAX8/CHPBWn1oD6s/s1600/diff.jpg" alt=""/></p> <p><img src="http://3.bp.blogspot.com/-1kz2FFv-Vn4/VGq-7oOHZuI/AAAAAAAAAYU/HZjj5vt3GC0/s1600/imdiff.png" alt=""/></p> <p><img src="http://2.bp.blogspot.com/-2nE8WvBfkb4/VGq-8QTDe6I/AAAAAAAAAYc/4xYRBU4GlhI/s1600/std.jpg" alt="tracks"/></p> <p><img src="http://3.bp.blogspot.com/-QaViLEdy55E/VGq-6b2dsMI/AAAAAAAAAYE/CnSJQJ5PM_g/s1600/histogram.png" alt=""/></p>]]></content><author><name></name></author><category term="Python"/><category term="Image Processing"/><summary type="html"><![CDATA[For my project, I want to try tracking cars in a video to determine velocities of vehicle on the road. Just a simple code with a rough estimate of velocity is what I need for now, I don’t need to match velocities to specific cars yet. But first, I need to be able to track an object across a video, which is simply a series of still images.]]></summary></entry><entry><title type="html">Morphological Operations</title><link href="https://damiandailisan.com/blog/2014/dilation-and-erosion-dilation-and/" rel="alternate" type="text/html" title="Morphological Operations"/><published>2014-10-02T03:41:00+00:00</published><updated>2014-10-02T03:41:00+00:00</updated><id>https://damiandailisan.com/blog/2014/dilation-and-erosion-dilation-and</id><content type="html" xml:base="https://damiandailisan.com/blog/2014/dilation-and-erosion-dilation-and/"><![CDATA[<h2 id="dilation-and-erosion">Dilation and Erosion</h2> <p>Dilation and erosion was performed by hand on a graphing paper. The initial shapes and structuring elements are outlined in red, while the results are outlined in blue. In the structuring element, we first chose a pixel to use as the “origin”. We reflect the image about this origin.</p> <p>For Dilation, we move the element around the shape, such that the origin remains in the shape. The combined outlines of the structuring element as it moves through the shape is the Dilation.</p> <p style="text-align: center;"><img src="http://1.bp.blogspot.com/-VaJ0pngO2-w/VCzD8fD-7fI/AAAAAAAAAUA/pVokgY96cw8/s1600/dilation.jpg" alt=""/><br/> <em>Dilation</em></p> <p>For Erosion, we move the element around the shape, such that the element remains in the shape. The shape traced out by the origin is the Erosion of the shape due to the element.</p> <p style="text-align: center;"><img src="http://3.bp.blogspot.com/-XwA9vsw3aTA/VCzEft9MrkI/AAAAAAAAAUI/pmpoXv9Hg1I/s1600/erosion.jpg" alt=""/><br/> <em>Erosion</em></p> <p>In general, we can say that Dilation makes the shape bigger, while Erosion makes the shape smaller.</p> <h2 id="computer-simulation">Computer Simulation</h2> <p style="text-align: center;"><img src="http://2.bp.blogspot.com/-tGnOmzjs_SQ/VCy_9STV2kI/AAAAAAAAATY/02g_6jjYX-s/s1600/dilation%2Ball.png" alt=""/><br/> <em>Dilation</em></p> <p style="text-align: center;"><img src="http://3.bp.blogspot.com/-fsWZpXOKcU8/VCy_-6EazII/AAAAAAAAATg/paMRZRIDCog/s1600/erosion%2Ball.png" alt=""/><br/> <em>Erosion</em></p> <p>I performed Dilation and Erosion in Scilab using the IPD toolbox. The results I obtained were consistent with my hand drawn Dilations and Erosions.</p> <h2 id="cancer-cell-detection">Cancer Cell Detection</h2> <p>The image file <code class="language-plaintext highlighter-rouge">Circles.jpg</code> was first binarized by setting a threshold value. The binarized image was then cleaned of small white dots using OpenImage, and holes in big circles were filled using CloseImage. The result is shown below (as a whole image, not the subimages). The image was segmented into subimages so that better thresholding can be applied on the different areas of the image, which may not be uniformly illuminated.</p> <p><img src="http://3.bp.blogspot.com/-gzDyeREQkKU/VCzNiWDgCOI/AAAAAAAAAUk/JPYymCG4USs/s1600/circ.png" alt=""/></p> <p>From this, we can measure the best estimate for “normal cells”. We used SearchBlobs first, and then filtered the results to remove obviously large and small cells by area. Small cells would be less than 300 in area. Big cells will be above 600. After this filtering we get</p> <p style="text-align: center;">mean = 492<br/> stdev = 49.7</p> <p>From the mean and standard deviation, we used the same process to binarize <code class="language-plaintext highlighter-rouge">Circles with cancer.jpg</code>. Using SearchBlobs, we removed blobs which fit the best estimates for a normal cell. This leaves us with our abnormal cells, shown in the image below.</p> <p><img src="http://2.bp.blogspot.com/-gdg95Hez3-E/VCzJq2u_BaI/AAAAAAAAAUY/kVvwHM2r2DQ/s1600/cancer.png" alt=""/></p>]]></content><author><name>Damian</name></author><category term="Image Processing"/><summary type="html"><![CDATA[Dilation and Erosion]]></summary></entry></feed>