home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l460 / 2.ddi / SPECFUN.DI$ / GAMMALN.M < prev    next >
Encoding:
Text File  |  1993-03-07  |  4.8 KB  |  154 lines

  1. function res = gammaln(x)
  2. %GAMMALN The loggamma function.
  3. %    Y = GAMMALN(X) is LOG(GAMMA(X)), avoiding underflow and overflow.
  4. %    See also GAMMA.
  5.  
  6. %    C. Moler, 2-1-91.
  7. %    Copyright (c) 1984-93 by The MathWorks, Inc.
  8.  
  9. %   This is based on a FORTRAN program by W. J. Cody,
  10. %   Argonne National Laboratory, NETLIB/SPECFUN, June 16, 1988.
  11. %
  12. % References:
  13. %
  14. %  1) W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for
  15. %     the Natural Logarithm of the Gamma Function,' Math. Comp. 21,
  16. %     1967, pp. 198-203.
  17. %
  18. %  2) K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May,
  19. %     1969.
  20. %  3) Hart, Et. Al., Computer Approximations, Wiley and sons, New
  21. %     York, 1968.
  22. %
  23.  
  24.      d1 = -5.772156649015328605195174e-1;
  25.      p1 = [4.945235359296727046734888e0; 2.018112620856775083915565e2; 
  26.            2.290838373831346393026739e3; 1.131967205903380828685045e4; 
  27.            2.855724635671635335736389e4; 3.848496228443793359990269e4; 
  28.            2.637748787624195437963534e4; 7.225813979700288197698961e3];
  29.      q1 = [6.748212550303777196073036e1; 1.113332393857199323513008e3; 
  30.            7.738757056935398733233834e3; 2.763987074403340708898585e4; 
  31.            5.499310206226157329794414e4; 6.161122180066002127833352e4; 
  32.            3.635127591501940507276287e4; 8.785536302431013170870835e3];
  33.      d2 = 4.227843350984671393993777e-1;
  34.      p2 = [4.974607845568932035012064e0; 5.424138599891070494101986e2; 
  35.            1.550693864978364947665077e4; 1.847932904445632425417223e5; 
  36.            1.088204769468828767498470e6; 3.338152967987029735917223e6; 
  37.            5.106661678927352456275255e6; 3.074109054850539556250927e6];
  38.      q2 = [1.830328399370592604055942e2; 7.765049321445005871323047e3; 
  39.            1.331903827966074194402448e5; 1.136705821321969608938755e6; 
  40.            5.267964117437946917577538e6; 1.346701454311101692290052e7; 
  41.            1.782736530353274213975932e7; 9.533095591844353613395747e6];
  42.      d4 = 1.791759469228055000094023e0;
  43.      p4 = [1.474502166059939948905062e4; 2.426813369486704502836312e6; 
  44.            1.214755574045093227939592e8; 2.663432449630976949898078e9; 
  45.            2.940378956634553899906876e10; 1.702665737765398868392998e11; 
  46.            4.926125793377430887588120e11; 5.606251856223951465078242e11];
  47.      q4 = [2.690530175870899333379843e3; 6.393885654300092398984238e5; 
  48.            4.135599930241388052042842e7; 1.120872109616147941376570e9; 
  49.            1.488613728678813811542398e10; 1.016803586272438228077304e11; 
  50.            3.417476345507377132798597e11; 4.463158187419713286462081e11];
  51.      c = [-1.910444077728e-03; 8.4171387781295e-04; 
  52.           -5.952379913043012e-04; 7.93650793500350248e-04; 
  53.           -2.777777777777681622553e-03; 8.333333333333333331554247e-02; 
  54.            5.7083835261e-03];
  55.  
  56.    if any((imag(x) ~= 0) | (x < 0))
  57.       error('Input arguments must be real and nonnegative.')
  58.    end
  59.    res = x;
  60. %
  61. %  0 <= x <= eps
  62. %
  63.    k = find(x <= eps);
  64.    if any(k)
  65.       res(k) = -log(x(k));
  66.    end
  67. %
  68. %  eps < x <= 0.5
  69. %
  70.    k = find((x > eps) & (x <= 0.5));
  71.    if any(k)
  72.       y = x(k);
  73.       xden = ones(size(k));
  74.       xnum = 0;
  75.       for i = 1:8
  76.          xnum = xnum .* y + p1(i);
  77.          xden = xden .* y + q1(i);
  78.       end
  79.       res(k) = -log(y) + (y .* (d1 + y .* (xnum ./ xden)));
  80.    end
  81. %
  82. %  0.5 < x <= 0.6796875
  83. %
  84.    k = find((x > 0.5) & (x <= 0.6796875));
  85.    if any(k)
  86.       xm1 = (x(k) - 0.5) - 0.5;
  87.       xden = ones(size(k));
  88.       xnum = 0;
  89.       for i = 1:8
  90.          xnum = xnum .* xm1 + p2(i);
  91.          xden = xden .* xm1 + q2(i);
  92.       end
  93.       res(k) = -log(x(k)) + xm1 .* (d2 + xm1 .* (xnum ./ xden));
  94.    end
  95. %
  96. %  0.6796875 < x <= 1.5
  97. %
  98.    k = find((x > 0.6796875) & (x <= 1.5));
  99.    if any(k)
  100.       xm1 = (x(k) - 0.5) - 0.5;
  101.       xden = ones(size(k));
  102.       xnum = 0;
  103.       for i = 1:8
  104.          xnum = xnum .* xm1 + p1(i);
  105.          xden = xden .* xm1 + q1(i);
  106.       end
  107.       res(k) = xm1 .* (d1 + xm1 .* (xnum ./ xden));
  108.    end
  109. %
  110. %  1.5 < x <= 4
  111. %
  112.    k = find((x > 1.5) & (x <= 4));
  113.    if any(k)
  114.       xm2 = x(k) - 2;
  115.       xden = ones(size(k));
  116.       xnum = 0;
  117.       for i = 1:8
  118.          xnum = xnum .* xm2 + p2(i);
  119.          xden = xden .* xm2 + q2(i);
  120.       end
  121.       res(k) = xm2 .* (d2 + xm2 .* (xnum ./ xden));
  122.    end
  123. %
  124. %  4 < x <= 12
  125. %
  126.    k = find((x > 4) & (x <= 12));
  127.    if any(k)
  128.       xm4 = x(k) - 4;
  129.       xden = -ones(size(k));
  130.       xnum = 0;
  131.       for i = 1:8
  132.          xnum = xnum .* xm4 + p4(i);
  133.          xden = xden .* xm4 + q4(i);
  134.       end
  135.       res(k) = d4 + xm4 .* (xnum ./ xden);
  136.    end
  137. %
  138. %  x > 12
  139. %
  140.    k = find(x > 12);
  141.    if any(k)
  142.       y = x(k);
  143.       r = c(7)*ones(size(k));
  144.       ysq = y .* y;
  145.       for i = 1:6
  146.          r = r ./ ysq + c(i);
  147.       end
  148.       r = r ./ y;
  149.       corr = log(y);
  150.       spi = 0.9189385332046727417803297;
  151.       res(k) = r + spi - 0.5*corr + y .* (corr-1);
  152.    end
  153.