function ln_num_ways = nchoosekln(nn, kk) %NCHOOSEKLN log Binomial coefficient for large choices, log(nchoosek(nn, kk)) % % ln_num_ways = nchoosekln(nn, kk); % % returns the natural logarithm of the number of ways of picking kk items from a % set of size nn. This routine works for huge kk, unlike log(nchoosek(nn, kk)), % which overflows. % % Inputs: % nn MxN or 1x1 size of population to choose from % kk MxN or 1x1 number of items to choose % % Outputs: % ln_num_ways MxN elementwise log(nchoosek(nn,kk)) = log( nn!/((nn-kk)!*kk!) ) % % NOTE NCHOOSEK interprets vector-valued nn's differently: it enumerates the % subsets of nn of size kk. This routine is designed for large kk where % enumeration of the subsets is impractical. Instead vector-valued nn's are % interpreted as a list of population sizes, which allows some codes to be % vectorized more easily. % % SEE ALSO: NCHOOSEK, NCHOOSEK_WR, NCHOOSEK_OWR % Iain Murray, September 2010 % Input sanity checking to help avoid bugs: if ~isequal(round(nn), nn) || any(nn < 0) error('Number of items, nn, must be a nonnegative integer.'); end if ~isequal(round(kk), kk) || any(kk < 0) || any(kk > nn) error('Number of choices, kk, must be between 0 and nn.'); end % This function is a trivial one-liner, provided for readability: % ln_num_ways = log( nn!/((nn-kk)!*kk!) ) ln_num_ways = gammaln(nn+1) - gammaln(nn-kk+1) - gammaln(kk+1);