source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/lightspeed/digamma.m @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

  • Property svn:executable set to *
File size: 1.9 KB
Line 
1function y = digamma(x)
2%DIGAMMA   Digamma function.
3% DIGAMMA(X) returns digamma(x) = d log(gamma(x)) / dx
4% If X is a matrix, returns the digamma function evaluated at each element.
5
6% Reference:
7%
8%    J Bernardo,
9%    Psi ( Digamma ) Function,
10%    Algorithm AS 103,
11%    Applied Statistics,
12%    Volume 25, Number 3, pages 315-317, 1976.
13%
14% From http://www.psc.edu/~burkardt/src/dirichlet/dirichlet.f
15
16large = 9.5;
17d1 = -0.5772156649015328606065121;  % digamma(1)
18d2 = pi^2/6;
19small = 1e-6;
20s3 = 1/12;
21s4 = 1/120;
22s5 = 1/252;
23s6 = 1/240;
24s7 = 1/132;
25s8 = 691/32760;
26s9 = 1/12;
27s10 = 3617/8160;
28
29% Initialize
30y = zeros(size(x));
31
32% illegal arguments
33i = find(x == -Inf | isnan(x));
34if ~isempty(i)
35  x(i) = NaN;
36  y(i) = NaN;
37end
38
39% Negative values
40i = find(x < 0);
41if ~isempty(i)
42  % Use the reflection formula (Jeffrey 11.1.6):
43  % digamma(-x) = digamma(x+1) + pi*cot(pi*x)
44  y(i) = digamma(-x(i)+1) + pi*cot(-pi*x(i));
45  % This is related to the identity
46  % digamma(-x) = digamma(x+1) - digamma(z) + digamma(1-z)
47  % where z is the fractional part of x
48  % For example:
49  % digamma(-3.1) = 1/3.1 + 1/2.1 + 1/1.1 + 1/0.1 + digamma(1-0.1)
50  %               = digamma(4.1) - digamma(0.1) + digamma(1-0.1)
51  % Then we use
52  % digamma(1-z) - digamma(z) = pi*cot(pi*z)
53end
54 
55i = find(x == 0);
56if ~isempty(i)
57  y(i) = -Inf;
58end
59
60%  Use approximation if argument <= small.
61i = find(x > 0 & x <= small);
62if ~isempty(i)
63  y(i) = y(i) + d1 - 1 ./ x(i) + d2*x(i);
64end
65
66%  Reduce to digamma(X + N) where (X + N) >= large.
67while(1)
68  i = find(x > small & x < large);
69  if isempty(i)
70    break
71  end
72  y(i) = y(i) - 1 ./ x(i);
73  x(i) = x(i) + 1;
74end
75
76%  Use de Moivre's expansion if argument >= large.
77% In maple: asympt(Psi(x), x);
78i = find(x >= large);
79if ~isempty(i)
80  r = 1 ./ x(i);
81  y(i) = y(i) + log(x(i)) - 0.5 * r;
82  r = r .* r;
83  y(i) = y(i) - r .* ( s3 - r .* ( s4 - r .* (s5 - r .* (s6 - r .* s7))));
84end
Note: See TracBrowser for help on using the repository browser.