1* $Id$ 2c To get dgamma, "send dgamma from fnlib". 3c To get d1mach, mail netlib 4c send d1mach from core 5c 6 subroutine gaussq(kind, n, alpha, beta, kpts, endpts, b, t, w) 7c 8c this set of routines computes the nodes t(j) and weights 9c w(j) for gaussian-type quadrature rules with pre-assigned 10c nodes. these are used when one wishes to approximate 11c 12c integral (from a to b) f(x) w(x) dx 13c 14c n 15c by sum w f(t ) 16c j=1 j j 17c 18c (note w(x) and w(j) have no connection with each other.) 19c here w(x) is one of six possible non-negative weight 20c functions (listed below), and f(x) is the 21c function to be integrated. gaussian quadrature is particularly 22c useful on infinite intervals (with appropriate weight 23c functions), since then other techniques often fail. 24c 25c associated with each weight function w(x) is a set of 26c orthogonal polynomials. the nodes t(j) are just the zeroes 27c of the proper n-th degree polynomial. 28c 29c input parameters (all real numbers are in double precision) 30c 31c kind an integer between 1 and 6 giving the type of 32c quadrature rule: 33c 34c kind = 1: legendre quadrature, w(x) = 1 on (-1, 1) 35c kind = 2: chebyshev quadrature of the first kind 36c w(x) = 1/sqrt(1 - x*x) on (-1, +1) 37c kind = 3: chebyshev quadrature of the second kind 38c w(x) = sqrt(1 - x*x) on (-1, 1) 39c kind = 4: hermite quadrature, w(x) = exp(-x*x) on 40c (-infinity, +infinity) 41c kind = 5: jacobi quadrature, w(x) = (1-x)**alpha * (1+x)** 42c beta on (-1, 1), alpha, beta .gt. -1. 43c note: kind=2 and 3 are a special case of this. 44c kind = 6: generalized laguerre quadrature, w(x) = exp(-x)* 45c x**alpha on (0, +infinity), alpha .gt. -1 46c 47c n the number of points used for the quadrature rule 48c alpha real parameter used only for gauss-jacobi and gauss- 49c laguerre quadrature (otherwise use 0.d0). 50c beta real parameter used only for gauss-jacobi quadrature-- 51c (otherwise use 0.d0) 52c kpts (integer) normally 0, unless the left or right end- 53c point (or both) of the interval is required to be a 54c node (this is called gauss-radau or gauss-lobatto 55c quadrature). then kpts is the number of fixed 56c endpoints (1 or 2). 57c endpts real array of length 2. contains the values of 58c any fixed endpoints, if kpts = 1 or 2. 59c b real scratch array of length n 60c 61c output parameters (both double precision arrays of length n) 62c 63c t will contain the desired nodes. 64c w will contain the desired weights w(j). 65c 66c underflow may sometimes occur, but is harmless. 67c 68c references 69c 1. golub, g. h., and welsch, j. h., "calculation of gaussian 70c quadrature rules," mathematics of computation 23 (april, 71c 1969), pp. 221-230. 72c 2. golub, g. h., "some modified matrix eigenvalue problems," 73c siam review 15 (april, 1973), pp. 318-334 (section 7). 74c 3. stroud and secrest, gaussian quadrature formulas, prentice- 75c hall, englewood cliffs, n.j., 1966. 76c 77c original version 20 jan 1975 from stanford 78c modified 21 dec 1983 by eric grosse 79c imtql2 => gausq2 80c hex constant => d1mach (from core library) 81c compute pi using datan 82c removed accuracy claims, description of method 83c added single precision version 84c 85 double precision b(n), t(n), w(n), endpts(2), muzero, t1, 86 x gam, solve, dsqrt, alpha, beta 87c 88 call class (kind, n, alpha, beta, b, t, muzero) 89c 90c the matrix of coefficients is assumed to be symmetric. 91c the array t contains the diagonal elements, the array 92c b the off-diagonal elements. 93c make appropriate changes in the lower right 2 by 2 94c submatrix. 95c 96 if (kpts.eq.0) go to 100 97 if (kpts.eq.2) go to 50 98c 99c if kpts=1, only t(n) must be changed 100c 101 t(n) = solve(endpts(1), n, t, b)*b(n-1)**2 + endpts(1) 102 go to 100 103c 104c if kpts=2, t(n) and b(n-1) must be recomputed 105c 106 50 gam = solve(endpts(1), n, t, b) 107 t1 = ((endpts(1) - endpts(2))/(solve(endpts(2), n, t, b) - gam)) 108 b(n-1) = dsqrt(t1) 109 t(n) = endpts(1) + gam*t1 110c 111c note that the indices of the elements of b run from 1 to n-1 112c and thus the value of b(n) is arbitrary. 113c now compute the eigenvalues of the symmetric tridiagonal 114c matrix, which has been modified as necessary. 115c the method used is a ql-type method with origin shifting 116c 117 100 w(1) = 1.0d0 118 do 105 i = 2, n 119 105 w(i) = 0.0d0 120c 121 call gausq2 (n, t, b, w, ierr) 122 do 110 i = 1, n 123 110 w(i) = muzero * w(i) * w(i) 124c 125 return 126 end 127c 128c 129c 130 double precision function solve(shift, n, a, b) 131c 132c this procedure performs elimination to solve for the 133c n-th component of the solution delta to the equation 134c 135c (jn - shift*identity) * delta = en, 136c 137c where en is the vector of all zeroes except for 1 in 138c the n-th position. 139c 140c the matrix jn is symmetric tridiagonal, with diagonal 141c elements a(i), off-diagonal elements b(i). this equation 142c must be solved to obtain the appropriate changes in the lower 143c 2 by 2 submatrix of coefficients for orthogonal polynomials. 144c 145c 146 double precision shift, a(n), b(n), alpha 147c 148 alpha = a(1) - shift 149 nm1 = n - 1 150 do 10 i = 2, nm1 151 10 alpha = a(i) - shift - b(i-1)**2/alpha 152 solve = 1.0d0/alpha 153 return 154 end 155c 156c 157c 158 subroutine class(kind, n, alpha, beta, b, a, muzero) 159c 160c this procedure supplies the coefficients a(j), b(j) of the 161c recurrence relation 162c 163c b p (x) = (x - a ) p (x) - b p (x) 164c j j j j-1 j-1 j-2 165c 166c for the various classical (normalized) orthogonal polynomials, 167c and the zero-th moment 168c 169c muzero = integral w(x) dx 170c 171c of the given polynomial's weight function w(x). since the 172c polynomials are orthonormalized, the tridiagonal matrix is 173c guaranteed to be symmetric. 174c 175c the input parameter alpha is used only for laguerre and 176c jacobi polynomials, and the parameter beta is used only for 177c jacobi polynomials. the laguerre and jacobi polynomials 178c require the gamma function. 179c 180 double precision a(n), b(n), muzero, alpha, beta 181 double precision abi, a2b2, dgamma, pi, dsqrt, ab 182c 183 pi = 4.0d0 * datan(1.0d0) 184 nm1 = n - 1 185 go to (10, 20, 30, 40, 50, 60), kind 186c 187c kind = 1: legendre polynomials p(x) 188c on (-1, +1), w(x) = 1. 189c 190 10 muzero = 2.0d0 191 do 11 i = 1, nm1 192 a(i) = 0.0d0 193 abi = i 194 11 b(i) = abi/dsqrt(4*abi*abi - 1.0d0) 195 a(n) = 0.0d0 196 return 197c 198c kind = 2: chebyshev polynomials of the first kind t(x) 199c on (-1, +1), w(x) = 1 / sqrt(1 - x*x) 200c 201 20 muzero = pi 202 do 21 i = 1, nm1 203 a(i) = 0.0d0 204 21 b(i) = 0.5d0 205 b(1) = dsqrt(0.5d0) 206 a(n) = 0.0d0 207 return 208c 209c kind = 3: chebyshev polynomials of the second kind u(x) 210c on (-1, +1), w(x) = sqrt(1 - x*x) 211c 212 30 muzero = pi/2.0d0 213 do 31 i = 1, nm1 214 a(i) = 0.0d0 215 31 b(i) = 0.5d0 216 a(n) = 0.0d0 217 return 218c 219c kind = 4: hermite polynomials h(x) on (-infinity, 220c +infinity), w(x) = exp(-x**2) 221c 222 40 muzero = dsqrt(pi) 223 do 41 i = 1, nm1 224 a(i) = 0.0d0 225 41 b(i) = dsqrt(i/2.0d0) 226 a(n) = 0.0d0 227 return 228c 229c kind = 5: jacobi polynomials p(alpha, beta)(x) on 230c (-1, +1), w(x) = (1-x)**alpha + (1+x)**beta, alpha and 231c beta greater than -1 232c 233 50 ab = alpha + beta 234 abi = 2.0d0 + ab 235 muzero = 2.0d0 ** (ab + 1.0d0) * dgamma(alpha + 1.0d0) * dgamma( 236 x beta + 1.0d0) / dgamma(abi) 237 a(1) = (beta - alpha)/abi 238 b(1) = dsqrt(4.0d0*(1.0d0 + alpha)*(1.0d0 + beta)/((abi + 1.0d0)* 239 1 abi*abi)) 240 a2b2 = beta*beta - alpha*alpha 241 do 51 i = 2, nm1 242 abi = 2.0d0*i + ab 243 a(i) = a2b2/((abi - 2.0d0)*abi) 244 51 b(i) = dsqrt (4.0d0*i*(i + alpha)*(i + beta)*(i + ab)/ 245 1 ((abi*abi - 1)*abi*abi)) 246 abi = 2.0d0*n + ab 247 a(n) = a2b2/((abi - 2.0d0)*abi) 248 return 249c 250c kind = 6: laguerre polynomials l(alpha)(x) on 251c (0, +infinity), w(x) = exp(-x) * x**alpha, alpha greater 252c than -1. 253c 254 60 muzero = dgamma(alpha + 1.0d0) 255 do 61 i = 1, nm1 256 a(i) = 2.0d0*i - 1.0d0 + alpha 257 61 b(i) = dsqrt(i*(i + alpha)) 258 a(n) = 2.0d0*n - 1 + alpha 259 return 260 end 261c 262c 263 subroutine gausq2(n, d, e, z, ierr) 264c 265c this subroutine is a translation of an algol procedure, 266c num. math. 12, 377-383(1968) by martin and wilkinson, 267c as modified in num. math. 15, 450(1970) by dubrulle. 268c handbook for auto. comp., vol.ii-linear algebra, 241-248(1971). 269c this is a modified version of the 'eispack' routine imtql2. 270c 271c this subroutine finds the eigenvalues and first components of the 272c eigenvectors of a symmetric tridiagonal matrix by the implicit ql 273c method. 274c 275c on input: 276c 277c n is the order of the matrix; 278c 279c d contains the diagonal elements of the input matrix; 280c 281c e contains the subdiagonal elements of the input matrix 282c in its first n-1 positions. e(n) is arbitrary; 283c 284c z contains the first row of the identity matrix. 285c 286c on output: 287c 288c d contains the eigenvalues in ascending order. if an 289c error exit is made, the eigenvalues are correct but 290c unordered for indices 1, 2, ..., ierr-1; 291c 292c e has been destroyed; 293c 294c z contains the first components of the orthonormal eigenvectors 295c of the symmetric tridiagonal matrix. if an error exit is 296c made, z contains the eigenvectors associated with the stored 297c eigenvalues; 298c 299c ierr is set to 300c zero for normal return, 301c j if the j-th eigenvalue has not been 302c determined after 30 iterations. 303c 304c ------------------------------------------------------------------ 305c 306 integer i, j, k, l, m, n, ii, mml, ierr 307 real*8 d(n), e(n), z(n), b, c, f, g, p, r, s, machep 308 real*8 dsqrt, dabs, dsign, d1mach 309c 310 machep=d1mach(4) 311c 312 ierr = 0 313 if (n .eq. 1) go to 1001 314c 315 e(n) = 0.0d0 316 do 240 l = 1, n 317 j = 0 318c :::::::::: look for small sub-diagonal element :::::::::: 319 105 do 110 m = l, n 320 if (m .eq. n) go to 120 321 if (dabs(e(m)) .le. machep * (dabs(d(m)) + dabs(d(m+1)))) 322 x go to 120 323 110 continue 324c 325 120 p = d(l) 326 if (m .eq. l) go to 240 327 if (j .eq. 30) go to 1000 328 j = j + 1 329c :::::::::: form shift :::::::::: 330 g = (d(l+1) - p) / (2.0d0 * e(l)) 331 r = dsqrt(g*g+1.0d0) 332 g = d(m) - p + e(l) / (g + dsign(r, g)) 333 s = 1.0d0 334 c = 1.0d0 335 p = 0.0d0 336 mml = m - l 337c 338c :::::::::: for i=m-1 step -1 until l do -- :::::::::: 339 do 200 ii = 1, mml 340 i = m - ii 341 f = s * e(i) 342 b = c * e(i) 343 if (dabs(f) .lt. dabs(g)) go to 150 344 c = g / f 345 r = dsqrt(c*c+1.0d0) 346 e(i+1) = f * r 347 s = 1.0d0 / r 348 c = c * s 349 go to 160 350 150 s = f / g 351 r = dsqrt(s*s+1.0d0) 352 e(i+1) = g * r 353 c = 1.0d0 / r 354 s = s * c 355 160 g = d(i+1) - p 356 r = (d(i) - g) * s + 2.0d0 * c * b 357 p = s * r 358 d(i+1) = g + p 359 g = c * r - b 360c :::::::::: form first component of vector :::::::::: 361 f = z(i+1) 362 z(i+1) = s * z(i) + c * f 363 200 z(i) = c * z(i) - s * f 364c 365 d(l) = d(l) - p 366 e(l) = g 367 e(m) = 0.0d0 368 go to 105 369 240 continue 370c 371c :::::::::: order eigenvalues and eigenvectors :::::::::: 372 do 300 ii = 2, n 373 i = ii - 1 374 k = i 375 p = d(i) 376c 377 do 260 j = ii, n 378 if (d(j) .ge. p) go to 260 379 k = j 380 p = d(j) 381 260 continue 382c 383 if (k .eq. i) go to 300 384 d(k) = d(i) 385 d(i) = p 386 p = z(i) 387 z(i) = z(k) 388 z(k) = p 389 300 continue 390c 391 go to 1001 392c :::::::::: set error -- no convergence to an 393c eigenvalue after 30 iterations :::::::::: 394 1000 ierr = l 395 1001 return 396c :::::::::: last card of gausq2 :::::::::: 397 end 398 399*DECK DGAMMA 400 DOUBLE PRECISION FUNCTION DGAMMA (X) 401C***BEGIN PROLOGUE DGAMMA 402C***PURPOSE Compute the complete Gamma function. 403C***LIBRARY SLATEC (FNLIB) 404C***CATEGORY C7A 405C***TYPE DOUBLE PRECISION (GAMMA-S, DGAMMA-D, CGAMMA-C) 406C***KEYWORDS COMPLETE GAMMA FUNCTION, FNLIB, SPECIAL FUNCTIONS 407C***AUTHOR Fullerton, W., (LANL) 408C***DESCRIPTION 409C 410C DGAMMA(X) calculates the double precision complete Gamma function 411C for double precision argument X. 412C 413C Series for GAM on the interval 0. to 1.00000E+00 414C with weighted error 5.79E-32 415C log weighted error 31.24 416C significant figures required 30.00 417C decimal places required 32.05 418C 419C***REFERENCES (NONE) 420C***ROUTINES CALLED D1MACH, D9LGMC, DCSEVL, DGAMLM, INITDS, XERMSG 421C***REVISION HISTORY (YYMMDD) 422C 770601 DATE WRITTEN 423C 890531 Changed all specific intrinsics to generic. (WRB) 424C 890911 Removed unnecessary intrinsics. (WRB) 425C 890911 REVISION DATE from Version 3.2 426C 891214 Prologue converted to Version 4.0 format. (BAB) 427C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) 428C 920618 Removed space from variable name. (RWC, WRB) 429C***END PROLOGUE DGAMMA 430 DOUBLE PRECISION X, GAMCS(42), DXREL, PI, SINPIY, SQ2PIL, XMAX, 431 1 XMIN, Y, D9LGMC, DCSEVL, D1MACH 432 LOGICAL FIRST 433C 434 SAVE GAMCS, PI, SQ2PIL, NGAM, XMIN, XMAX, DXREL, FIRST 435 DATA GAMCS( 1) / +.8571195590 9893314219 2006239994 2 D-2 / 436 DATA GAMCS( 2) / +.4415381324 8410067571 9131577165 2 D-2 / 437 DATA GAMCS( 3) / +.5685043681 5993633786 3266458878 9 D-1 / 438 DATA GAMCS( 4) / -.4219835396 4185605010 1250018662 4 D-2 / 439 DATA GAMCS( 5) / +.1326808181 2124602205 8400679635 2 D-2 / 440 DATA GAMCS( 6) / -.1893024529 7988804325 2394702388 6 D-3 / 441 DATA GAMCS( 7) / +.3606925327 4412452565 7808221722 5 D-4 / 442 DATA GAMCS( 8) / -.6056761904 4608642184 8554829036 5 D-5 / 443 DATA GAMCS( 9) / +.1055829546 3022833447 3182350909 3 D-5 / 444 DATA GAMCS( 10) / -.1811967365 5423840482 9185589116 6 D-6 / 445 DATA GAMCS( 11) / +.3117724964 7153222777 9025459316 9 D-7 / 446 DATA GAMCS( 12) / -.5354219639 0196871408 7408102434 7 D-8 / 447 DATA GAMCS( 13) / +.9193275519 8595889468 8778682594 0 D-9 / 448 DATA GAMCS( 14) / -.1577941280 2883397617 6742327395 3 D-9 / 449 DATA GAMCS( 15) / +.2707980622 9349545432 6654043308 9 D-10 / 450 DATA GAMCS( 16) / -.4646818653 8257301440 8166105893 3 D-11 / 451 DATA GAMCS( 17) / +.7973350192 0074196564 6076717535 9 D-12 / 452 DATA GAMCS( 18) / -.1368078209 8309160257 9949917230 9 D-12 / 453 DATA GAMCS( 19) / +.2347319486 5638006572 3347177168 8 D-13 / 454 DATA GAMCS( 20) / -.4027432614 9490669327 6657053469 9 D-14 / 455 DATA GAMCS( 21) / +.6910051747 3721009121 3833697525 7 D-15 / 456 DATA GAMCS( 22) / -.1185584500 2219929070 5238712619 2 D-15 / 457 DATA GAMCS( 23) / +.2034148542 4963739552 0102605193 2 D-16 / 458 DATA GAMCS( 24) / -.3490054341 7174058492 7401294910 8 D-17 / 459 DATA GAMCS( 25) / +.5987993856 4853055671 3505106602 6 D-18 / 460 DATA GAMCS( 26) / -.1027378057 8722280744 9006977843 1 D-18 / 461 DATA GAMCS( 27) / +.1762702816 0605298249 4275966074 8 D-19 / 462 DATA GAMCS( 28) / -.3024320653 7353062609 5877211204 2 D-20 / 463 DATA GAMCS( 29) / +.5188914660 2183978397 1783355050 6 D-21 / 464 DATA GAMCS( 30) / -.8902770842 4565766924 4925160106 6 D-22 / 465 DATA GAMCS( 31) / +.1527474068 4933426022 7459689130 6 D-22 / 466 DATA GAMCS( 32) / -.2620731256 1873629002 5732833279 9 D-23 / 467 DATA GAMCS( 33) / +.4496464047 8305386703 3104657066 6 D-24 / 468 DATA GAMCS( 34) / -.7714712731 3368779117 0390152533 3 D-25 / 469 DATA GAMCS( 35) / +.1323635453 1260440364 8657271466 6 D-25 / 470 DATA GAMCS( 36) / -.2270999412 9429288167 0231381333 3 D-26 / 471 DATA GAMCS( 37) / +.3896418998 0039914493 2081663999 9 D-27 / 472 DATA GAMCS( 38) / -.6685198115 1259533277 9212799999 9 D-28 / 473 DATA GAMCS( 39) / +.1146998663 1400243843 4761386666 6 D-28 / 474 DATA GAMCS( 40) / -.1967938586 3451346772 9510399999 9 D-29 / 475 DATA GAMCS( 41) / +.3376448816 5853380903 3489066666 6 D-30 / 476 DATA GAMCS( 42) / -.5793070335 7821357846 2549333333 3 D-31 / 477 DATA PI / 3.1415926535 8979323846 2643383279 50 D0 / 478 DATA SQ2PIL / 0.9189385332 0467274178 0329736405 62 D0 / 479 DATA FIRST /.TRUE./ 480C***FIRST EXECUTABLE STATEMENT DGAMMA 481 IF (FIRST) THEN 482 NGAM = INITDS (GAMCS, 42, 0.1*REAL(D1MACH(3)) ) 483C 484 CALL DGAMLM (XMIN, XMAX) 485 DXREL = SQRT(D1MACH(4)) 486 ENDIF 487 FIRST = .FALSE. 488C 489 Y = ABS(X) 490 IF (Y.GT.10.D0) GO TO 50 491C 492C COMPUTE GAMMA(X) FOR -XBND .LE. X .LE. XBND. REDUCE INTERVAL AND FIND 493C GAMMA(1+Y) FOR 0.0 .LE. Y .LT. 1.0 FIRST OF ALL. 494C 495 N = X 496 IF (X.LT.0.D0) N = N - 1 497 Y = X - N 498 N = N - 1 499 DGAMMA = 0.9375D0 + DCSEVL (2.D0*Y-1.D0, GAMCS, NGAM) 500 IF (N.EQ.0) RETURN 501C 502 IF (N.GT.0) GO TO 30 503C 504C COMPUTE GAMMA(X) FOR X .LT. 1.0 505C 506 N = -N 507 IF (X .EQ. 0.D0) CALL XERMSG ('SLATEC', 'DGAMMA', 'X IS 0', 4, 2) 508 IF (X .LT. 0.0 .AND. X+N-2 .EQ. 0.D0) CALL XERMSG ('SLATEC', 509 + 'DGAMMA', 'X IS A NEGATIVE INTEGER', 4, 2) 510 IF (X .LT. (-0.5D0) .AND. ABS((X-AINT(X-0.5D0))/X) .LT. DXREL) 511 + CALL XERMSG ('SLATEC', 'DGAMMA', 512 + 'ANSWER LT HALF PRECISION BECAUSE X TOO NEAR NEGATIVE INTEGER', 513 + 1, 1) 514C 515 DO 20 I=1,N 516 DGAMMA = DGAMMA/(X+I-1 ) 517 20 CONTINUE 518 RETURN 519C 520C GAMMA(X) FOR X .GE. 2.0 AND X .LE. 10.0 521C 522 30 DO 40 I=1,N 523 DGAMMA = (Y+I) * DGAMMA 524 40 CONTINUE 525 RETURN 526C 527C GAMMA(X) FOR ABS(X) .GT. 10.0. RECALL Y = ABS(X). 528C 529 50 IF (X .GT. XMAX) CALL XERMSG ('SLATEC', 'DGAMMA', 530 + 'X SO BIG GAMMA OVERFLOWS', 3, 2) 531C 532 DGAMMA = 0.D0 533 IF (X .LT. XMIN) CALL XERMSG ('SLATEC', 'DGAMMA', 534 + 'X SO SMALL GAMMA UNDERFLOWS', 2, 1) 535 IF (X.LT.XMIN) RETURN 536C 537 DGAMMA = EXP ((Y-0.5D0)*LOG(Y) - Y + SQ2PIL + D9LGMC(Y) ) 538 IF (X.GT.0.D0) RETURN 539C 540 IF (ABS((X-AINT(X-0.5D0))/X) .LT. DXREL) CALL XERMSG ('SLATEC', 541 + 'DGAMMA', 542 + 'ANSWER LT HALF PRECISION, X TOO NEAR NEGATIVE INTEGER', 1, 1) 543C 544 SINPIY = SIN (PI*Y) 545 IF (SINPIY .EQ. 0.D0) CALL XERMSG ('SLATEC', 'DGAMMA', 546 + 'X IS A NEGATIVE INTEGER', 4, 2) 547C 548 DGAMMA = -PI/(Y*SINPIY*DGAMMA) 549C 550 RETURN 551 END 552 553