<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Calculating Combinatorials</title>
	<atom:link href="http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/</link>
	<description>An Irishman's Fiery</description>
	<lastBuildDate>Sat, 13 Feb 2010 12:16:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Fergal Daly</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-319359</link>
		<dc:creator>Fergal Daly</dc:creator>
		<pubDate>Mon, 14 Dec 2009 02:33:44 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-319359</guid>
		<description>The cs definitely are all integers. For random integers

c * i / (i – k)

can yield fractions however c is not random. It&#039;s a product of consecutive numbers divided by another product of just as many, smaller consecutive numbers and i and (i - k) are the next numbers in those repective sequences. This is always an integer, in fact it is comb(i, i - k) (I got that wrong in the earlier post, when I said comb(n, i))

Also, I think when you say

&lt;blockquote&gt;
There’s no reason k should be a whole divisor of c * i
&lt;/blockquote&gt;

you are assuming that c*i/(i-k) is whole if and only if k divides i. This is not the case e.g. c=5, i=6, k=2: 5 * 6 / (6 - 2) = 30/4 does not divide even though k does divide i. Also c=5, i=6, k=4: 30/2 = 15 despite the fact that k does not divide i. That kind of thing hold on the numerator e.g. (9 + x)/3 is only whole when 3 divides x.

The comment box ate my attempt to do a bit of maths and  post my code, so I posted it &lt;a href=&quot;http://wargle.blogspot.com/2009/12/computing-combinatorials.html&quot; rel=&quot;nofollow&quot;&gt;over here&lt;/a&gt;.</description>
		<content:encoded><![CDATA[<p>The cs definitely are all integers. For random integers</p>
<p>c * i / (i – k)</p>
<p>can yield fractions however c is not random. It&#8217;s a product of consecutive numbers divided by another product of just as many, smaller consecutive numbers and i and (i &#8211; k) are the next numbers in those repective sequences. This is always an integer, in fact it is comb(i, i &#8211; k) (I got that wrong in the earlier post, when I said comb(n, i))</p>
<p>Also, I think when you say</p>
<blockquote><p>
There’s no reason k should be a whole divisor of c * i
</p></blockquote>
<p>you are assuming that c*i/(i-k) is whole if and only if k divides i. This is not the case e.g. c=5, i=6, k=2: 5 * 6 / (6 &#8211; 2) = 30/4 does not divide even though k does divide i. Also c=5, i=6, k=4: 30/2 = 15 despite the fact that k does not divide i. That kind of thing hold on the numerator e.g. (9 + x)/3 is only whole when 3 divides x.</p>
<p>The comment box ate my attempt to do a bit of maths and  post my code, so I posted it <a href="http://wargle.blogspot.com/2009/12/computing-combinatorials.html" rel="nofollow">over here</a>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: colmmacc</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-319339</link>
		<dc:creator>colmmacc</dc:creator>
		<pubDate>Sun, 13 Dec 2009 14:50:44 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-319339</guid>
		<description>The final result won&#039;t have fractions, but intermediate calculations will - I started the c *= i and it doesn&#039;t pass tests, at least in python :-) 

  c * i / (i - k)

can clearly result in fractions! There&#039;s no reason k should be a whole divisor of c * i :-) You&#039;re right about the last snippet! stupid typo.</description>
		<content:encoded><![CDATA[<p>The final result won&#8217;t have fractions, but intermediate calculations will &#8211; I started the c *= i and it doesn&#8217;t pass tests, at least in python :-) </p>
<p>  c * i / (i &#8211; k)</p>
<p>can clearly result in fractions! There&#8217;s no reason k should be a whole divisor of c * i :-) You&#8217;re right about the last snippet! stupid typo.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Fergal Daly</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-318992</link>
		<dc:creator>Fergal Daly</dc:creator>
		<pubDate>Thu, 10 Dec 2009 00:26:02 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-318992</guid>
		<description>Also, you can avoid floats while keeping just 1 loop.. Just change

c *= float(i) / (i - k)

to

c *= i
c /= i - k

and you&#039;re done. You won&#039;t get fractions because

 comb(n, k) = comb(n, k - 1) * (n - k + 1) / k

(just write it out as factorials and cancel things)

so &lt;b&gt;c&lt;/b&gt; in your loop takes the values

comb(n, 0)
comb(n, 1)
comb(n, 2)
...
comb(n, k)

which are, of course, all integers.

By the way, I think the last code snippet in the main post should be range(k + 1, n + 1).</description>
		<content:encoded><![CDATA[<p>Also, you can avoid floats while keeping just 1 loop.. Just change</p>
<p>c *= float(i) / (i &#8211; k)</p>
<p>to</p>
<p>c *= i<br />
c /= i &#8211; k</p>
<p>and you&#8217;re done. You won&#8217;t get fractions because</p>
<p> comb(n, k) = comb(n, k &#8211; 1) * (n &#8211; k + 1) / k</p>
<p>(just write it out as factorials and cancel things)</p>
<p>so <b>c</b> in your loop takes the values</p>
<p>comb(n, 0)<br />
comb(n, 1)<br />
comb(n, 2)<br />
&#8230;<br />
comb(n, k)</p>
<p>which are, of course, all integers.</p>
<p>By the way, I think the last code snippet in the main post should be range(k + 1, n + 1).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Fergal Daly</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-318987</link>
		<dc:creator>Fergal Daly</dc:creator>
		<pubDate>Wed, 09 Dec 2009 23:36:14 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-318987</guid>
		<description>Throw in a

k = max(k, n - k)

at the beginning to knock 50% off the expected number of loop iterations (assuming you&#039;re calling it multiple times and all values of k are equally likely).

Without it, running this on k=0, ..., n would loop 0 + 1 + 2 + ... + n = n*(n+1)/2 times.

With it, that&#039;s 2*(0 + 1 + 2 + ... + n/2-1 + n/2) = (n/2) * (n/2+1) which is pretty much half of n*(n+1)/2 .</description>
		<content:encoded><![CDATA[<p>Throw in a</p>
<p>k = max(k, n &#8211; k)</p>
<p>at the beginning to knock 50% off the expected number of loop iterations (assuming you&#8217;re calling it multiple times and all values of k are equally likely).</p>
<p>Without it, running this on k=0, &#8230;, n would loop 0 + 1 + 2 + &#8230; + n = n*(n+1)/2 times.</p>
<p>With it, that&#8217;s 2*(0 + 1 + 2 + &#8230; + n/2-1 + n/2) = (n/2) * (n/2+1) which is pretty much half of n*(n+1)/2 .</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: dwmalone</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-294117</link>
		<dc:creator>dwmalone</dc:creator>
		<pubDate>Tue, 02 Jun 2009 16:48:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-294117</guid>
		<description>For largeish numbers, then using Stirling&#039;s formula may give you OK estimates. Largeish may not be as large as you expect too.

(I guess you know that you basically get this by estimating log(n!) with an integral.)</description>
		<content:encoded><![CDATA[<p>For largeish numbers, then using Stirling&#8217;s formula may give you OK estimates. Largeish may not be as large as you expect too.</p>
<p>(I guess you know that you basically get this by estimating log(n!) with an integral.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Adam</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-293025</link>
		<dc:creator>Adam</dc:creator>
		<pubDate>Fri, 29 May 2009 17:10:05 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-293025</guid>
		<description>I was interested by the decision to do the calculation in one loop rather
than two, as this forces you to work in arbitrary precision rationals
rather than integers.  My implementation of your algorithm is:

comb :: Rational -&gt; Rational -&gt; Rational
comb n k = prod $ map f [k+1..n]
    where f i = i / (i - k)

but doing two loops and dividing the result has the advantage of allowing
you to do integer arithmetic only (at the expense of dealing with larger
numbers).

comb :: Integer -&gt; Integer -&gt; Integer
comb n k = x `div` y
   where x = prod [k+1..n]
         y = prod $ map (\i -&gt; (i-k)) [k+1..n]

For my quick and unscientific test this is 30% faster doing comb 100000 50000.</description>
		<content:encoded><![CDATA[<p>I was interested by the decision to do the calculation in one loop rather<br />
than two, as this forces you to work in arbitrary precision rationals<br />
rather than integers.  My implementation of your algorithm is:</p>
<p>comb :: Rational -&gt; Rational -&gt; Rational<br />
comb n k = prod $ map f [k+1..n]<br />
    where f i = i / (i &#8211; k)</p>
<p>but doing two loops and dividing the result has the advantage of allowing<br />
you to do integer arithmetic only (at the expense of dealing with larger<br />
numbers).</p>
<p>comb :: Integer -&gt; Integer -&gt; Integer<br />
comb n k = x `div` y<br />
   where x = prod [k+1..n]<br />
         y = prod $ map (\i -&gt; (i-k)) [k+1..n]</p>
<p>For my quick and unscientific test this is 30% faster doing comb 100000 50000.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JD</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-292944</link>
		<dc:creator>JD</dc:creator>
		<pubDate>Fri, 29 May 2009 10:49:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-292944</guid>
		<description>And a brief test proves you correct... in python at least :)

It&#039;s a good point that applying a little bit of brain to make calculations easier for a computer is often time well spent.</description>
		<content:encoded><![CDATA[<p>And a brief test proves you correct&#8230; in python at least :)</p>
<p>It&#8217;s a good point that applying a little bit of brain to make calculations easier for a computer is often time well spent.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: colmmacc</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-292932</link>
		<dc:creator>colmmacc</dc:creator>
		<pubDate>Fri, 29 May 2009 10:09:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-292932</guid>
		<description>Not in comparison to what&#039;s saved though. In a real implementation, not shortened for a blog post, the multiplication and division will be performed with arbitrary precision arithmetic libraries anyway :-)

Mostly just wanted a correct illustrative snippet people could try on their own machine quickly.</description>
		<content:encoded><![CDATA[<p>Not in comparison to what&#8217;s saved though. In a real implementation, not shortened for a blog post, the multiplication and division will be performed with arbitrary precision arithmetic libraries anyway :-)</p>
<p>Mostly just wanted a correct illustrative snippet people could try on their own machine quickly.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JD</title>
		<link>http://www.stdlib.net/~colmmacc/2009/05/29/calculating-combinatorials/comment-page-1/#comment-292930</link>
		<dc:creator>JD</dc:creator>
		<pubDate>Fri, 29 May 2009 10:06:59 +0000</pubDate>
		<guid isPermaLink="false">http://www.stdlib.net/~colmmacc/?p=372#comment-292930</guid>
		<description>I was thinking about combining the division and multiplication when you posted your original solution, but wouldn&#039;t ending up with floats slow down the entire operation?</description>
		<content:encoded><![CDATA[<p>I was thinking about combining the division and multiplication when you posted your original solution, but wouldn&#8217;t ending up with floats slow down the entire operation?</p>
]]></content:encoded>
	</item>
</channel>
</rss>
