changeset 11269:628b03328765

improve range of betapdf function
author Christos Dimitrakakis <christos.dimitrakakis@gmail.com>
date Thu, 18 Nov 2010 14:38:29 -0500
parents 1ddf64be9cbd
children 5dd8e80fb6c1
files scripts/ChangeLog scripts/statistics/distributions/betapdf.m
diffstat 2 files changed, 48 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,9 @@
+2010-11-18  Christos Dimitrakakis  <christos.dimitrakakis@gmail.com>
+
+	* statistics/distributions/betapdf.m: Use lgamma to compute
+	normalising constant in log space in order to handle large
+	parameters a and b.  Ensure correct values at x == 0 or x == 1.
+
 2010-11-18  Ben Abbott <bpabbott@mac.com>
 
 	* plot/__print_parse_opts__.m: For tests, allow __print_parse_opts__
--- a/scripts/statistics/distributions/betapdf.m
+++ b/scripts/statistics/distributions/betapdf.m
@@ -1,4 +1,5 @@
 ## Copyright (C) 1995, 1996, 1997, 2005, 2006, 2007 Kurt Hornik
+## Copyright (C) 2010 Christos Dimitrakakis
 ##
 ## This file is part of Octave.
 ##
@@ -22,7 +23,7 @@
 ## distribution with parameters @var{a} and @var{b}.
 ## @end deftypefn
 
-## Author: KH <Kurt.Hornik@wu-wien.ac.at>
+## Author: KH <Kurt.Hornik@wu-wien.ac.at>, CD <christos.dimitrakakis@gmail.com>
 ## Description: PDF of the Beta distribution
 
 function pdf = betapdf (x, a, b)
@@ -46,15 +47,52 @@
     pdf (k) = NaN;
   endif
 
-  k = find ((x > 0) & (x < 1) & (a > 0) & (b > 0));
+  k = find ((x > 0) & (x < 1) & (a > 0) & (b > 0) & ((a != 1) | (b != 1)));
   if (any (k))
     if (isscalar(a) && isscalar(b))
       pdf(k) = exp ((a - 1) .* log (x(k))
-                    + (b - 1) .* log (1 - x(k))) ./ beta (a, b);
+		            + (b - 1) .* log (1 - x(k))
+                    + lgamma(a + b) - lgamma(a) - lgamma(b));
     else
       pdf(k) = exp ((a(k) - 1) .* log (x(k))
-                    + (b(k) - 1) .* log (1 - x(k))) ./ beta (a(k), b(k));
+		            + (b(k) - 1) .* log (1 - x(k))
+                    + lgamma(a(k) + b(k)) - lgamma(a(k)) - lgamma(b(k)));
+    endif
+  endif
+
+  ## Most important special cases when the density is finite.
+  k = find ((x == 0) & (a == 1) & (b > 0) & (b != 1));
+  if (any (k))
+    if (isscalar(a) && isscalar(b))
+      pdf(k) = exp(lgamma(a + b) - lgamma(a) - lgamma(b));
+    else
+      pdf(k) = exp(lgamma(a(k) + b(k)) - lgamma(a(k)) - lgamma(b(k)));
     endif
   endif
 
+  k = find ((x == 1) & (b == 1) & (a > 0) & (a != 1));
+  if (any (k))
+    if (isscalar(a) && isscalar(b))
+      pdf(k) = exp(lgamma(a + b) - lgamma(a) - lgamma(b));
+    else
+      pdf(k) = exp(lgamma(a(k) + b(k)) - lgamma(a(k)) - lgamma(b(k)));
+    endif
+  endif
+
+  k = find ((x >= 0) & (x <= 1) & (a == 1) & (b == 1));
+  if (any (k))
+    pdf(k) = 1;
+  endif
+
+  ## Other special case when the density at the boundary is infinite.
+  k = find ((x == 0) & (a < 1));
+  if (any (k))
+    pdf(k) = Inf;
+  endif
+
+  k = find ((x == 1) & (b < 1));
+  if (any (k))
+    pdf(k) = Inf;
+  endif
+
 endfunction