<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shriphani Palakodety &#187; python</title>
	<atom:link href="http://shriphani.com/blog/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://shriphani.com/blog</link>
	<description>In Pursuit Of Truth and Beauty</description>
	<lastBuildDate>Sat, 28 Aug 2010 23:54:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Listener Gets Another VAD</title>
		<link>http://shriphani.com/blog/2010/08/09/listener-gets-another-vad/</link>
		<comments>http://shriphani.com/blog/2010/08/09/listener-gets-another-vad/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 23:46:49 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA["voice activity detection"]]></category>
		<category><![CDATA["voice"]]></category>
		<category><![CDATA[Listener]]></category>
		<category><![CDATA[VAD]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=631</guid>
		<description><![CDATA[A list of additions to Listener. The additions include a new Voice Activity Detection algorithm.]]></description>
			<content:encoded><![CDATA[<p>Over this summer, I wanted to make <a href="http://shriphani.com/blog/Listener" target="_blank">Listener</a> Python only (there was a ton of needless applescript) and since my work @ VACCINE [<a href="http://www.purdue.edu/discoverypark/vaccine/" target="_blank">VACCINE homepage</a>] (more on this in a new post) didn&#8217;t leave much time for tinkering with things, I had to push this back as much as I could. I also added another voice activity detection algorithm which I believe works a lot better than what I had previously. And I also moved my project over to GITHUB.</p>
<p>The additions to Listener:</p>
<ul>
<li>A new Voice Activity Detection algorithm <a href="http://www.eurasip.org/proceedings/eusipco/eusipco2009/contents/papers/1569192958.pdf" target="_blank">[ link to pdf by Moattar and Homayounpour]</a>.</li>
<li>Skype4Py is still buggy on OS X with Python2.5 and it takes a nice solid dump (segfault) with Python2.6 so I am sure if the Skype part of the code works.</li>
<li>Python only. I removed the applescript portion from my code.</li>
</ul>
<p>I have moved the entire code over to github: <a href="http://github.com/shriphani/Listener/">http://github.com/shriphani/Listener/</a> . The VAD algorithms can be seen in the file <a href="http://github.com/shriphani/Listener/blob/master/VAD.py" target="_blank">VAD.py</a>.</p>
<p>This VAD also works by starting off with a base threshold for energy, power and an attribute called Spectral Flatness Measure. Luckily the paper had pseudocode so my DSP n00bishness wouldn&#8217;t get in the way of progress.</p>
<p>Anyway, to get this version of Listener running, download <a href="http://github.com/downloads/shriphani/Listener/Listener.tar" target="_blank">Listener.tar</a> , untar it and run:</p>
<pre>python2.5 audio_analysis.py</pre>
<p>And you should be all set.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2010/08/09/listener-gets-another-vad/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bellman-Ford Algorithm&#8217;s Applications &#8211; Triangular Arbitrage</title>
		<link>http://shriphani.com/blog/2010/07/02/bellman-ford-algorithms-applications-triangular-arbitrage/</link>
		<comments>http://shriphani.com/blog/2010/07/02/bellman-ford-algorithms-applications-triangular-arbitrage/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 01:30:57 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[arbitrage]]></category>
		<category><![CDATA[bellman-ford]]></category>
		<category><![CDATA[cs]]></category>
		<category><![CDATA[graphs]]></category>
		<category><![CDATA[shortest-path]]></category>
		<category><![CDATA[triangular-arbitrage]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=582</guid>
		<description><![CDATA[Using the Bellman-Ford Single Source Shortest Path algorithm to detect triangular arbitrage. ]]></description>
			<content:encoded><![CDATA[<p>A very interesting application of the bellman-ford algorithm is arbitrage, essentially, given a table of currencies and their exchange rates, one needs to be able to figure out if we can start with a certain amount of money in one currency, exchange this amount for other currencies and end up with more money than what we had at first.</p>
<p>Example: 1 USD gives us 0.8 Euro and 1 Euro gives us 0.8 GBP and 1 GBP gives us 1.7 USD. So if I start with 1 dollar, I can exchange it for 0.8 Euro which can then be exchanged for 0.64 GBP and if converted back to USD we have 1.088 dollars.</p>
<p>So if rate_i_j is used to represent the amount of currency_j which we can get for 1 unit of currency_i, we observe:</p>
<p>rate_i_j * rate_j_k * rate_k_l * &#8230;.. * rate_z_i &gt; 1</p>
<p>Invert this to get:</p>
<p>1/(rate_i_j * rate_j_k * rate_k_l * &#8230;.. * rate_z_i) &lt; 1</p>
<p>and take lg on both sides:</p>
<p>lg(1/rate_i_j) + lg(1/rate_j_k) + &#8230;.. + lg(1/rate_z_i) &lt; 0</p>
<p>So we observe that if we represent our table using a graph with lg(1/exchange_rate) as the weights, then the presence of a negative weight cycle is all that is needed to ensure we get more $$ than we started out with.</p>
<p>And of course, negative weight cycle detection is really easy with the bellman-ford single source shortest path algorithm.</p>
<p>This algorithm operates by the following dynamic programming equation:</p>
<p>distanceFromSource(v) = distanceFromSource(w) + weight(w, v)</p>
<p>When we set the distance of vertex &#8216;v&#8217; from the source, we look at the edge (w, v) and observe that if we can get to &#8216;v&#8217; by a shorter path through &#8216;w&#8217;, we discard the old distance and set distanceFromSource(w) + weight(w, v) as the new distance. This operation is called &#8220;Relaxing an edge&#8221;</p>
<p>Now, we only need to observe every edge a certain number of times. Precisely |V| &#8211; 1 times. Why? Well, consider a graph where the max out-degree is 1.</p>
<p>So, we have something like: v1 &#8212;-&gt; v2 &#8212;&#8211;&gt; v3 &#8212;&#8211;&gt; v4 &#8212;&#8212;&gt; &#8230;&#8230;.. &#8212;&#8212;&gt; v{n}. This is a directed graph with n vertices. If our source is v1, in the first of |V| &#8211; 1 iterations, we relax the first edge and fix the path to v2 (cannot get to v2 using a shorter path see?). In the second iteration, the path to v3 is fixed and continuing this we finish fixing the paths to the vertices |V| &#8211; 1 iterations (Remember, you relax <strong>every</strong> edge in each iteration).</p>
<p>To detect a negative weight cycle, finish relaxing all the edges |V| &#8211; 1 times. Now, carry the relax operation out once again. Since, all paths from the source to each vertex are guaranteed to be fixed by now, if you ever stumble upon a situation where you change distanceFromSource(v) for a vertex v, then a negative weight cycle starts and ends at v. The result of this is that a shortest path to v cannot be found, since for every path to v, you can make another trip about this negative-weight cycle and obtain an even shorter path.</p>
<p>So, I wrote a simple script for the Bellman-Ford routine and tested it using the USD, Euro, GBP example.</p>
<p>Here&#8217;s the Bellman-Ford routine:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="co1">#!/usr/bin/env python</span><br />
<span class="co1">#Author: Shriphani Palakodety</span></p>
<p><span class="co1">#Bellman Ford Implementation. Look it up on wikipedia.</span></p>
<p>distances = <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
parents = <span class="br0">&#123;</span><span class="br0">&#125;</span></p>
<p><span class="kw1">def</span> Initialize<span class="br0">&#40;</span>graph, start<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Prepares the graph for the bellman-ford algorithm&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> vertex <span class="kw1">in</span> graph.<span class="me1">V</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> graph.<span class="me1">E</span>.<span class="me1">has_key</span><span class="br0">&#40;</span><span class="br0">&#40;</span>start, vertex<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distances<span class="br0">&#91;</span>vertex<span class="br0">&#93;</span> = 9999999e6</p>
<p>&nbsp; &nbsp; distances<span class="br0">&#91;</span>start<span class="br0">&#93;</span> = <span class="nu0">0</span><br />
&nbsp; &nbsp; parents<span class="br0">&#91;</span>start<span class="br0">&#93;</span> = <span class="kw2">None</span></p>
<p><span class="kw1">def</span> Bellman_Ford<span class="br0">&#40;</span>graph, start<span class="br0">&#41;</span>:</p>
<p>&nbsp; &nbsp; Initialize<span class="br0">&#40;</span>graph, start<span class="br0">&#41;</span> <span class="co1">#first initialize the graph</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>graph.<span class="me1">V</span><span class="br0">&#41;</span> &#8211; <span class="nu0">1</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> edge <span class="kw1">in</span> graph.<span class="me1">E</span>.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>graph.<span class="me1">E</span><span class="br0">&#91;</span>edge<span class="br0">&#93;</span> + distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &lt; distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span> = graph.<span class="me1">E</span><span class="br0">&#91;</span>edge<span class="br0">&#93;</span> + distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parents<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span> = edge<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; <span class="co1">#one final check for negative weight cycles.</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> edge <span class="kw1">in</span> graph.<span class="me1">E</span>.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>graph.<span class="me1">E</span><span class="br0">&#91;</span>edge<span class="br0">&#93;</span> + distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &lt; distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span> = graph.<span class="me1">E</span><span class="br0">&#91;</span>edge<span class="br0">&#93;</span> + distances<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parents<span class="br0">&#91;</span>edge<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span> = edge<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> edge<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> <span class="co1">#return here since, a negative weight cycle is detected</span></p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">None</span> <span class="co1">#return none on successful completion.</span></div>
<p>And the test itself:</p>
<div class="dean_ch" style="white-space: nowrap;">!/usr/bin/env python<br />
<span class="co1">#Author: Shriphani Palakodety</span><br />
<span class="co1">#Mail: spalakod@purdue.edu</span></p>
<p><span class="co1">#Testing Arbitrage</span></p>
<p><span class="co1">#import graph</span><br />
<span class="kw1">import</span> bellman_ford<br />
<span class="kw1">from</span> <span class="kw3">math</span> <span class="kw1">import</span> log</p>
<p><span class="co1">#in the format cur1_cur2 = no. of units of cur2 for 1 unit of cur1</span></p>
<p>usd_euro = <span class="nu0">0.8</span><br />
euro_gbp = <span class="nu0">0.8</span><br />
gbp_usd = <span class="nu0">1.7</span></p>
<p><span class="co1">#Nodes List</span><br />
nodes = <span class="br0">&#91;</span><span class="st0">&quot;usd&quot;</span>, <span class="st0">&quot;euro&quot;</span>, <span class="st0">&quot;gbp&quot;</span><span class="br0">&#93;</span><br />
edge_dict = <span class="br0">&#123;</span> <span class="br0">&#40;</span><span class="st0">&quot;usd&quot;</span>, <span class="st0">&quot;euro&quot;</span><span class="br0">&#41;</span> : log<span class="br0">&#40;</span><span class="nu0">1</span>/usd_euro<span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="st0">&quot;euro&quot;</span>, <span class="st0">&quot;gbp&quot;</span><span class="br0">&#41;</span> : log<span class="br0">&#40;</span><span class="nu0">1</span>/euro_gbp<span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="st0">&quot;gbp&quot;</span>, <span class="st0">&quot;usd&quot;</span><span class="br0">&#41;</span> : log<span class="br0">&#40;</span><span class="nu0">1</span>/gbp_usd<span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="st0">&quot;euro&quot;</span>, <span class="st0">&quot;usd&quot;</span><span class="br0">&#41;</span> : log<span class="br0">&#40;</span>usd_euro<span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="st0">&quot;gbp&quot;</span>, <span class="st0">&quot;euro&quot;</span><span class="br0">&#41;</span> : log<span class="br0">&#40;</span>euro_gbp<span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="st0">&quot;usd&quot;</span>, <span class="st0">&quot;gbp&quot;</span><span class="br0">&#41;</span> : log<span class="br0">&#40;</span>gbp_usd<span class="br0">&#41;</span><span class="br0">&#125;</span><br />
<span class="co1">#make a small graph to represent the currency network.</span></p>
<p>cur_graph = bellman_ford.<span class="me1">Graph</span><span class="br0">&#40;</span>nodes, edge_dict<span class="br0">&#41;</span></p>
<p><span class="kw1">print</span> bellman_ford.<span class="me1">Bellman_Ford</span><span class="br0">&#40;</span>cur_graph, <span class="st0">&quot;usd&quot;</span><span class="br0">&#41;</span></div>
<p>And when run, I get:</p>
<pre>?(shriphani@Shriphani-Palakodetys-MacBook-Pro)?(533/ttys001)?(09:10P:07/02/10)?-
??(%:~/scripts)?- python arbitrage_test.py
usd
??(shriphani@Shriphani-Palakodetys-MacBook-Pro)?(534/ttys001)?(09:10P:07/02/10)?-
??(%:~/scripts)?-</pre>
<p>So, there&#8217;s a negative weight cycle and if you kick off with some USD, you can get rich.</p>
<p>Get my routines here:</p>
<ul>
<li><a href="http://shriphani.com/scripts/bellman_ford.py">Bellman-Ford</a></li>
<li><a href="http://shriphani.com/scripts/arbitrage_test.py">Test For Arbitrage</a></li>
</ul>
<p>My code reads too much like pseudocode. Didn&#8217;t know a theory class corrupts so much.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2010/07/02/bellman-ford-algorithms-applications-triangular-arbitrage/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Disjoint Set Data Structure</title>
		<link>http://shriphani.com/blog/2010/05/20/disjoint-set-data-structure/</link>
		<comments>http://shriphani.com/blog/2010/05/20/disjoint-set-data-structure/#comments</comments>
		<pubDate>Thu, 20 May 2010 01:35:54 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA["disjoint sets"]]></category>
		<category><![CDATA["kruskal"]]></category>
		<category><![CDATA["path compression"]]></category>
		<category><![CDATA["weighted union"]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[analysis of algorithms]]></category>
		<category><![CDATA[cs]]></category>
		<category><![CDATA[purdue]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=542</guid>
		<description><![CDATA[Two implementations of a disjoint set data structure and an implementation of kruskal's algorithm.]]></description>
			<content:encoded><![CDATA[<p>The last two weeks didn&#8217;t really offer a lot of challenges considering the semester is over and I didn&#8217;t grow a big enough pair to actually leave the practice rooms in TopCoder and go participate. So, I decided to revise some of the most interesting stuff I learned in my CS 381 class. And since I really liked the stuff we did with Disjoint Sets (not a lot of stuff, just kruskal&#8217;s algorithm but it still is pretty neat).We typically define 3 operations on disjoint sets:</p>
<ul>
<li>MakeSet(x) : Create a set with the element &#8216;x&#8217; in it.</li>
<li>FindSet(x) : Return the set that the element belongs to</li>
<li>Union(x, y) : Make a new set defined as :  <a href="http://shriphani.com/blog/wp-content/uploads/2010/05/CodeCogsEqn.gif"><img class="alignnone size-full wp-image-543" title="CodeCogsEqn" src="http://shriphani.com/blog/wp-content/uploads/2010/05/CodeCogsEqn.gif" alt="" width="146" height="21" /></a> where <a href="http://shriphani.com/blog/wp-content/uploads/2010/05/CodeCogsEqn2.gif"><img class="alignnone size-full wp-image-544" title="CodeCogsEqn(2)" src="http://shriphani.com/blog/wp-content/uploads/2010/05/CodeCogsEqn2.gif" alt="" width="50" height="15" /></a> and   <a href="http://shriphani.com/blog/wp-content/uploads/2010/05/CodeCogsEqn3.gif"><img class="alignnone size-full wp-image-545" title="CodeCogsEqn(3)" src="http://shriphani.com/blog/wp-content/uploads/2010/05/CodeCogsEqn3.gif" alt="" width="48" height="18" /></a> and destroy X and Y.</li>
</ul>
<h2><span style="text-decoration: underline;">Implementation Using A Linked List:</span></h2>
<p>Here each set is represented by placing its elements in the nodes of a linked list. In each node, we also store a pointer to the parent which contains the name of each set and some other information like the number of elements in the set, the name and so on.</p>
<h3><span style="text-decoration: underline;">Running Time For Each Operation:</span></h3>
<p>MakeSet(x) : Constant Time</p>
<p>FindSet(x) : Return the parent that the parent pointer points to</p>
<p>Union(x, y)  :  Assume X is the set x resides in and Y is the set y resides in. Now, if we append the elements of X to Y, we would need to walk through X and set the parent pointers to Y. So, 1 union operation takes O(n) time.</p>
<h3><span style="text-decoration: underline;">Special Heuristics</span>:</h3>
<p>The Union(x, y) implementation gets a slight change here. When deciding which set to append to the other in the union operation, we append that set which has fewer elements to the other set. The advantage is that the walk through the list to change the parent takes lesser time.</p>
<h2><span style="text-decoration: underline;">Implementation Using A Tree:</span></h2>
<p>We represent a set by a rooted tree where each node points to its parent (not parent -&gt; children but the other way round). We define a special term here called rank. The rank of a set is an upper bound on the height of the tree. Why it is an upper bound will be evident soon.</p>
<h3><span style="text-decoration: underline;">Running Time Per Operation:</span></h3>
<p>MakeSet(x) : Constant Time. Let x be a node whose parent is itself</p>
<p>FindSet(x) : O(log(n)) time. Basically need to go from x to the root.</p>
<p>Union(x, y): Constant time. We just make the root of either X or Y (the sets x and y belong to respectively) the parent of the other root.</p>
<h3><span style="text-decoration: underline;">Special Heuristics:</span></h3>
<p>We use a heuristic here called path compression. When we run FindSet(x), we typically traverse the path from x to the root. With path compression, we basically make all nodes on this path the immediate children of the root. The advantage? Subsequent FindSet() operations on these nodes take constant time. This might modify the actual height (as you can see). BUT YOU DON&#8217;T CHANGE THE RANK HERE. Hence the rank is an &#8220;upper-bound&#8221; on the height. If we didn&#8217;t have the path-compression heuristic, the rank would have been the height.</p>
<p>So, the code follows. First the linked list implementation:</p>
<p>Here are the class definitions for the Nodes, the List and the Universe</p>
<div class="dean_ch" style="white-space: nowrap;">valueNodeDict = <span class="br0">&#123;</span><span class="br0">&#125;</span></p>
<p><span class="kw1">class</span> Node<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Represents a node of the linked list&#8217;</span><span class="st0">&#8221;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, value, parent, next=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">value</span> = value<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">next</span> = next<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">parent</span> = parent<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; valueNodeDict<span class="br0">&#91;</span>value<span class="br0">&#93;</span> = <span class="kw2">self</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__str__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">str</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">value</span><span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> List<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Represents the linked list itself&#8217;</span><span class="st0">&#8221;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name, value=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Creates a set and sets head and tail to the appropriate nodes&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">count</span> = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> value <span class="kw1">is</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">head</span> = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tail</span> = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">head</span> = Node<span class="br0">&#40;</span>value, <span class="kw2">self</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tail</span> = <span class="kw2">self</span>.<span class="me1">head</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">count</span> += <span class="nu0">1</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__str__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Lists out all the elements&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = <span class="kw2">self</span>.<span class="me1">name</span> + <span class="st0">&quot;: &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node = <span class="kw2">self</span>.<span class="me1">head</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> node != <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s += <span class="kw2">str</span><span class="br0">&#40;</span>node<span class="br0">&#41;</span> + <span class="st0">&quot;, &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node = node.<span class="me1">next</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> s + <span class="st0">&quot;<span class="es0">\n</span>&quot;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> addElement<span class="br0">&#40;</span><span class="kw2">self</span>, node<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Add another node&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tail</span>.<span class="me1">next</span> = node<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tail</span> = <span class="kw2">self</span>.<span class="me1">tail</span>.<span class="me1">next</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">count</span> += <span class="nu0">1</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> changeParent<span class="br0">&#40;</span><span class="kw2">self</span>, newParent<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Changes the parent of every node in the set&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node = <span class="kw2">self</span>.<span class="me1">head</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> node <span class="kw1">is</span> <span class="kw1">not</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.<span class="me1">parent</span> = newParent<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node = node.<span class="me1">next</span></p>
<p><span class="kw1">class</span> Universe<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Operations you can perform in the universe&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, name=<span class="st0">&quot;U&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Creates the universe where all your subsequent sets belong&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">name</span> = name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">setCount</span> = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="kw3">sets</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__str__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = <span class="kw2">self</span>.<span class="me1">name</span> + <span class="st0">&quot;:<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="kw2">set</span> <span class="kw1">in</span> <span class="kw2">self</span>.__sets:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s += <span class="st0">&quot;<span class="es0">\t</span>&quot;</span> + <span class="kw2">str</span><span class="br0">&#40;</span><span class="kw2">set</span><span class="br0">&#41;</span> + <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> s</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> addSet<span class="br0">&#40;</span><span class="kw2">self</span>, name=<span class="kw2">None</span>, value=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Adds a set to the universe&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> name <span class="kw1">is</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.__sets.<span class="me1">append</span><span class="br0">&#40;</span>List<span class="br0">&#40;</span><span class="st0">&quot;S&quot;</span>+<span class="kw2">str</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">setCount</span><span class="br0">&#41;</span>, value<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">setCount</span> += <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.__sets.<span class="me1">add</span><span class="br0">&#40;</span>List<span class="br0">&#40;</span>name, value<span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>U = Universe<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>As you can see, I have a valueNodeDict dictionary in the implementation. The idea is that I should be able to use the values themselves in the operations and not the nodes.</p>
<p>Next, the operations themselves:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">def</span> MakeSet<span class="br0">&#40;</span>x, name=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Makes a new Linked List&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; U.<span class="me1">addSet</span><span class="br0">&#40;</span>name, x<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> FindSet<span class="br0">&#40;</span>x<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Find The Set This Node Belongs To&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> valueNodeDict<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">parent</span></p>
<p><span class="kw1">def</span> Union<span class="br0">&#40;</span>x, y<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Destructively Perform The Union&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> valueNodeDict<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">parent</span> <span class="kw1">is</span> <span class="kw1">not</span> valueNodeDict<span class="br0">&#91;</span>y<span class="br0">&#93;</span>.<span class="me1">parent</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x_set = valueNodeDict<span class="br0">&#91;</span>x<span class="br0">&#93;</span>.<span class="me1">parent</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y_set = valueNodeDict<span class="br0">&#91;</span>y<span class="br0">&#93;</span>.<span class="me1">parent</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> x_set.<span class="me1">count</span> &lt; y_set.<span class="me1">count</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#x gets appended to y</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y_set.<span class="me1">count</span> += x_set.<span class="me1">count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x_set.<span class="me1">changeParent</span><span class="br0">&#40;</span>y_set<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y_set.<span class="me1">tail</span>.<span class="me1">next</span> = x_set.<span class="me1">head</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y_set.<span class="me1">tail</span> = x_set.<span class="me1">tail</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; U.<span class="kw3">sets</span>.<span class="me1">remove</span><span class="br0">&#40;</span>x_set<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#y gets appended to x</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x_set.<span class="me1">count</span> += y_set.<span class="me1">count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y_set.<span class="me1">changeParent</span><span class="br0">&#40;</span>x_set<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x_set.<span class="me1">tail</span>.<span class="me1">next</span> = y_set.<span class="me1">head</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x_set.<span class="me1">tail</span> = y_set.<span class="me1">tail</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; U.<span class="kw3">sets</span>.<span class="me1">remove</span><span class="br0">&#40;</span>y_set<span class="br0">&#41;</span><br />
&nbsp;</div>
<p>Now, the tree implementation:</p>
<div class="dean_ch" style="white-space: nowrap;">valueNodeDict = <span class="br0">&#123;</span><span class="br0">&#125;</span></p>
<p><span class="kw1">class</span> Node<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Represents a node in a tree&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, value, parent, rank<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">value</span> = value<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">parent</span> = parent<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">rank</span> = rank<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; valueNodeDict<span class="br0">&#91;</span>value<span class="br0">&#93;</span> = <span class="kw2">self</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__str__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">str</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span></p>
<p><span class="kw1">class</span> Universe<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;The Universe where all sets sit&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="kw3">sets</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="co1">#list of all root nodes</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> addSet<span class="br0">&#40;</span><span class="kw2">self</span>, root<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="kw3">sets</span>.<span class="me1">append</span><span class="br0">&#40;</span>root<span class="br0">&#41;</span></p>
<p>U = Universe<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>And the operations:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">def</span> internalFindSet<span class="br0">&#40;</span>x<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Find The Root Of The Tree That Contains This Node. Uses path compression&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> x.<span class="me1">parent</span> <span class="kw1">is</span> <span class="kw1">not</span> x:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x.<span class="me1">parent</span> = internalFindSet<span class="br0">&#40;</span>x.<span class="me1">parent</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> x.<span class="me1">parent</span></p>
<p><span class="kw1">def</span> MakeSet<span class="br0">&#40;</span>x<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Make a new node whose parent is itself&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; a = Node<span class="br0">&#40;</span>x, <span class="kw2">None</span>, <span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; a.<span class="me1">parent</span> = a<br />
&nbsp; &nbsp; &nbsp; &nbsp; U.<span class="me1">addSet</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> FindSet<span class="br0">&#40;</span>x<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Returns the root of the tree which contains this value&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; x_node = valueNodeDict<span class="br0">&#91;</span>x<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> internalFindSet<span class="br0">&#40;</span>x_node<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> Union<span class="br0">&#40;</span>x, y<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Destructively Unite X and Y where x belongs to X and y to Y&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; x_set = FindSet<span class="br0">&#40;</span>x<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; y_set = FindSet<span class="br0">&#40;</span>y<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> x_set.<span class="me1">rank</span> &gt; y_set.<span class="me1">rank</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y_set.<span class="me1">parent</span> = x_set<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x_set.<span class="me1">parent</span> = y_set<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> x_set.<span class="me1">rank</span> == y_set.<span class="me1">rank</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y_set.<span class="me1">rank</span> += <span class="nu0">1</span><br />
&nbsp;</div>
<p>As an added exercise, I also threw in Kruskal&#8217;s algorithm for finding the Minimum Spanning Tree of a Graph. Here is my graph implementation which just consists of an edge-list and a vertex-list:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">import</span> <span class="kw3">heapq</span><br />
<span class="kw1">from</span> disjoint_set2 <span class="kw1">import</span> *</p>
<p><span class="kw1">class</span> Vertex:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, value<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">value</span> = value</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__str__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">value</span></p>
<p><span class="kw1">class</span> Edge:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, vertex1, vertex2, weight<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">vertex1</span> = vertex1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">vertex2</span> = vertex2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">weight</span> = weight</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__str__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = <span class="st0">&quot;Connects: &quot;</span> + <span class="kw2">str</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">vertex1</span><span class="br0">&#41;</span> + <span class="st0">&quot; and &quot;</span> + <span class="kw2">str</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">vertex2</span><span class="br0">&#41;</span> + <span class="st0">&quot;<span class="es0">\t</span>Weight: &quot;</span> + <span class="kw2">str</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">weight</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> s</p>
<p><span class="kw1">class</span> Graph:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, V, E<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">V</span> = V<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">E</span> = E<br />
&nbsp;</div>
<p>I decided to create a small graph with nodes: &#8216;a&#8217;, &#8216;b&#8217;, &#8216;c&#8217;, &#8216;d&#8217; and &#8216;e&#8217;. The code to do that:</p>
<div class="dean_ch" style="white-space: nowrap;">characters = <span class="br0">&#91;</span><span class="st0">&#8216;a&#8217;</span>, <span class="st0">&#8216;b&#8217;</span>, <span class="st0">&#8216;c&#8217;</span>, <span class="st0">&#8216;d&#8217;</span>, <span class="st0">&#8216;e&#8217;</span><span class="br0">&#93;</span></p>
<p>vertices = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
edges = <span class="br0">&#91;</span><span class="br0">&#93;</span></p>
<p><span class="kw1">for</span> char <span class="kw1">in</span> characters:<br />
&nbsp; &nbsp; &nbsp; &nbsp; vertices.<span class="me1">append</span><span class="br0">&#40;</span>Vertex<span class="br0">&#40;</span>char<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>Next, I decided to connect every vertex to every other vertex using edges whose weights are in increasing order as follows:</p>
<p>Edge from &#8216;a&#8217; to &#8216;a&#8217; has weight 0</p>
<p>From &#8216;a&#8217; to &#8216;b&#8217; we get 1</p>
<p>From &#8216;a&#8217; to &#8216;c&#8217; we get 2</p>
<p>and so on, you get the idea. The plan was to get a verifiable result straight away.</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">for</span> vertex1 <span class="kw1">in</span> vertices:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> vertex2 <span class="kw1">in</span> vertices:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; edges.<span class="me1">append</span><span class="br0">&#40;</span>Edge<span class="br0">&#40;</span>vertex1, vertex2, i<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i += <span class="nu0">1</span></p>
<p>G = Graph<span class="br0">&#40;</span>vertices, edges<span class="br0">&#41;</span><br />
&nbsp;</div>
<p>Now, we prepare the required data structures for this algorithm. We need a priority queue. Python 2.6.5 ships with a <a href="http://docs.python.org/library/heapq.html">heapq module</a>. Using this module, we can maintain a heap in an array and the desired &#8220;bubble up&#8221; and &#8220;bubble down&#8221; operations are performed by the heapq module&#8217;s routines. As it is known to mankind, the root of any heap contains the element with the smallest key (assuming the heap is storing (key, value) pairs and is a min-heap). So, we finally have:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">def</span> kruskal<span class="br0">&#40;</span>G<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; heap = <span class="br0">&#91;</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> edge <span class="kw1">in</span> G.<span class="me1">E</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">heapq</span>.<span class="me1">heappush</span><span class="br0">&#40;</span>heap, <span class="br0">&#40;</span>edge.<span class="me1">weight</span>, edge<span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; T = <span class="br0">&#91;</span><span class="br0">&#93;</span> &nbsp;<span class="co1">#this contains all the edges in the tree</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># run makeset on all the vertices</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> vertex <span class="kw1">in</span> G.<span class="me1">V</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MakeSet<span class="br0">&#40;</span>vertex<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> heap:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; min_edge = <span class="kw3">heapq</span>.<span class="me1">heappop</span><span class="br0">&#40;</span>heap<span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> FindSet<span class="br0">&#40;</span>min_edge.<span class="me1">vertex1</span><span class="br0">&#41;</span> <span class="kw1">is</span> <span class="kw1">not</span> FindSet<span class="br0">&#40;</span>min_edge.<span class="me1">vertex2</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># perform a union and add this edge to the Tree</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; T.<span class="me1">append</span><span class="br0">&#40;</span>min_edge<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Union<span class="br0">&#40;</span>min_edge.<span class="me1">vertex1</span>, min_edge.<span class="me1">vertex2</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> T<br />
&nbsp;</div>
<p>So, I return a list of edges in the MST. When I run this on the graph created above, I get:</p>
<pre>(shriphani@Shriphani-Palakodetys-MacBook-Pro) (556/ttys000) (09:03P:05/19/10) -
(%:~/scripts) &gt; python kruskal.py
Connects: a and b	Weight: 1
Connects: a and c	Weight: 2
Connects: a and d	Weight: 3
Connects: a and e	Weight: 4
</pre>
<p>Which when checked is the actual MST.</p>
<p><span style="text-decoration: underline;"><strong>Analysis</strong></span></p>
<p>Assume that we have n makeset operations out of m overall operations, with the special heuristic we use, anytime a list is chosen for appending to another list, we observe that this list has to have fewer elements than the other list.</p>
<p>So, this is the pattern we have:</p>
<ul>
<li>If there is one element in the list and this list is chosen for appending to the other list, then the resulting size would be at least 2</li>
<li>If the current size is 2 and we append this list to another list, the resulting size will be at least 4</li>
<li>Once we append a list of size 4 to another list, the resulting list would have a size of 8.</li>
</ul>
<p>So, we observe that in 3 append operations, we approached a size of 8. So, in lg(8) operations, we approached size 8. So, we would approach size &#8216;n&#8217; (the kruskal() routine obtains the MST on a connected graph at this stage) in lg(n) operations.</p>
<p>Also, there need to be n-1 union operations since the Universe finally contains just 1 set with all vertices in it (assuming you have a connected graph). There need to be n-1 union operations for the universe to approach this state. So, a final running time is O(n * lg(n)) for this.</p>
<p>Now, if the graph is pretty sparse, as in 5 vertices and a single edge in the entire graph, the other operations would dominate. So, the actual running time is</p>
<p>O(m + n*lg(n))</p>
<p>With the tree based structure, our course didn&#8217;t cover the analysis but we were told that the running time was a cool O(m * alpha(n)) where alpha(n) &lt;= 4 for  most circumstances.</p>
<p>The code can be obtained at:</p>
<ul>
<li><a href="http://shriphani.com/scripts/disjoint_set1.py" target="_blank">Linked List Based Implementation</a></li>
<li><a href="http://shriphani.com/scripts/disjoint_set2.py" target="_blank">Tree Based Implementation</a></li>
<li><a href="http://shriphani.com/scripts/kruskal.py" target="_blank">Kruskal Implementation</a></li>
</ul>
<p>In this post I used material from Cormen-Leiserson-Rivest-Stein&#8217;s amazing book (It is the best book I&#8217;ve ever read. Please go get a copy. You won&#8217;t regret it). And of course, stuff from Professor GNF&#8217;s CS 381 class. It is the best CS course I&#8217;ve taken thus far.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2010/05/20/disjoint-set-data-structure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Listener Gets a VAD</title>
		<link>http://shriphani.com/blog/2010/01/21/listener-gets-a-vad/</link>
		<comments>http://shriphani.com/blog/2010/01/21/listener-gets-a-vad/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 01:15:23 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=419</guid>
		<description><![CDATA[So, the beginning of the 4th semester in the midst of losers and overachievers and this sem promises to set my a$$ on fire. As usual, I plan to continue working under Dr. Kihara this sem so that should be interesting. Anyway, I decided to improve upon what listener offered and decided to add a [...]]]></description>
			<content:encoded><![CDATA[<p>So, the beginning of the 4th semester in the midst of losers and overachievers and this sem promises to set my a$$ on fire. As usual, I plan to continue working under Dr. Kihara this sem so that should be interesting. Anyway, I decided to improve upon what listener offered and decided to add a VAD algorithm to it. I initially chose the algorithm by moattar and homayounpur and decided that I ended up with too much to do (it might certainly be a good candidate for later, when I have more time for example). Hence, I decided to snoop around for something simpler and found this paper which seemed small and had a sort of ever changing threshold for successive frames. The paper was authored by S.Milanovic, Z. Lukac and A. Domazetovic. I still don&#8217;t think I got it exactly right though. The paper mentioned that they used counters to mark frames as silence based on what the previous frame was and I had to come with a counter upper bound for myself and finally chose to go with 10 as a good counter for such stuff. i.e. even if a particular frame doesn&#8217;t make it beyond its threshold, it still will be marked as active if the previous frame was active. This is done to accommodate situations where we end up reducing our volume at the end of a word / sentence.</p>
<p>Finally to decide whether there was speech on an overall level, I look for at least 3 instances of 18 consecutive frames being marked as active (just random picks, 18 frames allows 8 active frames and 10 additional for the counter we have and 3 looked like a good candidate at the end when I spoke my own name out).</p>
<p>And as a final measure, I also ensure that the overall intensity beats 48 dB so that someone trying to have a conversation with me is only recognized.</p>
<p>Finally, I made the switch from GeekTool to Growl as this thing kept taking a solid amount of real estate and since I have one 23&#8221; monitor and a 15&#8221; monitor, this thing is positioned outside the real estate of my laptop&#8217;s display. Growl seems like a better candidate overall and since I could get growl bindings to build on my machine finally, I think I should let growl handle this.</p>
<p>So, the only places where my VAD implementation (or my mod of whatever was in that paper) doesn&#8217;t seem to work is in surroundings with a piano (in our dorm&#8217;s lobby for example), v inconvenient but whatever, probably some time in the future, I will begin understanding DSP and spectral analysis well enough to come up with a simple VAD algorithm (as opposed to implementing something straight from a paper without any understanding of what is going on). Anyway, here is the updated script, it seems to do well recognizing speech in sort of silent settings:</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="co1">#!/usr/bin/env python</span><br />
<span class="co1">#Author: Shriphani Palakodety</span><br />
<span class="co1">#Tool to aid those with noise cancellation headphones</span></p>
<p><span class="kw1">import</span> pyaudio<br />
<span class="kw1">import</span> <span class="kw3">wave</span><br />
<span class="kw1">import</span> <span class="kw3">sys</span><br />
<span class="kw1">import</span> <span class="kw3">struct</span><br />
<span class="kw1">import</span> numpy<br />
<span class="kw1">import</span> <span class="kw3">time</span></p>
<p>Growl_exists = <span class="kw2">True</span></p>
<p><span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">import</span> Growl<br />
<span class="kw1">except</span> <span class="kw2">ImportError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;No Growl&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Growl_exists = <span class="kw2">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pass</span></p>
<p>skype_on_call = <span class="kw2">False</span><br />
notifier = <span class="nu0">0</span><br />
<span class="kw1">if</span> Growl_exists:<br />
&nbsp; &nbsp; &nbsp; &nbsp; notifier = Growl.<span class="me1">GrowlNotifier</span><span class="br0">&#40;</span><span class="st0">&#8216;Listener&#8217;</span>, &nbsp;<span class="br0">&#91;</span><span class="st0">&#8216;Attention&#8217;</span>, <span class="st0">&#8216;test&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#notifier.applicationName = &#8216;Listener&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; notifier.<span class="me1">register</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> record<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Records Input From Microphone Using PyAudio&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; duration = <span class="nu0">3</span> <span class="co1">#record for 1 second. Pretty long duration don&#8217;t you think</span><br />
&nbsp; &nbsp; outfile = <span class="st0">&quot;analysis.wav&quot;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; p = pyaudio.<span class="me1">PyAudio</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; inStream = p.<span class="kw2">open</span><span class="br0">&#40;</span>format=pyaudio.<span class="me1">paInt16</span>, channels=<span class="nu0">1</span>, rate=<span class="nu0">44100</span>,<span class="kw2">input</span>=<span class="kw2">True</span>, frames_per_buffer=<span class="nu0">1024</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; out = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; upper_lim = <span class="nu0">44100</span> / <span class="nu0">1024</span> * duration <span class="co1">#upper limit of the range we record to. 44100 / 1024 sized chunk * 5 seconds</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="nu0">0</span>, upper_lim<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; data = inStream.<span class="me1">read</span><span class="br0">&#40;</span><span class="nu0">1024</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; out.<span class="me1">append</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">#now the writing section where we write to file</span><br />
&nbsp; &nbsp; data = <span class="st0">&#8221;</span>.<span class="me1">join</span><span class="br0">&#40;</span>out<span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile = <span class="kw3">wave</span>.<span class="kw2">open</span><span class="br0">&#40;</span>outfile, <span class="st0">&quot;wb&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">setnchannels</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">setsampwidth</span><span class="br0">&#40;</span>p.<span class="me1">get_sample_size</span><span class="br0">&#40;</span>pyaudio.<span class="me1">paInt16</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">setframerate</span><span class="br0">&#40;</span><span class="nu0">44100</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">writeframes</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; analyze<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>
<span class="kw1">def</span> analyze<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">if</span> skype_on_call:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Skype Call In Progress&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Listener On Hold&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
&nbsp; &nbsp; inFile = <span class="kw3">wave</span>.<span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;analysis.wav&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span> <span class="co1">#open a wav file in read mode</span><br />
&nbsp; &nbsp; thresh = <span class="nu0">1000</span> &nbsp;<span class="co1">#establish a minimum threshold</span><br />
&nbsp; &nbsp; max_samp = <span class="nu0">0</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; decision = <span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; <span class="co1">#for i in xrange(441):</span></p>
<p>&nbsp; &nbsp; inactive_counter = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; vals = inFile.<span class="me1">readframes</span><span class="br0">&#40;</span>inFile.<span class="me1">getnframes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="co1">#read in 30 samples</span><br />
&nbsp; &nbsp; <span class="kw2">len</span><span class="br0">&#40;</span>vals<span class="br0">&#41;</span><br />
&nbsp; &nbsp; results = <span class="kw3">struct</span>.<span class="me1">unpack</span><span class="br0">&#40;</span><span class="st0">&quot;%dh&quot;</span>%<span class="br0">&#40;</span>inFile.<span class="me1">getnframes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, vals<span class="br0">&#41;</span> &nbsp;<span class="co1">#unpack to get the samples</span><br />
&nbsp; &nbsp; results = <span class="br0">&#91;</span><span class="kw2">abs</span><span class="br0">&#40;</span>x<span class="br0">&#41;</span> <span class="kw1">for</span> x <span class="kw1">in</span> results<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">#now we need to pull 30 samples at a time (30 samples = 1 frame).</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="nu0">4404</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; frame = results<span class="br0">&#91;</span><span class="nu0">30</span>*i: <span class="nu0">30</span>*<span class="br0">&#40;</span>i<span class="nu0">+1</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> frame<br />
&nbsp; &nbsp; &nbsp; &nbsp; new_thresh = <span class="br0">&#40;</span>thresh * <span class="br0">&#40;</span><span class="nu0">1</span> &#8211; <span class="br0">&#40;</span><span class="nu0">2.0</span> ** <span class="nu0">-7</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &nbsp;+ &nbsp;<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="nu0">2</span> ** <span class="nu0">-8</span><span class="br0">&#41;</span> * max_samp<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#check how many samples go above this new threshold</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; count = <span class="nu0">0</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> j <span class="kw1">in</span> frame:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> j &gt; new_thresh:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count += <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> count / <span class="nu0">30.0</span> &gt;= <span class="nu0">0.9</span> : &nbsp; <span class="co1">#need it to beat 90%</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#frame is a candidate for speech</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; decision.<span class="me1">append</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#this is where we use a counter based implementation for labelling inactiveness</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> inactive_counter &lt; <span class="nu0">10</span> <span class="kw1">and</span> decision<span class="br0">&#91;</span><span class="nu0">-1</span><span class="br0">&#93;</span> == <span class="nu0">1</span>: <span class="co1">#we ignore silence for 10 runs</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; decision.<span class="me1">append</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inactive_counter += <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inactive_counter = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; decision.<span class="me1">append</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#update the threshold and the max sample values</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; thresh = new_thresh<br />
&nbsp; &nbsp; &nbsp; &nbsp; max_samp = <span class="kw2">max</span><span class="br0">&#40;</span>frame<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1">#final check for characterization as speech, we use another counter</span><br />
&nbsp; &nbsp; active_counter = <span class="nu0">0</span> <span class="co1">#since the inactive counter will cause silence to be recognized as speech, we only consider speech as </span><br />
&nbsp; &nbsp; <span class="kw1">print</span> decision<br />
&nbsp; &nbsp; final_num = <span class="nu0">0</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> val <span class="kw1">in</span> decision:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> active_counter &gt;= <span class="nu0">18</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Speech!&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final_num += <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; active_counter = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> val == <span class="nu0">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; active_counter += <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; active_counter = <span class="nu0">0</span></p>
<p>&nbsp; &nbsp; results = <span class="br0">&#91;</span>x ** <span class="nu0">2</span> <span class="kw1">for</span> x <span class="kw1">in</span> results<span class="br0">&#93;</span><br />
&nbsp; &nbsp; intensity = <span class="nu0">20</span> * numpy.<span class="me1">log10</span><span class="br0">&#40;</span>numpy.<span class="me1">sqrt</span><span class="br0">&#40;</span><span class="kw2">sum</span><span class="br0">&#40;</span>results<span class="br0">&#41;</span>/inFile.<span class="me1">getnframes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">if</span> final_num &gt;= <span class="nu0">3</span> <span class="kw1">and</span> intensity &gt; <span class="nu0">48</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> Growl_exists:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifier.<span class="me1">notify</span><span class="br0">&#40;</span><span class="st0">&#8216;Attention&#8217;</span>,<span class="st0">&#8216;Listener&#8217;</span>, <span class="st0">&#8216;Speech Detected Nearby&#8217;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Speech Detected Nearby!<span class="es0">\n</span>Someone might be calling you&quot;</span><br />
&nbsp; &nbsp; inFile.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; f = <span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;skype_Status&quot;</span>, <span class="st0">&quot;r&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> new_line <span class="kw1">in</span> f:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> new_line == <span class="st0">&quot;PROGRESS&quot;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; skype_on_call = <span class="kw2">True</span></p>
<p>&nbsp; &nbsp; <span class="kw1">if</span> skype_on_call:<br />
&nbsp; &nbsp; &nbsp; &nbsp; analyze<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; record<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p> Anyway, it would be really convenient if I could find something about VAD algorithms and improve listener to work better for my dorm room settings. It is doing a pretty good job already but there is always scope for improvement.</p>
<p>As always, my solutions need to be convoluted and over here, I make use of applescript to check if there&#8217;s a skype call going on or not, so yeah, you can find all that <a href="http://shriphani.com/scripts/listener">here</a>.</p>
<p>Screenshots etc available on Listener&#8217;s new home: <a href="http://shriphani.com/blog/listener/">http://shriphani.com/blog/listener/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2010/01/21/listener-gets-a-vad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The One PITA</title>
		<link>http://shriphani.com/blog/2009/11/29/the-one-pita/</link>
		<comments>http://shriphani.com/blog/2009/11/29/the-one-pita/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 05:22:15 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[Daily life]]></category>
		<category><![CDATA[PITA]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=414</guid>
		<description><![CDATA[Well, it is thanksgiving break and I was so far having a decent semester, straight As in all exams (a perfect score in economics &#8211; not that I should be proud of it or anythin) and then terror strikes. Or well whatever the college version of a cataclysm is. I managed to f&#8217;kin ruin (misunderstand) [...]]]></description>
			<content:encoded><![CDATA[<p>Well, it is thanksgiving break and I was so far having a decent semester, straight As in all exams (a perfect score in economics &#8211; not that I should be proud of it or anythin) and then terror strikes. Or well whatever the college version of a cataclysm is. I managed to f&#8217;kin ruin (misunderstand) the spec on a project and I am in danger of throwing away a coveted 4.0 GPA which would have been a great reward for the long hours of study I have put in + a retooling of my schedule so I have the multitasking capability of a mule and those $$ my parents spend so their son can enjoy a pain free life in a first world country and try to make them proud. Well, as it happens, I managed to (or at least I think &#8211; the scores are not yet out) misunderstand a spec AAAAARRRGGHH! In a datastructures course, I mastered AVL &amp; Red-Black trees, spent hours trying to tweak my implementations, did well on the exam and managed to blow it when it came to reading a text file and filling an array. I just wonder how I even pull this stuff off. With Grad School apps coming in 2 years, what will I have to show  &#8211;  a carelessness in even reading specs seriously that puts doubts on the efficacy of my research methodology, I just hope I don&#8217;t cause major problems for myself.</p>
<p>Well, in case this doesn&#8217;t make sense, I managed to misunderstand a technique to populate an array with data (the data structs would work with this but oh no, in my interest to take the maximum from this course, I devoted long hours to getting the data structs right). There is a very good chance that the part I screwed up would end up being insignificant but that is not the point. The point is that once again my grade is going to shuttle between the first two letters of the english alphabet.</p>
<p>Anyway, in all this self hatred that I have been building up for myself, I have managed to learn some cool stuff in Dr. Kihara&#8217;s lab. The work there is pleasant, I can feel good boasting about it and when I talk to my friends&#8217; parents, I can make them believe I am going to find a solution to poverty in 4 years and find a cure for cancer in my spare time (you can see I am not popular).</p>
<p>However, a weird question I was dealing with was that most of the stuff I have written for my work is in Python and it would be cool if I could call it from Java since there are a bunch of people in the lab who use it. I am not looking for something complicated, just want to call a bunch of methods from a Python module. JPype and Jython seem to the things I should be looking for but with my awesome constraints (Python 2.6 should be supported, It should make coffee etc), I will need to use my Uber-GOOGLE-SKILLZ.</p>
<p>Anyway, this blog has managed to get to pagerank 0 (I will interpret that as the pagerank o loner being relevant ) and I am now a suggestion on Google (yay! my plan for world domination is in full swing!)</p>
<p>And I love this Charlie dude who bites his bro&#8217;s finger, as for kanye, well even the prez thinks he&#8217;s a jackass:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/FMbVPMzSqYY&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/FMbVPMzSqYY&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2009/11/29/the-one-pita/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tinkering With A New Project</title>
		<link>http://shriphani.com/blog/2009/09/18/tinkering-with-a-new-project/</link>
		<comments>http://shriphani.com/blog/2009/09/18/tinkering-with-a-new-project/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 16:46:57 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=401</guid>
		<description><![CDATA[During the vacation this summer, I began working on creating an app that would help me respond to calls of attention when my auditory sensory capabilities were compromised courtesy the noise cancellation capabilities of my Bose headsets. Well, I managed to make a few mods to that script, used a touch of applescript (thank god [...]]]></description>
			<content:encoded><![CDATA[<p>During the vacation this summer, I began working on creating an app that would help me respond to calls of attention when my auditory sensory capabilities were compromised courtesy the noise cancellation capabilities of my Bose headsets. Well, I managed to make a few mods to that script, used a touch of applescript (thank god OS X apps are scriptable) and introduced a bunch of new behaviors:</p>
<p>-&gt; When a Skype call is in progress, the app stops listening.</p>
<p>Ok, not a bunch, just one. Also, this is not exactly an app you should be using since it relies too much on quirks in my own computing environment. Anyway, for more details you can head over to <a href="http://shriphani.com/Shriphani_Website/Listener.html" target="_blank">http://shriphani.com/Shriphani_Website/Listener.html</a>.</p>
<p>So, a few screenshots:</p>

<a href='http://shriphani.com/blog/2009/09/18/tinkering-with-a-new-project/screen-shot-2009-09-18-at-12-41-10-pm/' title='Screen shot 2009-09-18 at 12.41.10 PM'><img width="150" height="150" src="http://shriphani.com/blog/wp-content/uploads/2009/09/Screen-shot-2009-09-18-at-12.41.10-PM-150x150.png" class="attachment-thumbnail" alt="Screen shot 2009-09-18 at 12.41.10 PM" title="Screen shot 2009-09-18 at 12.41.10 PM" /></a>
<a href='http://shriphani.com/blog/2009/09/18/tinkering-with-a-new-project/screen-shot-2009-09-18-at-12-42-39-pm/' title='Screen shot 2009-09-18 at 12.42.39 PM'><img width="150" height="150" src="http://shriphani.com/blog/wp-content/uploads/2009/09/Screen-shot-2009-09-18-at-12.42.39-PM-150x150.png" class="attachment-thumbnail" alt="Screen shot 2009-09-18 at 12.42.39 PM" title="Screen shot 2009-09-18 at 12.42.39 PM" /></a>
<a href='http://shriphani.com/blog/2009/09/18/tinkering-with-a-new-project/screen-shot-2009-09-18-at-12-43-40-pm/' title='Screen shot 2009-09-18 at 12.43.40 PM'><img width="150" height="150" src="http://shriphani.com/blog/wp-content/uploads/2009/09/Screen-shot-2009-09-18-at-12.43.40-PM-150x150.png" class="attachment-thumbnail" alt="Screen shot 2009-09-18 at 12.43.40 PM" title="Screen shot 2009-09-18 at 12.43.40 PM" /></a>

<p>Apart from that, I also wrote a protein function matching script as part of my research this semester. I will be putting it up soon. Wow, I have been more productive in these three weeks than all of last year.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2009/09/18/tinkering-with-a-new-project/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Bio-Informatics</title>
		<link>http://shriphani.com/blog/2009/09/04/bio-informatics/</link>
		<comments>http://shriphani.com/blog/2009/09/04/bio-informatics/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 17:20:22 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=377</guid>
		<description><![CDATA[It has been an amazing first week at college here. First, I began working with Prof Kihara and got to see a whopping 160 thousand (!) annotations. The coolest part is that I got to see a few protein function prediction algorithms (I get to code! Yippee!). Well, at one point I had to whip [...]]]></description>
			<content:encoded><![CDATA[<p>It has been an amazing first week at college here. First, I began working with Prof Kihara and got to see a whopping 160 thousand (!) annotations. The coolest part is that I got to see a few protein function prediction algorithms (I get to code! Yippee!). Well, at one point I had to whip up my own factorial function (since I can&#8217;t use Python2.6 which has a math.factorial courtesy lab machines). Well, I modded a bit of the code I found at http://en.literateprograms.org/Factorials_with_prime_factorization_%28Python%29 (which helped me a lot, thanks). And then I mixed it up with <a href="http://shriphani.com/blog/2008/04/09/prime-numbers-miller-rabin/" target="_blank">my miller rabin implementation</a> and had a bit of fun :D.</p>
<p>So the slightly modded version of the factorial script should look like <a href="http://shriphani.com/scripts/factorial.py" target="_blank">this</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2009/09/04/bio-informatics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First DSP Attempts</title>
		<link>http://shriphani.com/blog/2009/06/26/first-dsp-attempts/</link>
		<comments>http://shriphani.com/blog/2009/06/26/first-dsp-attempts/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 13:51:02 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=349</guid>
		<description><![CDATA[Well, since my last post on detecting calls of attention using my microphone, I have been paying attention to DSP since it seems to be one cool topic to spend 3 months on. So, I decided to begin reading the dspguide and found some cool stuff which I decided to tinker with. After reading about [...]]]></description>
			<content:encoded><![CDATA[<p>Well, since my last post on detecting calls of attention using my microphone, I have been paying attention to DSP since it seems to be one cool topic to spend 3 months on. So, I decided to begin reading the <a href="http://www.dspguide.com/">dspguide</a> and found some cool stuff which I decided to tinker with. After reading about convolution, I decided to implement some basic filters that would help me amplify, add echoes and so on. First, implementations of convolution, the input side algorithm and the output side algorithm:</p>
<p><strong>The input side algorithm:</strong></p>
<p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> convolute_inside<span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">global</span> output_signal<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">global</span> input_signal<br />
&nbsp; &nbsp; &nbsp; &nbsp; len_out_signal = <span class="kw2">len</span><span class="br0">&#40;</span>input_signal<span class="br0">&#41;</span>+<span class="kw2">len</span><span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span><span class="nu0">-1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; output_signal = <span class="br0">&#91;</span><span class="nu0">0</span> <span class="kw1">for</span> x <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span>len_out_signal<span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>input_signal<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> j <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output_signal<span class="br0">&#91;</span>i+j<span class="br0">&#93;</span> = output_signal<span class="br0">&#91;</span>i+j<span class="br0">&#93;</span> + input_signal<span class="br0">&#91;</span>i<span class="br0">&#93;</span>*impulse_response<span class="br0">&#91;</span>j<span class="br0">&#93;</span><br />
&nbsp;</div>
</p>
<p><strong>The output side algorithm:</strong></p>
<p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> convolute_outside<span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">global</span> output_signal<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">global</span> input_signal<br />
&nbsp; &nbsp; &nbsp; &nbsp; len_out_signal = <span class="kw2">len</span><span class="br0">&#40;</span>input_signal<span class="br0">&#41;</span>+<span class="kw2">len</span><span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span><span class="nu0">-1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span>len_out_signal<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output_signal.<span class="me1">append</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span>len_out_signal<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> j <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#print i, j</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="br0">&#40;</span>i-j<span class="br0">&#41;</span>&lt;<span class="nu0">0</span> <span class="kw1">and</span> <span class="kw1">not</span> <span class="br0">&#40;</span>i-j<span class="br0">&#41;</span>&gt;len<span class="br0">&#40;</span>input_signal<span class="br0">&#41;</span><span class="nu0">-1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output_signal<span class="br0">&#91;</span>i<span class="br0">&#93;</span> += impulse_response<span class="br0">&#91;</span>j<span class="br0">&#93;</span> * input_signal<span class="br0">&#91;</span>i-j<span class="br0">&#93;</span></p>
<p>&nbsp;</p></div>
</p>
<p>Next, using appropriate filters, we can add echoes and amplify the input signal. So, we first need to read in a wav file. Using my previous script, that should be simple:<br />
<strong>Reading a wav file:</strong></p>
<p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> readWavFile<span class="br0">&#40;</span><span class="kw2">input</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; inFile = <span class="kw3">wave</span>.<span class="kw2">open</span><span class="br0">&#40;</span><span class="kw2">input</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; sample_rate = inFile.<span class="me1">getframerate</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; total_samples = inFile.<span class="me1">getnframes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; vals = inFile.<span class="me1">readframes</span><span class="br0">&#40;</span>total_samples<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; inFile.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">struct</span>.<span class="me1">unpack</span><span class="br0">&#40;</span><span class="st0">&quot;%dh&quot;</span>%<span class="br0">&#40;</span>total_samples<span class="br0">&#41;</span>, vals<span class="br0">&#41;</span><br />
&nbsp;</div>
</p>
<p>This next function adds an echo to the input signal:<br />
<strong>Add an echo:</strong></p>
<p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> add_echo<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Amounts to scaling and shifting the delta function and then adding it to a delta function&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#considering the intensity of the echo to be 60% of that of the original signal and delayed by 1000 samples:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; impulse_response = <span class="br0">&#91;</span><span class="nu0">0</span> <span class="kw1">for</span> x <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="nu0">1003</span><span class="br0">&#41;</span><span class="br0">&#93;</span> <span class="co1">#shifted and scaled delta function + delta function</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; impulse_response<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> = <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; impulse_response<span class="br0">&#91;</span><span class="nu0">-1</span><span class="br0">&#93;</span> = <span class="nu0">0.6</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; convolute_inside<span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span></p>
<p>&nbsp;</p></div>
</p>
<p>The above function considers that an echo occurs a 1000 samples after the current one and with an intensity 6 tenths of the original signal. Since testing this becomes a serious pain, I decided to test my echo function using a different input signal and impulse response (echo is 6/10 of the original intensity and 4 samples away). </p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> add_new_echo<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Amounts to scaling and shifting the delta function and then adding it to a delta function&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#considering the intensity of the echo to be 60% of that of the original signal and delayed by 4 samples:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; impulse_response = <span class="br0">&#91;</span><span class="nu0">1</span>,<span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0.6</span><span class="br0">&#93;</span> <span class="co1">#shifted and scaled delta function + delta function</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; convolute_inside<span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span></p>
<p>input_signal = <span class="br0">&#91;</span><span class="nu0">1</span>,<span class="nu0">2</span>,<span class="nu0">3</span>,<span class="nu0">4</span><span class="br0">&#93;</span><br />
<span class="co1">#print input_signal</span><br />
add_new_echo<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">print</span> output_signal<br />
&nbsp;</div>
<p>The output of this is:</p>
<pre>
mouse-den% python convolution.py
[1, 2, 3, 4, 0.59999999999999998, 1.2, 1.7999999999999998, 2.3999999999999999]
</pre>
<p>The impulse response for amplifying a signal would be a scaled delta function, so:</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> amplify<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Make the impulse function a scaled delta function&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; impulse_response = <span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; convolute_inside<span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span><br />
&nbsp;</div>
<p>The code to write to a wave file should be pretty straightforward:</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> writeWavFile<span class="br0">&#40;</span>out<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; outStream = <span class="kw3">wave</span>.<span class="kw2">open</span><span class="br0">&#40;</span>out, <span class="st0">&quot;wb&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outStream.<span class="me1">setnchannels</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outStream.<span class="me1">setsampwidth</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outStream.<span class="me1">setframerate</span><span class="br0">&#40;</span><span class="nu0">44100</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; data = <span class="st0">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>output_signal<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data += <span class="kw3">struct</span>.<span class="me1">pack</span><span class="br0">&#40;</span><span class="st0">&#8216;h&#8217;</span>, output_signal<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outStream.<span class="me1">writeframes</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; outStream.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>So, here is the test wave file: <a href='http://shriphani.com/blog/wp-content/uploads/2009/06/test.wav'>test.wav</a></p>
<p>And the amplified wav file: <a href='http://shriphani.com/blog/wp-content/uploads/2009/06/output1.wav'>output1.wav</a></p>
<p>Now, to the part where we try to figure out if a signal contains another signal.</p>
<p>Turns out, to do that, you just need to obtain the cross-correlation of the input signal and the waveform we already have.</p>
<p>So, the code to do this for a signal that goes like [1,2,3,4] is:</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> cross_correlate<span class="br0">&#40;</span>input_file=<span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Cross correlate, obtain the graph and find the peak&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">global</span> input_signal<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">global</span> output_signal<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#input_signal = record() #this procedure reads in the signal we need to find</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; input_signal = <span class="br0">&#91;</span><span class="nu0">1</span>,<span class="nu0">2</span>,<span class="nu0">3</span>,<span class="nu0">4</span>,<span class="nu0">11</span>,<span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">1</span>,<span class="nu0">10</span>,<span class="nu0">5</span>,<span class="nu0">2</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; impulse_response = <span class="br0">&#91;</span><span class="nu0">1</span>,<span class="nu0">2</span>,<span class="nu0">3</span>,<span class="nu0">4</span><span class="br0">&#93;</span> <span class="co1">#read in our signal</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; impulse_response.<span class="me1">reverse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; convolute_outside<span class="br0">&#40;</span>impulse_response<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> output_signal<br />
&nbsp;</div>
<p>This results in a signal that looks like:</p>
<pre>[4, 11, 20, 30, 64, 44, 26, 15, 43, 52, 44, 26, 9, 2]</pre>
<p>So, I had to figure out an algorithm to detect the peak and I found one on stackoverflow.com and it goes like this:</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>output_signal<span class="br0">&#41;</span><span class="nu0">-1</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; travel = output_signal<span class="br0">&#91;</span>i<span class="nu0">+1</span><span class="br0">&#93;</span> &#8211; output_signal<span class="br0">&#91;</span>i<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rise = output_signal<span class="br0">&#91;</span><span class="kw2">len</span><span class="br0">&#40;</span>output_signal<span class="br0">&#41;</span><span class="nu0">-1</span><span class="br0">&#93;</span> &#8211; output_signal<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>travel/rise<span class="br0">&#41;</span> &gt; <span class="nu0">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#print output_signal[i]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; peak_options<span class="br0">&#91;</span>output_signal<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#93;</span>=i</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> peak_options<span class="br0">&#91;</span><span class="kw2">max</span><span class="br0">&#40;</span>peak_options.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>&nbsp; &nbsp;<br />
&nbsp;</div>
<p>In other news, I am going to work in Prof. Kihara&#8217;s bio-informatics laboratory this fall and I hope it works out.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2009/06/26/first-dsp-attempts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
<enclosure url="http://shriphani.com/blog/wp-content/uploads/2009/06/test.wav" length="117292" type="audio/x-wav" />
<enclosure url="http://shriphani.com/blog/wp-content/uploads/2009/06/output1.wav" length="117292" type="audio/x-wav" />
		</item>
		<item>
		<title>WAV Files, Spring Semester, Research Hopes, IPL,</title>
		<link>http://shriphani.com/blog/2009/05/26/wav-files-spring-semester-research-hopes-ip/</link>
		<comments>http://shriphani.com/blog/2009/05/26/wav-files-spring-semester-research-hopes-ip/#comments</comments>
		<pubDate>Tue, 26 May 2009 04:21:47 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=338</guid>
		<description><![CDATA[UPDATE 02/13/2010: Most recent version of this script is now moved to: http://shriphani.com/blog/listener. EDIT: An updated version of this script along with tools to improve the user experience can be obtained at http://shriphani.com/Shriphani_Website/Listener.html After an looooong time, I&#8217;ve decided to put finger on keyboard (I think that sounds stupid). Considering that I now use BOSE [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE 02/13/2010: </strong>Most recent version of this script is now moved to: <a href="http://shriphani.com/blog/listener">http://shriphani.com/blog/listener</a>.</p>
<p><strong>EDIT: </strong>An updated version of this script along with tools to improve the user experience can be obtained at <a href="http://shriphani.com/Shriphani_Website/Listener.html">http://shriphani.com/Shriphani_Website/Listener.html</a></p>
<p>After an looooong time, I&#8217;ve decided to put finger on keyboard (I think that sounds stupid). Considering that I now use BOSE headphones which cut me off from the outside world when I am listening to anything (I use the triport headphones; not the Quietcomfort), it has been a bit hard to respond to all the calls for attention over here (no one usually wants me to pay attention and that&#8217;s how it works best). So I decided that it would be better if I could use the mic on my mac to check if someone was calling me. This is the first time I have tinkered with .wav files and I am sure that I am doing loads of things wrong. First, I decided to use PyAudio, PortAudio&#8217;s Python bindings, to record audio from the microphone, save it to a wav file and then open it and analyze etc. So with help from the Examples that come bundled with PyAudio, here is the code to record from the inbuilt microphone:</p>
<p><strong>Recording:</strong></p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">def</span> record<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;Records Input From Microphone Using PyAudio&#8217;</span><span class="st0">&#8221;</span><br />
&nbsp; &nbsp; duration = <span class="nu0">1</span> <span class="co1">#record for 1 second. Pretty long duration don&#8217;t you think</span><br />
&nbsp; &nbsp; outfile = <span class="st0">&quot;analysis.wav&quot;</span></p>
<p>&nbsp; &nbsp; p = pyaudio.<span class="me1">PyAudio</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; inStream = p.<span class="kw2">open</span><span class="br0">&#40;</span>format=pyaudio.<span class="me1">paInt16</span>, channels=<span class="nu0">1</span>, rate=<span class="nu0">44100</span>,<span class="kw2">input</span>=<span class="kw2">True</span>, frames_per_buffer=<span class="nu0">1024</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;recording has begun&quot;</span><br />
&nbsp; &nbsp; out = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; upper_lim = <span class="nu0">44100</span> / <span class="nu0">1024</span> * duration <span class="co1">#upper limit of the range we record to. 44100 / 1024 sized chunk * 5 seconds</span></p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="nu0">0</span>, upper_lim<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; data = inStream.<span class="me1">read</span><span class="br0">&#40;</span><span class="nu0">1024</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; out.<span class="me1">append</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1">#now the writing section where we write to file</span></p>
<p>&nbsp; &nbsp; data = <span class="st0">&#8221;</span>.<span class="me1">join</span><span class="br0">&#40;</span>out<span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile = <span class="kw3">wave</span>.<span class="kw2">open</span><span class="br0">&#40;</span>outfile, <span class="st0">&quot;wb&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">setnchannels</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">setsampwidth</span><span class="br0">&#40;</span>p.<span class="me1">get_sample_size</span><span class="br0">&#40;</span>pyaudio.<span class="me1">paInt16</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">setframerate</span><span class="br0">&#40;</span><span class="nu0">44100</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">writeframes</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><br />
&nbsp; &nbsp; outFile.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>Then, I opened the wav file and read the first 2000 values from it and obtained the root mean square amplitude and then obtained the intensity of sound using the following snippet:</p>
<p><strong>Analyzing</strong></p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">def</span> analyze<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; inFile = <span class="kw3">wave</span>.<span class="kw2">open</span><span class="br0">&#40;</span><span class="st0">&quot;analysis.wav&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span> <span class="co1">#open a wav file in read mode</span><br />
&nbsp; &nbsp; sample_rate = inFile.<span class="me1">getframerate</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; total_samples = inFile.<span class="me1">getnframes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; fftLength = <span class="nu0">128</span><br />
&nbsp; &nbsp; fft_num = <span class="br0">&#40;</span>total_samples/fftLength<span class="br0">&#41;</span> <span class="nu0">-2</span><br />
&nbsp; &nbsp; vals = inFile.<span class="me1">readframes</span><span class="br0">&#40;</span><span class="nu0">2000</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; results = <span class="kw3">struct</span>.<span class="me1">unpack</span><span class="br0">&#40;</span><span class="st0">&quot;%dh&quot;</span>%<span class="br0">&#40;</span><span class="nu0">2000</span><span class="br0">&#41;</span>, vals<span class="br0">&#41;</span><br />
&nbsp; &nbsp; results = <span class="br0">&#91;</span>x**<span class="nu0">2</span> <span class="kw1">for</span> x <span class="kw1">in</span> results<span class="br0">&#93;</span><br />
&nbsp; &nbsp; intensity = <span class="nu0">20</span> * numpy.<span class="me1">log10</span><span class="br0">&#40;</span>numpy.<span class="me1">sqrt</span><span class="br0">&#40;</span><span class="kw2">sum</span><span class="br0">&#40;</span>results<span class="br0">&#41;</span>/<span class="nu0">2000</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>intensity &gt; <span class="nu0">55</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Someone might be calling you&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; curtime = <span class="kw3">time</span>.<span class="me1">localtime</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Current Time: %d:%d:%d&quot;</span>%<span class="br0">&#40;</span>curtime<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span>, curtime<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span>, curtime<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Intensity: &quot;</span>+<span class="kw2">str</span><span class="br0">&#40;</span>intensity<span class="br0">&#41;</span> + <span class="st0">&quot; dB<span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; inFile.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
<p>I chose 55 dB because well 55 dB seems to be the right intensity of sound you would hear if you were conversing with someone 1 meter away.</p>
<p>The next thing to do would be to repeat this action over and over again. I decided to use something like:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">while</span> <span class="kw2">True</span>:<br />
&nbsp; &nbsp; record<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; analyze<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; sleep<span class="br0">&#40;</span><span class="nu0">2.0</span><span class="br0">&#41;</span></div>
<p>I am not sure what went wrong there but when it ran the second time it gave me an &#8220;internal PortAudio Error&#8221; which pissed me off. However, using BASH to handle the endless loop worked and I could achieve the desired functionality using something like:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">while</span> <span class="br0">&#91;</span> <span class="st0">&quot;true&quot;</span> <span class="br0">&#93;</span><br />
<span class="kw1">do</span><br />
&nbsp; python audio_analysis.py<br />
&nbsp; <span class="kw2">sleep</span> <span class="nu0">2</span><br />
<span class="kw1">done</span></div>
<p>This might be the wrong way to go about it but it works at least&#8230;..</p>
<p>Also, I thought growl would be something cool to have and I decided that I would go out there and get it use Growl to notify me but for some screwed up reason I cannot build Growl&#8217;s Python bindings using the Enthought Python Distribution which I use. I can however build it using Python 2.6 (and I still use the Numpy that comes with EPD). I get errors like:</p>
<pre>running install
running build
running build_py
running build_ext
building '_growlImage' extension
gcc -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -g -L/usr/local/lib -L/Library/Frameworks/Python.framework/Versions/4.3.0/lib -bundle -undefined dynamic_lookup build/temp.macosx-10.3-fat-2.5/growlImage.o -o build/lib.macosx-10.3-fat-2.5/_growlImage.so -framework Cocoa
ld: in /Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/Python.framework/Versions/4.3.0/lib/libz.1.dylib, file is not of required architecture for architecture ppc
collect2: ld returned 1 exit status
lipo: can't open input file: /var/tmp//ccNgltEc.out (No such file or directory)
error: command 'gcc' failed with exit status 1</pre>
<p>I think that I am unable to generate a universal binary there and as a result I can&#8217;t use Growl. Anyway, I have two screens and I can leave a terminal window open on one of those to see what&#8217;s going on in the surroundings. So sample run:</p>
<pre>cm92:scripts shriphani$ ./repeat.sh
Someone might be calling you
Current Time: 11:55:22
Intensity: 56.9166929341 dB

Someone might be calling you
Current Time: 11:55:33
Intensity: 72.6820018669 dB

Someone might be calling you
Current Time: 11:55:51
Intensity: 56.7505666696 dB

Someone might be calling you
Current Time: 11:55:54
Intensity: 55.571208569 dB

Someone might be calling you
Current Time: 11:55:58
Intensity: 60.0388858371 dB

Someone might be calling you
Current Time: 11:56:1
Intensity: 56.3460220002 dB</pre>
<p>These results were obtained in the following situations:</p>
<ul>
<li>The TV running.</li>
<li>My mom calling me.</li>
</ul>
<p>Anyway, in other news, I managed to end up with a GPA of 3.85 overall thanks to a series of mistakes towards the end of the semester and lost the 4.0&#8230;&#8230;.. it is depressing, but I&#8217;ll just put that behind me for now.</p>
<p>And I&#8217;m also trying to find a spot in Prof Kihara&#8217;s computational bio lab&#8230;.. I hope I get to do some research next semester.</p>
<p>The spring was not full of disappointment, I got to meet some awesome professors in the honors seminar (in which I skipped most of the student presentations except the one I was supposed to speak in). I got to meet Prof. Wagstaff who has a prime number named after him, I got to meet Prof Kihara and others.</p>
<p>Congrats to the Deccan Chargers for their excellent performance in the Indian Premier League. Thanks for rewarding our unyielding support by bringing the trophy to Hyderabad.</p>
<p>Now I&#8217;ve got to go and entertain myself with Combat Arms.</p>
<p>UPDATE: The script can be obtained at: <a href="http://shriphani.com/scripts/audio_analysis.py" target="_blank">Script to Record+Analyze</a> and <a href="http://shriphani.com/scripts/repeat.sh" target="_blank">Script to Repeat action</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2009/05/26/wav-files-spring-semester-research-hopes-ip/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hebb&#8217;s Rule</title>
		<link>http://shriphani.com/blog/2009/02/09/hebbs-rule/</link>
		<comments>http://shriphani.com/blog/2009/02/09/hebbs-rule/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 00:58:30 +0000</pubDate>
		<dc:creator>Shriphani</dc:creator>
				<category><![CDATA[College]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://shriphani.com/blog/?p=321</guid>
		<description><![CDATA[This post is slightly psychology influenced. Well, in the Psychology class I have been taking this semester (Introduction To Cognitive Learning), I was taught about Neural Networks and a certain Hebb&#8217;s Rule which allows a network to remember a previous configuration and use this configuration to interpret new information. We use the following model to [...]]]></description>
			<content:encoded><![CDATA[<p>This post is slightly psychology influenced. Well, in the Psychology class I have been taking this semester (Introduction To Cognitive Learning), I was taught about Neural Networks and a certain Hebb&#8217;s Rule which allows a network to remember a previous configuration and use this configuration to interpret new information. We use the following model to represent a cell:</p>
<p>1. A cell (neuron) has only two activation states: On or Off.</p>
<ul>
<li> On: Cell has high firing rate. (High number of action potentials fired in unit time).</li>
<li> Off: Cell has low firing rate.</li>
</ul>
<p>2. Cell weights are reciprocal. Weights symbolize the size of the synapse between two cells. Greater size = greater strength.</p>
<p>3. If cells fire simultaneously, they develop positive weights. The active cells (activation = on) inhibit the inactive cells (develop negative weights.</p>
<p>4. The network organizes itself based on sensory input. And new sensory info is interpreted by previously developed weights.</p>
<p>5. The network updates itself one at a time.</p>
<p>6. The activation of a cell can be determined by the following formula:</p>
<p>1 if &sum;w<sub>ij</sub>a<sub>j</sub> &gt; 0<br />
0 otherwise</p>
<p>The weights lend a sort of memory to the network since weights influence the interpretation of subsequent sensory input.</p>
<p>Based on these rules, I wrote something that simulated a network that implemented the Hebb&#8217;s rule.</p>
<p>First, we need to describe a neuron. Our neurons represent an uppercase letter of the english alphabet. We also need a way to represent the weights with each of the other neurons.</p>
<p>So a basic class to describe a neuron:</p>
<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">class</span> Neuron:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, a, weight_dict<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8221;</span><span class="st0">&#8216;A Represents The Cell&#8217;</span>s Content<span class="st0">&#8221;</span><span class="st0">&#8216;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.content = a #what letter of the alphabet a cell represents<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.weights = weight_dict #only contains contents of each neuron.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.state = 0 #activation state initially on.</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; def __str__(self):<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &quot;Activation: &quot;+str(self.state)+&quot;<span class="es0">\n</span>Weights: &quot;+str(self.weights)</span></div>
<p>Now, the network has a collection of neurons (26 in our case which signify each letter of the alphabet). Hence, the init method for the neuron class:</p>
<div class="dean_ch" style="white-space: nowrap;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">neurons</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">flush</span> = <span class="br0">&#123;</span><span class="br0">&#125;</span> <span class="co1">#weight calculator while updating activities</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">possibilities</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> char <span class="kw1">in</span> <span class="kw3">string</span>.<span class="me1">uppercase</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">flush</span><span class="br0">&#91;</span>char<span class="br0">&#93;</span> = <span class="nu0">0</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> letter <span class="kw1">in</span> <span class="kw3">string</span>.<span class="me1">uppercase</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; weights = <span class="kw3">copy</span>.<span class="kw3">copy</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">flush</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; weights.<span class="me1">pop</span><span class="br0">&#40;</span>letter<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a = Neuron<span class="br0">&#40;</span>letter, weights<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">neurons</span>.<span class="me1">append</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span></div>
<p>Now that we have a network that is populated, we need a method that receives input and figures out the changes in the weights between cells (or the strength of the connection between cells). This method is then fed by another method that figures out the overall change in the weights and computer which cells are active:</p>
<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">def</span> recvInput<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a = <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;Sensory Interface: &quot;</span><span class="br0">&#41;</span> <span class="co1">#Get a word</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> a != <span class="st0">&quot;QUIT&quot;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b = <span class="kw2">list</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">xrange</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>b<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> neuron <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">neurons</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char = b<span class="br0">&#91;</span>i<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> neuron.<span class="me1">content</span> == char:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; neuron.<span class="me1">state</span> = <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reqd_list = b<span class="br0">&#91;</span><span class="nu0">0</span>:i<span class="br0">&#93;</span>+b<span class="br0">&#91;</span>i<span class="nu0">+1</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> char <span class="kw1">in</span> <span class="kw3">string</span>.<span class="me1">uppercase</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> char <span class="kw1">in</span> reqd_list:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; neuron.<span class="me1">weights</span><span class="br0">&#91;</span>char<span class="br0">&#93;</span>+=<span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> neuron.<span class="me1">weights</span>.<span class="me1">has_key</span><span class="br0">&#40;</span>char<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; neuron.<span class="me1">weights</span><span class="br0">&#91;</span>char<span class="br0">&#93;</span>-=<span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">continue</span></p>
<p>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">checkInfo</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">possibleInfo</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;The possible interpretations of this input might be anagrams of the subsets of: <span class="es0">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="kw2">self</span>.<span class="me1">possibilities</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a = <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;Sensory Interface: &quot;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> checkInfo<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; possibilities = <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> neuron <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">neurons</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> neuron.<span class="me1">state</span> == <span class="nu0">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> info <span class="kw1">in</span> neuron.<span class="me1">weights</span>.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">flush</span><span class="br0">&#91;</span>info<span class="br0">&#93;</span> += neuron.<span class="me1">weights</span><span class="br0">&#91;</span>info<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="kw2">self</span>.<span class="me1">flush</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> neuron <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">neurons</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">flush</span><span class="br0">&#91;</span>neuron.<span class="me1">content</span><span class="br0">&#93;</span> &gt; <span class="nu0">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; neuron.<span class="me1">state</span> = <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; neuron.<span class="me1">state</span> = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> char <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">flush</span>.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">flush</span><span class="br0">&#91;</span>char<span class="br0">&#93;</span> = <span class="nu0">0</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> possibleInfo<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">possibilities</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> neuron <span class="kw1">in</span> <span class="kw2">self</span>.<span class="me1">neurons</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> neuron.<span class="me1">state</span> == <span class="nu0">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">possibilities</span>.<span class="me1">append</span><span class="br0">&#40;</span>neuron.<span class="me1">content</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>Then we run this network with:</p>
<div class="dean_ch" style="white-space: nowrap;">
words = Network<span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>words.<span class="me1">recvInput</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>Before I run this, let me mention that this thing only accepts uppercase letters and breaks if a letter is repeated in a word. This is because neurons rarely have their own axon connected to their own dendrite (neurons are not connected to themselves).</p>
<p>So, a sample run:</p>
<pre>
tark-b-183:scripts shriphani\> python hebb.py
Sensory Interface: HELP
{'A': -4, 'C': -4, 'B': -4, 'E': 3, 'D': -4, 'G': -4, 'F': -4, 'I': -4, 'H': 3, 'K': -4, 'J': -4, 'M': -4, 'L': 3, 'O': -4, 'N': -4, 'Q': -4, 'P': 3, 'S': -4, 'R': -4, 'U': -4, 'T': -4, 'W': -4, 'V': -4, 'Y': -4, 'X': -4, 'Z': -4}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'H', 'L', 'P']
Sensory Interface: LOSER
{'A': -9, 'C': -9, 'B': -9, 'E': 7, 'D': -9, 'G': -9, 'F': -9, 'I': -9, 'H': -2, 'K': -9, 'J': -9, 'M': -9, 'L': 7, 'O': 0, 'N': -9, 'Q': -9, 'P': -2, 'S': 0, 'R': 0, 'U': -9, 'T': -9, 'W': -9, 'V': -9, 'Y': -9, 'X': -9, 'Z': -9}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'L']
Sensory Interface: HOMELY
{'A': -12, 'C': -12, 'B': -12, 'E': 9, 'D': -12, 'G': -12, 'F': -12, 'I': -12, 'H': 4, 'K': -12, 'J': -12, 'M': -1, 'L': 9, 'O': 4, 'N': -12, 'Q': -12, 'P': -6, 'S': -6, 'R': -6, 'U': -12, 'T': -12, 'W': -12, 'V': -12, 'Y': -1, 'X': -12, 'Z': -12}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'H', 'L', 'O']
Sensory Interface: LOSER
{'A': -17, 'C': -17, 'B': -17, 'E': 13, 'D': -17, 'G': -17, 'F': -17, 'I': -17, 'H': -5, 'K': -17, 'J': -17, 'M': -9, 'L': 13, 'O': 8, 'N': -17, 'Q': -17, 'P': -11, 'S': 1, 'R': 1, 'U': -17, 'T': -17, 'W': -17, 'V': -17, 'Y': -9, 'X': -17, 'Z': -17}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'L', 'O', 'R', 'S']
</pre>
<p>So we observe that in the first case, four neurons were activated. The word &#8220;LOSER&#8221; led to H and P being deactivated because the synapse weakened. The next input &#8220;HOMELY&#8221; causes H and O to activate because O began developing positive weights with other cells and when LOSER was submitted as input and developed a strong enough connection when it was seen in another sensory input. When LOSER is flashed again, it leads to H being forgotten and causes R and S to activate. </p>
<p>Now, a particular case which (I think) indicates the use of this &#8220;learning&#8221; technique is when we are playing scrabble. Assume that I have words such as NEAR in my memory and when I see N and E on a board, I should be able to complete these words. Watch:</p>
<pre>
Sensory Interface: NEAR
{'A': 3, 'C': -4, 'B': -4, 'E': 3, 'D': -4, 'G': -4, 'F': -4, 'I': -4, 'H': -4, 'K': -4, 'J': -4, 'M': -4, 'L': -4, 'O': -4, 'N': 3, 'Q': -4, 'P': -4, 'S': -4, 'R': 3, 'U': -4, 'T': -4, 'W': -4, 'V': -4, 'Y': -4, 'X': -4, 'Z': -4}
The possible interpretations of this input might be anagrams of the subsets of: 

['A', 'E', 'N', 'R']
Sensory Interface: NE
{'A': 1, 'C': -6, 'B': -6, 'E': 4, 'D': -6, 'G': -6, 'F': -6, 'I': -6, 'H': -6, 'K': -6, 'J': -6, 'M': -6, 'L': -6, 'O': -6, 'N': 4, 'Q': -6, 'P': -6, 'S': -6, 'R': 1, 'U': -6, 'T': -6, 'W': -6, 'V': -6, 'Y': -6, 'X': -6, 'Z': -6}
The possible interpretations of this input might be anagrams of the subsets of: 

['A', 'E', 'N', 'R']
Sensory Interface:
</pre>
<p>Well, this semester, I have already been taught some insanely great stuff. I have a bunch of exams coming up. Great scores will be the perfect way to make an awesome semester even better.</p>
<p>The script can be downloaded <a href="http://shriphani.com/scripts/hebb.py" target="_blank">here</a>.<br />
The material here was used from Professor Greg Francis&#8217; <a href="http://www1.psych.purdue.edu/~gfrancis/Classes/PSY200/L08.pdf" target="_blank">notes on Neural Learning</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shriphani.com/blog/2009/02/09/hebbs-rule/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
