📄 betainv.m
字号:
function x = betainv(p,a,b);
%BETAINV Inverse of the beta cumulative distribution function (cdf).
% X = BETAINV(P,A,B) returns the inverse of the beta cdf with
% parameters A and B at the values in P.
%
% 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.
%
% BETAINV uses Newton's method to converge to the solution.
% Reference:
% [1] M. Abramowitz and I. A. Stegun, "Handbook of Mathematical
% Functions", Government Printing Office, 1964.
% B.A. Jones 1-12-93
% Copyright (c) 1993 by The MathWorks, Inc.
% $Revision: 1.1 $ $Date: 1993/05/24 18:53:18 $
if nargin < 3,
error('Requires three input arguments.');
end
[errorcode p a b] = distchck(3,p,a,b);
if errorcode > 0
error('The arguments must be the same size or be scalars.');
end
% Initialize x to zero.
x = zeros(size(p));
% Return NaN if the arguments are outside their respective limits.
k = find(p < 0 | p > 1 | a <= 0 | b <= 0);
if any(k),
x(k) = NaN * ones(size(k));
end
% The inverse cdf of 0 is 0, and the inverse cdf of 1 is 1.
k0 = find(p == 0 & a > 0 & b > 0);
if any(k0),
x(k0) = zeros(size(k0));
end
k1 = find(p==1);
if any(k1),
x(k1) = ones(size(k1));
end
% Newton's Method.
% Permit no more than count_limit interations.
count_limit = 100;
count = 0;
k = find(p > 0 & p < 1 & a > 0 & b > 0);
pk = p(k);
% Use the mean as a starting guess.
xk = a(k) ./ (a(k) + b(k));
% Move starting values away from the boundaries.
if xk == 0,
xk = sqrt(eps);
end
if xk == 1,
xk = 1 - sqrt(eps);
end
h = ones(size(pk));
crit = sqrt(eps);
% Break out of the iteration loop for the following:
% 1) The last update is very small (compared to x).
% 2) The last update is very small (compared to 100*eps).
% 3) There are more than 100 iterations. This should NEVER happen.
while(any(abs(h) > crit * abs(xk)) & max(abs(h)) > crit ...
& count < count_limit),
count = count+1;
h = (betacdf(xk,a(k),b(k)) - pk) ./ betapdf(xk,a(k),b(k));
xnew = xk - h;
% Make sure that the values stay inside the bounds.
% Initially, Newton's Method may take big steps.
ksmall = find(xnew < 0);
klarge = find(xnew > 1);
if any(ksmall) | any(klarge)
xnew(ksmall) = xk(ksmall) /10;
xnew(klarge) = 1 - (1 - xk(klarge))/10;
end
xk = xnew;
end
% Return the converged value(s).
x(k) = xk;
if count==count_limit,
fprintf('\nWarning: BETAINV did not converge.\n');
fprintf('The last Newton step was:\n');
disp(h);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -