function p = nctcdf(x,nu,delta)
%NCTCDF Noncentral T cumulative distribution function (cdf).
%   P = NCTCDF(X,NU,DELTA) Returns the noncentral T cdf with NU 
%   degrees of freedom and noncentrality parameter, DELTA, at the values 
%   in X.
%
%   The size of Y is the common size of the input arguments. A scalar input  
%   functions as a constant matrix of the same size as the other inputs.     

%   References:
%      [1]  Johnson, Norman, and Kotz, Samuel, "Distributions in
%      Statistics: Continuous Univariate Distributions-2", Wiley
%      1970 p. 205.
%      [2]  Evans, Merran, Hastings, Nicholas and Peacock, Brian,
%      "Statistical Distributions, Second Edition", Wiley
%      1993 pp. 147-148.

%   B.A. Jones 8-22-94
%   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 x nu delta] = distchck(3,x,nu,delta);

if errorcode > 0
    error('Requires non-scalar arguments to match in size.');
end

% Initialize P to zero.
[m,n] = size(x);
p = zeros(m,n);

% Probability that x < 0
p0 = normcdf(-delta,0,1);

kneg = find(x < 0);
kzero = find(x == 0);
kpos = 1:m*n;
kpos([kneg(:); kzero(:)]) = [];

%Value passed to Incomplete Beta function.
tmp = (x.^2)./(nu+x.^2);

% Set up for infinite sum.
done = 0;
j = 0;
jk9  = zeros(size(x));
jk10 = zeros(size(x));
eterm = exp(-0.5*delta.^2);

% Sum the series.
while ~done
   %Compute Incomplete Beta function values.
   k0      = (find(x~=0));
   if any(k0)
      ibeta9  = zeros(size(x));
      ibeta9(k0)  = betainc(tmp(k0),(j+1)/2,nu(k0)/2);    % Johnson & Kotz eqn. 9
      ibeta10 = zeros(size(x));
      ibeta10(k0) = betainc(tmp(k0),(j+1/2),nu(k0)/2);    % Johnson & Kotz eqn. 10

      %Probability that t lies between 0 and x (x>0)
      nt9   = (exp(0.5*j*log(0.5*delta.^2) - gammaln(j/2+1))).*ibeta9;
      jk9   = jk9 + nt9;
      %Probability that t lies between x and -x.
      nt10  = (exp(j*log(0.5*delta.^2) - gammaln(j+1))).*ibeta10;
      jk10  = jk10 + nt10; 
   
      % Convergence test.
      if all((nt9(k0)./(jk9(k0)+(eps^(1/4)))) < sqrt(eps)) ...
      & all((nt10(k0)./(jk10(k0)+(eps^(1/4)))) < sqrt(eps))
         done = 1;
      end
      j = j + 1;
   else
      done = 1;
   end
end

% Compute probability for non-negative Xs.
p = p0 + eterm.*jk9/2;

% Compute probability for negative Xs. P(t < 0) + P(0 < t < |x|) - P(-|x| < t < |x|)
p(kneg) = p(kneg) - eterm(kneg).*jk10(kneg);


% Return NaN if X is negative or NU is not a positive integer.
k1 = find(nu <= 0 | round(nu) ~= nu);
if any(k1)
    tmp   = NaN 
    p(k1) = tmp(ones(size(k1)));
end
