<?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>A Party to the World &#187; math</title>
	<atom:link href="http://dan.lecocq.us/wordpress/tag/math/feed/" rel="self" type="application/rss+xml" />
	<link>http://dan.lecocq.us/wordpress</link>
	<description>Life, love, and computer science</description>
	<lastBuildDate>Fri, 06 Jan 2012 17:21:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Sum of Dice</title>
		<link>http://dan.lecocq.us/wordpress/2011/05/10/sum-of-dice/</link>
		<comments>http://dan.lecocq.us/wordpress/2011/05/10/sum-of-dice/#comments</comments>
		<pubDate>Tue, 10 May 2011 17:28:41 +0000</pubDate>
		<dc:creator>dan.lecocq</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[combinatorics]]></category>
		<category><![CDATA[dice]]></category>

		<guid isPermaLink="false">http://dan.lecocq.us/wordpress/?p=922</guid>
		<description><![CDATA[I recently had an interview in which I was asked, &#8220;how many ways can 1000 dice make the sum 3000?&#8221; I was caught a little off-guard, and the phrasing made me wonder about a closed-form solution which, after some reading, I don&#8217;t believe exists. Still, a workable solution isn&#8217;t as easy as that. Let F(n, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had an interview in which I was asked, &#8220;how many ways can 1000 dice make the sum 3000?&#8221; I was caught a little off-guard, and the phrasing made me wonder about a closed-form solution which, after some reading, I don&#8217;t believe exists. Still, a workable solution isn&#8217;t as easy as that.</p>
<p>Let <em>F(n, k)</em> denote the number of ways <em>n</em> dice can make the sum <em>k</em>. Note that the first die can be 1, 2, 3, 4, 5 or 6, so <em>F(1000, 3000) = F(999, 2999) + F(999, 2998) + &#8230; + F(999, 2994)</em>. While this recurrence relation leads to an easy implementation, it suffers from two big problems: performance and maximum recursion depth. Without any <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a> or optimization, this would lead to 6<sup>1000</sup> function calls, which is about 10<sup>780</sup>. That&#8217;s a big number. If you were able to evaluate one such function call every clock cycle on every computer in the world (about 7 x 10<sup>18</sup> cycles/second), you would need about 10<sup>750</sup> years, or 10<sup>650</sup> lifetimes of the universe (about 10<sup>100</sup> years) to solve it. Get ready to wait.</p>
<p>One optimization is to check if the arguments n and k make sense at each level, and prune accordingly. For example, n dice can only sum to between n and 6n, so if k is outside of that range, you don&#8217;t need to branch down any farther. Even using this and instantaneous branch evaluation, your code still wouldn&#8217;t complete in the expected lifetime of the universe.</p>
<p>Obviously, this is still a solvable problem (there are about 10<sup>757</sup> ways 1000 dice can sum to 3000). A python implementation figured that out in 3.5 seconds. One way to help crack this egg is to use memoization. Consider the calls to <em>F(999, 2999)</em> and <em>F(999, 2998)</em>. Expand these out to get:</p>
<ul>
<li><em>F(999, 2999) = sum[F(998, k = 2998, 2997, 2996, 2995, 2994, 2993)]</em></li>
<li><em>F(999, 2998) = sum[F(998, k = 2997, 2996, 2995, 2994, 2993, 2992)]</em></li>
</ul>
<p>You&#8217;ll notice that both of these expansions call <em>F(998, k = 2997, 2996, 2995, 2994, 2993)</em>, each of which is a <em>lot</em> of work to evaluate. So, if once you determined each of these values once, you could use them in other places and save huge amounts of time.</p>
<p>One thing you&#8217;d need in order to implement memoization is a map (or dictionary in python) that stores key-value pairs. So once you figure out <em>F(998, 2997)</em>, you could store it like <em>myMap[(998, 2997)] = &#8230;</em>; but this can add some complication. Every time to call F, you&#8217;d have to check if you&#8217;ve already evaluated the function for those arguments. And when you&#8217;ve figured out and stored a lot of these values, each search will take some time. It will still work and will get you the answer you need, but probably not as fast as you&#8217;d like, and not as fast as it could be. Using memoization for <em>F(700, 2100)</em> took 8.2 seconds in a python implementation, but a better approach took 1.5 seconds. The maximum recursion depth prevented it from using bigger numbers.</p>
<p>Algorithmically, the best you&#8217;ll be able to do (as far as I can tell) is <em>O(n<sup>2</sup>)</em>, which is not bad in the scheme of things, and certainly not the combinatoric time we saw first. Enter dynamic programming. Particularly, we&#8217;ll use a <a href="http://en.wikipedia.org/wiki/Top-down_and_bottom-up_design">bottom-up approach</a>. We&#8217;ll build two arrays, each associated with a number of dice. The <em>i</em>&#8216;th index in that array is the number of ways n dice can sum up to <em>(n + i)</em>. So for 1 die, <em>myArray[0]</em> is the number of ways you can roll a 1, and for 4 dice, <em>myArray[10]</em> would be the number of ways you can roll 4 dice to get 14.</p>
<p>As I said, we&#8217;ll keep track of two arrays, say <em>previous</em> and <em>current</em>. First, initialize previous to be the number of ways 1 die can be rolled: <em>{1, 1, 1, 1, 1, 1}</em>, because 1 die can be rolled each number in only one way. Then, we&#8217;ll use that to fill the array &#8220;current&#8221; with the number of ways 2 dice can be rolled, based on the array <em>previous</em>. For example, <em>current[0] = previous[0] = 1</em>, because the only way to get a sum of n with n dice is to roll all 1&#8242;s. Then, <em>current[1] = previous[0] + previous[1]</em>, because if we roll a 2 for the second dice, there are <em>previous[0]</em> ways to sum up to 1 with the remaining die, or if we roll a 1 for the second dice, there are <em>previous[1]</em> ways to sum up to 2 with the remaining die.</p>
<p>Each entry <em>current[i]</em> should be the sum of <em>previous[i-5, i-4, i-3, i-2, i-1, i]</em>, taking the bounds of the previous array into consideration (this can actually be generalized to any <em>m</em>-sided dice by using previous[i-m+1, ..., i]). Once you&#8217;ve filled the array <em>current</em>, then you assign current to previous, and move on to the next number of dice, 3. Continue this until you have filled the array for the desired number of dice. If performance is a big issue, this can be implemented as a moving frame. For example, since <em>current[i]</em> uses <em>previous[i-5, ..., i]</em> and <em>current[i+1]</em> uses <em>previous[i-4, ..., i+1]</em>, you can alternatively write <em>current[i+1] = current[i] &#8211; previous[i-5] + previous[i+1]</em>, and use only two add/subtract operations instead of 5.</p>
<p>A bonus to this bottom-approach is that once finished, you actually have an array with the number of ways you can make <em>any</em> sum with the <em>n</em> dice. This makes it easy if you wish to find the number of ways <em>n</em> dice can form a sum <em>up to</em> or <em>greater than</em> a number.</p>
]]></content:encoded>
			<wfw:commentRss>http://dan.lecocq.us/wordpress/2011/05/10/sum-of-dice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>webGLot &#8211; A Preview</title>
		<link>http://dan.lecocq.us/wordpress/2009/12/24/webglot-a-preview/</link>
		<comments>http://dan.lecocq.us/wordpress/2009/12/24/webglot-a-preview/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 12:14:40 +0000</pubDate>
		<dc:creator>dan.lecocq</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[openglot]]></category>
		<category><![CDATA[plotting]]></category>
		<category><![CDATA[webgl]]></category>
		<category><![CDATA[webglot]]></category>

		<guid isPermaLink="false">http://dan.lecocq.us/wordpress/?p=787</guid>
		<description><![CDATA[I&#8217;ve mentioned WebGL before, and I think it could be very important. There is a competitor from Google, but like OpenGL and OpenCL, this API is managed by the Khronos Group and that fact appeals to me. Perhaps it&#8217;s that I&#8217;ve used it fairly extensively, but I really like OpenGL. Despite its quirks, it&#8217;s quite [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve <a href="http://dan.lecocq.us/wordpress/2009/09/22/the-future-of-the-internet/">mentioned WebGL before</a>, and I think it could be very important.  There is a <a href="http://code.google.com/apis/o3d/">competitor from Google</a>, but like OpenGL and OpenCL, this API is managed by the <a href="http://www.khronos.org/">Khronos Group</a> and that fact appeals to me.  Perhaps it&#8217;s that I&#8217;ve used it fairly extensively, but I really like OpenGL.  Despite its quirks, it&#8217;s quite powerful.</p>
<p>The big &#8220;get&#8221; is that it gives programmers access to hardware-accelerated graphics from directly within the browser.  There&#8217;s a lot of interest in this arena for game development as it would obviate much of the need for separate distributions based on operating system.  (Skip to the end for more of an opinion on this subject.)</p>
<p>As such, I&#8217;ve been working with WebGL as opposed to the Google-proposed O3D.  (I have every intention to explore O3D, time permitting, as there are some jagged edges to the current specification.)  The result of this recent toil is a budding WebGL implementation of my OpenGLot project.  It&#8217;s still in early stages, but in the coming weeks, it should develop even further.  To whet appetites, I have a few pictures.</p>
<div id="attachment_788" class="wp-caption aligncenter" style="width: 310px"><a href="http://dan.lecocq.us/wordpress/wp-content/uploads/2009/12/Picture-105.png"><img src="http://dan.lecocq.us/wordpress/wp-content/uploads/2009/12/Picture-105-300x182.png" alt="A scalar field, my persistent test function." title="Picture 105" width="300" height="182" class="size-medium wp-image-788" /></a><p class="wp-caption-text">A scalar field, my persistent test function.</p></div>
<div id="attachment_789" class="wp-caption aligncenter" style="width: 310px"><a href="http://dan.lecocq.us/wordpress/wp-content/uploads/2009/12/Picture-111.png"><img src="http://dan.lecocq.us/wordpress/wp-content/uploads/2009/12/Picture-111-300x215.png" alt="A 3D surface, again one of my usual test functions." title="Picture 111" width="300" height="215" class="size-medium wp-image-789" /></a><p class="wp-caption-text">A 3D surface, again one of my usual test functions.</p></div>
<p>I seriously doubt that WebGL will every match the performance of OpenGL.  Even though JavaScript interpreters are getting faster at a somewhat alarming rate, they won&#8217;t match the speed of C or C++.  That said, if one can appropriately offload work onto the GPU, it won&#8217;t matter as much, but there will always be that overhead.</p>
<p>It won&#8217;t so much be a matter of having the same performance, but <em>enough</em> performance.  If a person can go to a single webpage and get 60 frames per second performance in a game or tool without having to install software, that&#8217;s tremendous.  Currently I&#8217;ve been getting between 60 and 90 frames per second with WebGLot, and I&#8217;m sure I can keep that number up as more features are added.</p>
<p>My hope is that this will be a tool and library that has a wide-enough feature set by the time WebGL is widely adopted that becomes often-used.  But that&#8217;s just ego.  The purer motivation is that if you&#8217;re a math teacher, and you want to have interactive demonstrations of Newton&#8217;s method, or parametric surfaces, or even flow fields, you can write an application in 20 minutes that does all the heavy lifting of graphing it for you.  As long as you can describe the mathematical primitives, you should be able to render it.  Of course there will be a general-purpose grapher available for any calculus student who&#8217;s having trouble visualizing this or that, too.  Or a resourceful PDE student who need to solve his homework (the GPU-based PDE solver will take a little bit more time, but it&#8217;s very nearly complete).</p>
<p>In short, the strength of WebGL is that is has respectable performance, and in a year&#8217;s time, half the browsers (well maybe not half) on computers will support it, giving the average internet-user access to a wealth of media.</p>
]]></content:encoded>
			<wfw:commentRss>http://dan.lecocq.us/wordpress/2009/12/24/webglot-a-preview/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Sum of Combinatoric Terms</title>
		<link>http://dan.lecocq.us/wordpress/2008/10/03/sum-of-combinatoric-terms/</link>
		<comments>http://dan.lecocq.us/wordpress/2008/10/03/sum-of-combinatoric-terms/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 17:42:14 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[computer science]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[proofs]]></category>
		<category><![CDATA[infinite sum]]></category>
		<category><![CDATA[proof]]></category>
		<category><![CDATA[series]]></category>

		<guid isPermaLink="false">http://dan.lecocq.us/wordpress/2008/10/03/sum-of-combinatoric-terms/</guid>
		<description><![CDATA[Matt Matteson had a homework problem dealing with (n+a)^b, and finding a bound for it. Expanding this and evaluating it at n=a piqued my curiosity about the sum of each of the binomial expansion terms. That is to say, the sum of bC0 + bC1 + &#8230; + bCb. Well, I explored it a little [...]]]></description>
			<content:encoded><![CDATA[<p>Matt Matteson had a homework problem dealing with (n+a)^b, and finding a bound for it.  Expanding this and evaluating it at n=a piqued my curiosity about the sum of each of the binomial expansion terms.  That is to say, the sum of bC0 + bC1 + &#8230; + bCb.  Well, I explored it a little bit, and did a quick-and-dirty writeup of my findings:</p>
<p><a href='http://dan.lecocq.us/wordpress/wp-content/uploads/2008/10/combinotoricsum.pdf' title='Sum of Combinatoric Terms'>Sum of Combinatoric Terms</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dan.lecocq.us/wordpress/2008/10/03/sum-of-combinatoric-terms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

