X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fm%2Fmiscellaneous%2Fbincoeff.m;fp=octave_packages%2Fm%2Fmiscellaneous%2Fbincoeff.m;h=1f7cf57698605bc0fc7bc9352a3ed9d2c5b9b1c5;hp=0000000000000000000000000000000000000000;hb=1c0469ada9531828709108a4882a751d2816994a;hpb=63de9f36673d49121015e3695f2c336ea92bc278 diff --git a/octave_packages/m/miscellaneous/bincoeff.m b/octave_packages/m/miscellaneous/bincoeff.m new file mode 100644 index 0000000..1f7cf57 --- /dev/null +++ b/octave_packages/m/miscellaneous/bincoeff.m @@ -0,0 +1,120 @@ +## Copyright (C) 1995-2012 Kurt Hornik +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . + +## -*- texinfo -*- +## @deftypefn {Mapping Function} {} bincoeff (@var{n}, @var{k}) +## Return the binomial coefficient of @var{n} and @var{k}, defined as +## @tex +## $$ +## {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!} +## $$ +## @end tex +## @ifnottex +## +## @example +## @group +## / \ +## | n | n (n-1) (n-2) @dots{} (n-k+1) +## | | = ------------------------- +## | k | k! +## \ / +## @end group +## @end example +## +## @end ifnottex +## For example: +## +## @example +## @group +## bincoeff (5, 2) +## @result{} 10 +## @end group +## @end example +## +## In most cases, the @code{nchoosek} function is faster for small +## scalar integer arguments. It also warns about loss of precision for +## big arguments. +## +## @seealso{nchoosek} +## @end deftypefn + +## Author: KH +## Created: 8 October 1994 +## Adapted-By: jwe + +function b = bincoeff (n, k) + + if (nargin != 2) + print_usage (); + endif + + [retval, n, k] = common_size (n, k); + if (retval > 0) + error ("bincoeff: N and K must be of common size or scalars"); + endif + + if (iscomplex (n) || iscomplex (k)) + error ("bincoeff: N and K must not be complex"); + endif + + b = zeros (size (n)); + + ok = (k >= 0) & (k == fix (k)) & (! isnan (n)); + b(! ok) = NaN; + + n_int = (n == fix (n)); + idx = n_int & (n < 0) & ok; + b(idx) = (-1) .^ k(idx) .* exp (gammaln (abs (n(idx)) + k(idx)) + - gammaln (k(idx) + 1) + - gammaln (abs (n(idx)))); + + idx = (n >= k) & ok; + b(idx) = exp (gammaln (n(idx) + 1) + - gammaln (k(idx) + 1) + - gammaln (n(idx) - k(idx) + 1)); + + idx = (! n_int) & (n < k) & ok; + b(idx) = (1/pi) * exp (gammaln (n(idx) + 1) + - gammaln (k(idx) + 1) + + gammaln (k(idx) - n(idx)) + + log (sin (pi * (n(idx) - k(idx) + 1)))); + + ## Clean up rounding errors. + b(n_int) = round (b(n_int)); + + idx = ! n_int; + b(idx) = real (b(idx)); + +endfunction + + +%!assert(bincoeff (4, 2), 6) +%!assert(bincoeff (2, 4), 0) +%!assert(bincoeff (-4, 2), 10) +%!assert(bincoeff (5, 2), 10) +%!assert(bincoeff (50, 6), 15890700) +%!assert(bincoeff (0.4, 2), -.12, 8*eps) + +%!assert(bincoeff ([4 NaN 4], [-1, 2, 2.5]), NaN (1, 3)) + +%% Test input validation +%!error bincoeff (); +%!error bincoeff (1, 2, 3); +%!error bincoeff (ones(3),ones(2)) +%!error bincoeff (ones(2),ones(3)) +