1## Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2005, 2006, 2007,
2## 2008, 2009 Kurt Hornik
4## This file is part of Octave.
6## Octave is free software; you can redistribute it and/or modify it
7## under the terms of the GNU General Public License as published by
8## the Free Software Foundation; either version 3 of the License, or (at
9## your option) any later version.
11## Octave is distributed in the hope that it will be useful, but
12## WITHOUT ANY WARRANTY; without even the implied warranty of
13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14## General Public License for more details.
16## You should have received a copy of the GNU General Public License
17## along with Octave; see the file COPYING. If not, see
18## <http://www.gnu.org/licenses/>.
21## @deftypefn {Mapping Function} {} bincoeff (@var{n}, @var{k})
22## Return the binomial coefficient of @var{n} and @var{k}, defined as
25## {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
33## | n | n (n-1) (n-2) @dots{} (n-k+1)
34## | | = -------------------------
50## In most cases, the @code{nchoosek} function is faster for small
51## scalar integer arguments. It also warns about loss of precision for
57## Author: KH <Kurt.Hornik@wu-wien.ac.at>
58## Created: 8 October 1994
61function b = bincoeff (n, k)
67 [retval, n, k] = common_size (n, k);
69 error ("bincoeff: n and k must be of common size or scalars");
75 ind = (! (k >= 0) | (k != real (round (k))) | isnan (n));
81 ind = ((k > 0) & ((n == real (round (n))) & (n < 0)));
82 b(ind) = (-1) .^ k(ind) .* exp (gammaln (abs (n(ind)) + k(ind))
83 - gammaln (k(ind) + 1)
84 - gammaln (abs (n(ind))));
86 ind = ((k > 0) & (n >= k));
87 b(ind) = exp (gammaln (n(ind) + 1)
88 - gammaln (k(ind) + 1)
89 - gammaln (n(ind) - k(ind) + 1));
91 ind = ((k > 0) & ((n != real (round (n))) & (n < k)));
92 b(ind) = (1/pi) * exp (gammaln (n(ind) + 1)
93 - gammaln (k(ind) + 1)
94 + gammaln (k(ind) - n(ind))
95 + log (sin (pi * (n(ind) - k(ind) + 1))));
97 ## Clean up rounding errors.
98 ind = (n == round (n));
99 b(ind) = round (b(ind));
101 ind = (n != round (n));
102 b(ind) = real (b(ind));
106%!assert(bincoeff(4,2), 6)
107%!assert(bincoeff(2,4), 0)
108%!assert(bincoeff(0.4,2), -.12, 8*eps)
110%!assert(bincoeff (5, 2) == 10 && bincoeff (50, 6) == 15890700);
114%!error bincoeff (1, 2, 3);