;ò
L‘Fc@sYdZdgd„Zdfd„ƒYZeƒZed„Zed„Zdd„ZdS( sDCombinatorics.
$Id: Pascal.py,v 1.1 2007/03/08 23:49:49 eddy Exp $
icCsñ|djo
td‚ny||SWntj
onX|dt|ƒf\}}xŽ||jo€y||}Wn#tj
ot|ƒ|}nXd|}t|ƒdjo+|i |ƒ|t|ƒjpt
‚q[q[W|SdS(s•Returns the factorial of any natural number.
Equivalent to reduce(lambda a,b:a*(1+b), range(num), 1L), except that it
doesn't return a long unless it has to (or num is one) and it degrades
gracefully when given invalid input.
For agrguments < 0 this raises a ValueError. For other arguments < 1,
you'll get the answer 1, as this is correct if your argument is valid
and resolves the problem of what to do with invalid input. For other
non-integer non-negative values, you'll get a computed positive value
which probably isn't far off the Gamma function's value at one more than
that non-integer. For valid input, i.e. non-negative integers,
factorial(num) = Gamma(1+num), wherein
Gamma(1+a) = integral(: exp(-t).power(a, t) ←t :{positive reals})
for arbitrary a in the complex plane, with a pole (of order 1) at each
negative integer and a real humdinger of a singularity at infinity. isI only do naturalsiÿÿÿÿii N(snums
ValueErrorscaches
IndexErrorslensresultsis
OverflowErrorslongsappendsAssertionError(snumscachesisresult((s(/home/eddy/.sys/py/study/maths/Pascal.pys factorials&
#sPascalcBs>tZdZhZd„Zd„Zd„ZeZd„ZRS(s]A dictionary describing Pascal's triangle.
Keys are pairs of naturals; value for (n,m) is (n+m)! / n! / m!
Given the symmetry, no value is actually stored for key (n,m) when m > n.
Given the nature of Pascal's triangle, computing the value for a given (n,m)
involves computing the values for all (i,j) with i<=n and j<=m.
Representation depicts Pascal's triangle with one side as the top line, the
other as the left column; a `row' of Pascal's triangle is thus a diagonal
stripe. Only values we've actually needed are shown, so there's nothing
above the diagonal; except on the top line, where a 1 is displayed above the
last digit of the diagonal entry in each column.
Note that neither this class nor its one instance is any part of this
module's export: it is over-ridden by a curried form of chose(), below.
cCs¼|\}}y|i||ƒ}Wntj
oƒ}|GH|iddjo‚nt ||ƒt |ƒt |ƒ}||jo||f\}}n||i
||fs != s
N(sresultsselfs_Pascal__valuessitemssnsmsvals factorialschecksappends
joinfields(sselfsvalsmsnsresultscheck((s(/home/eddy/.sys/py/study/maths/Pascal.pyscheck~s$
-( s__name__s
__module__s__doc__s_Pascal__valuess__getitem__s_Pascal__lookups__str__s__repr__scheck(((s(/home/eddy/.sys/py/study/maths/Pascal.pysPascal*s #cCs||||fSdS(s²chose(N,i) -> N! / (N-i)! / i!
This is the number of ways of chosing i items from among N, ignoring order
of choice. Computed using a cached form of Pascal's triangle. N(srackstotalspart(stotalspartsrack((s(/home/eddy/.sys/py/study/maths/Pascal.pyschose‹scCs|iƒdS(N(srackscheck(srack((s(/home/eddy/.sys/py/study/maths/Pascal.pyscheck“scCs*tt||d„td|ƒƒƒSdS(sfA row of Pascal's triangle, optionally scaled, as a tuple.
Required argument, tot, is the row index: Pascal(1+i)[1+j] = Pascal(i)[j] +
Pascal(i)[1+j] give-or-take missing entries being presumed zero, with
Pascal[0] = (1,). Optional second argument is an over-all scaling to apply
to all entries in the row; thus sum(Pascal(n, .5**n)) == 1.
cCst||ƒ|S(N(schosestsiss(sistss((s(/home/eddy/.sys/py/study/maths/Pascal.pyssiN(stuplesmapstotsscalesrange(stotsscale((s(/home/eddy/.sys/py/study/maths/Pascal.pysPascal•sN(s__doc__s factorialsPascalschosescheck(s factorialsPascalschosescheck((s(/home/eddy/.sys/py/study/maths/Pascal.pys?s$_