spm_Ipdf.m 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. function f = spm_Ipdf(x,n,p)
  2. % Probability Distribution Function of Binomial distribution
  3. % FORMAT f = spm_Ipdf(x,n,p)
  4. %
  5. % x - ordinates
  6. % n - Binomial n
  7. % p - Binomial p [Defaults to 0.5]
  8. % f - PDF
  9. %__________________________________________________________________________
  10. %
  11. % spm_Ipdf returns the Probability (Distribution) Function (PDF) for
  12. % the Binomial family of distributions.
  13. %
  14. % Definition:
  15. %--------------------------------------------------------------------------
  16. % The Bin(n,p) distribution is the distribution of the number of
  17. % successes from n identical independent Bernoulli trials each with
  18. % success probability p. If random variable X is the number of
  19. % successes from such a set of Bernoulli trials, then the PDF f(x) is
  20. % Pr{X=x}, defined for whole n (i.e. non-negative integer n) and
  21. % p in [0,1], given by: (See Evans et al., Ch6)
  22. %
  23. % { nCx * p^x * (1-p)^(n-x) for x=0,1,...,n
  24. % f(x) = |
  25. % { 0 otherwise
  26. %
  27. % where nCx is the Binomial coefficient "n-choose-x", given by n!/(x!(n-x)!).
  28. %
  29. % Algorithm:
  30. %--------------------------------------------------------------------------
  31. % For vary small n, nCx can be computed naively as the ratio of
  32. % factorials, using gamma(n+1) to return n!. For moderately sized n, n!
  33. % (& x! &/or (n-x)!) become very large, and naive computation isn't
  34. % possible. Direct computation is always possible upon noting that the
  35. % expression cancels down to the product of x fractions:
  36. %
  37. % n! n n-1 n-(x-1)
  38. % --------- = - x --- x ... x -------
  39. % n! (n-x)! x x-1 1
  40. %
  41. % Unfortunately this cunning computation (given at the end of this
  42. % function) is difficult to vectorise. Therefore we compute via the log
  43. % of nCx as e^(ln(n!)-ln(x!)-ln((n-x)!), using the special function
  44. % gammaln:
  45. %
  46. % nCx = exp( gammaln(n+1) - gammaln(x+1) - gammaln(n-x+1) )
  47. %
  48. % The result is rounded to cope with roundoff error for smaller values
  49. % of n & x. See Press et al., Sec6.1 for further details.
  50. %
  51. % References:
  52. %--------------------------------------------------------------------------
  53. % Evans M, Hastings N, Peacock B (1993)
  54. % "Statistical Distributions"
  55. % 2nd Ed. Wiley, New York
  56. %
  57. % Abramowitz M, Stegun IA, (1964)
  58. % "Handbook of Mathematical Functions"
  59. % US Government Printing Office
  60. %
  61. % Press WH, Teukolsky SA, Vetterling AT, Flannery BP (1992)
  62. % "Numerical Recipes in C"
  63. % Cambridge
  64. %
  65. %__________________________________________________________________________
  66. % Copyright (C) 1999-2011 Wellcome Trust Centre for Neuroimaging
  67. % Andrew Holmes
  68. % $Id: spm_Ipdf.m 4182 2011-02-01 12:29:09Z guillaume $
  69. %-Format arguments, note & check sizes
  70. %--------------------------------------------------------------------------
  71. if nargin<3, p=0.5; end
  72. if nargin<2, error('Insufficient arguments'), end
  73. ad = [ndims(x);ndims(n);ndims(p)];
  74. rd = max(ad);
  75. as = [[size(x),ones(1,rd-ad(1))];...
  76. [size(n),ones(1,rd-ad(2))];...
  77. [size(p),ones(1,rd-ad(3))]];
  78. rs = max(as);
  79. xa = prod(as,2)>1;
  80. if sum(xa)>1 && any(any(diff(as(xa,:)),1))
  81. error('non-scalar args must match in size');
  82. end
  83. %-Computation
  84. %--------------------------------------------------------------------------
  85. %-Initialise result to zeros
  86. f = zeros(rs);
  87. %-Only defined for whole n, and for p in [0,1]. Return NaN if undefined.
  88. md = ( ones(size(x)) & n==floor(n) & n>=0 & p>=0 & p<=1 );
  89. if any(~md(:))
  90. f(~md) = NaN;
  91. warning('Returning NaN for out of range arguments');
  92. end
  93. %-Non-zero only where defined and x is whole with 0<=x<=n
  94. Q = find( md & x==floor(x) & n>=x & x>=0 );
  95. if isempty(Q), return, end
  96. if xa(1), Qx=Q; else Qx=1; end
  97. if xa(2), Qn=Q; else Qn=1; end
  98. if xa(3), Qp=Q; else Qp=1; end
  99. %-Compute
  100. f(Q) = round(exp(gammaln(n(Qn)+1) -gammaln(x(Qx)+1) - gammaln(n(Qn)-x(Qx)+1)));
  101. f(Q) = f(Q).* p(Qp).^x(Qx) .* (1-p(Qp)).^(n(Qn)-x(Qx));
  102. %-Return
  103. %--------------------------------------------------------------------------
  104. return
  105. %==========================================================================
  106. %-Direct computation method: (For interest)
  107. %==========================================================================
  108. % The following cunning direct computation is faster than using log
  109. % gammas, but is rather difficult to vectorise.
  110. %q=1-p;
  111. %if r<n/2
  112. % %-better for small r (less terms) / small p (smaller numbers)
  113. % %----------------------------------------------------------------------
  114. % f=prod([[n:-1:n-r+1]*p,1]./[r:-1:1,1])*q^(n-r);
  115. %else
  116. % %-better for large r (less terms) / small q (smaller numbers)
  117. % %----------------------------------------------------------------------
  118. % f=prod([[n:-1:r+1]*q,1]./[n-r:-1:1,1])*p^r;
  119. %end