function x = nbininv(y,r,p)
%NBININV Inverse of the negative binomial cumulative distribution function (cdf).
%   X = NBININV(Y,R,P) returns the inverse of the negative binomial cdf with 
%   parameters R and P. Since the negative binomial distribution is discrete,
%   NBININV returns the least integer X such that the negative
%   binomial cdf evaluated at X, equals or exceeds Y.
%
%   The size of X is the common size of the input arguments. A scalar input  
%   functions as a constant matrix of the same size as the other inputs.    

%   B.A. Jones 1-24-95
%   Copyright (c) 1993-96 by The MathWorks, Inc.
%   $Revision: 2.3 $  $Date: 1996/02/21 18:34:00 $

if nargin < 3, 
    error('Requires three input arguments.'); 
end 

[errorcode y r p] = distchck(3,y,r,p);

if errorcode > 0
    error('Requires non-scalar arguments to match in size.');
end
k = 1:prod(size(y));
k1 = find(r < 1 | p < 0 | p > 1 | round(r) ~= r | y < 0 | y > 1 | isnan(y)); 
k(k1) = [];

% Initialize X to 0.
x = zeros(size(y));
cumdist = nbinpdf(x,r,p);

count = 0;

% Compare Y to the binomial distribution for each value of r.
while any(any(y(k) > cumdist(k)))
    count = count + 1;
    index = find(cumdist < y);
    x(index) = x(index) + 1;
    cumdist = cumdist + nbinpdf(count,r,p);
end

if any(k1)
    tmp   = NaN;
    x(k1) = tmp(ones(size(k1))); 
end
