GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
dpsifn.f
Go to the documentation of this file.
1*DECK DPSIFN
2 SUBROUTINE dpsifn (X, N, KODE, M, ANS, NZ, IERR)
3C***BEGIN PROLOGUE DPSIFN
4C***PURPOSE Compute derivatives of the Psi function.
5C***LIBRARY SLATEC
6C***CATEGORY C7C
7C***TYPE DOUBLE PRECISION (PSIFN-S, DPSIFN-D)
8C***KEYWORDS DERIVATIVES OF THE GAMMA FUNCTION, POLYGAMMA FUNCTION,
9C PSI FUNCTION
10C***AUTHOR Amos, D. E., (SNLA)
11C***DESCRIPTION
12C
13C The following definitions are used in DPSIFN:
14C
15C Definition 1
16C PSI(X) = d/dx (ln(GAMMA(X)), the first derivative of
17C the log GAMMA function.
18C Definition 2
19C K K
20C PSI(K,X) = d /dx (PSI(X)), the K-th derivative of PSI(X).
21C ___________________________________________________________________
22C DPSIFN computes a sequence of SCALED derivatives of
23C the PSI function; i.e. for fixed X and M it computes
24C the M-member sequence
25C
26C ((-1)**(K+1)/GAMMA(K+1))*PSI(K,X)
27C for K = N,...,N+M-1
28C
29C where PSI(K,X) is as defined above. For KODE=1, DPSIFN returns
30C the scaled derivatives as described. KODE=2 is operative only
31C when K=0 and in that case DPSIFN returns -PSI(X) + LN(X). That
32C is, the logarithmic behavior for large X is removed when KODE=2
33C and K=0. When sums or differences of PSI functions are computed
34C the logarithmic terms can be combined analytically and computed
35C separately to help retain significant digits.
36C
37C Note that CALL DPSIFN(X,0,1,1,ANS) results in
38C ANS = -PSI(X)
39C
40C Input X is DOUBLE PRECISION
41C X - Argument, X .gt. 0.0D0
42C N - First member of the sequence, 0 .le. N .le. 100
43C N=0 gives ANS(1) = -PSI(X) for KODE=1
44C -PSI(X)+LN(X) for KODE=2
45C KODE - Selection parameter
46C KODE=1 returns scaled derivatives of the PSI
47C function.
48C KODE=2 returns scaled derivatives of the PSI
49C function EXCEPT when N=0. In this case,
50C ANS(1) = -PSI(X) + LN(X) is returned.
51C M - Number of members of the sequence, M.ge.1
52C
53C Output ANS is DOUBLE PRECISION
54C ANS - A vector of length at least M whose first M
55C components contain the sequence of derivatives
56C scaled according to KODE.
57C NZ - Underflow flag
58C NZ.eq.0, A normal return
59C NZ.ne.0, Underflow, last NZ components of ANS are
60C set to zero, ANS(M-K+1)=0.0, K=1,...,NZ
61C IERR - Error flag
62C IERR=0, A normal return, computation completed
63C IERR=1, Input error, no computation
64C IERR=2, Overflow, X too small or N+M-1 too
65C large or both
66C IERR=3, Error, N too large. Dimensioned
67C array TRMR(NMAX) is not large enough for N
68C
69C The nominal computational accuracy is the maximum of unit
70C roundoff (=D1MACH(4)) and 1.0D-18 since critical constants
71C are given to only 18 digits.
72C
73C PSIFN is the single precision version of DPSIFN.
74C
75C *Long Description:
76C
77C The basic method of evaluation is the asymptotic expansion
78C for large X.ge.XMIN followed by backward recursion on a two
79C term recursion relation
80C
81C W(X+1) + X**(-N-1) = W(X).
82C
83C This is supplemented by a series
84C
85C SUM( (X+K)**(-N-1) , K=0,1,2,... )
86C
87C which converges rapidly for large N. Both XMIN and the
88C number of terms of the series are calculated from the unit
89C roundoff of the machine environment.
90C
91C***REFERENCES Handbook of Mathematical Functions, National Bureau
92C of Standards Applied Mathematics Series 55, edited
93C by M. Abramowitz and I. A. Stegun, equations 6.3.5,
94C 6.3.18, 6.4.6, 6.4.9 and 6.4.10, pp.258-260, 1964.
95C D. E. Amos, A portable Fortran subroutine for
96C derivatives of the Psi function, Algorithm 610, ACM
97C Transactions on Mathematical Software 9, 4 (1983),
98C pp. 494-502.
99C***ROUTINES CALLED D1MACH, I1MACH
100C***REVISION HISTORY (YYMMDD)
101C 820601 DATE WRITTEN
102C 890531 Changed all specific intrinsics to generic. (WRB)
103C 890911 Removed unnecessary intrinsics. (WRB)
104C 891006 Cosmetic changes to prologue. (WRB)
105C 891006 REVISION DATE from Version 3.2
106C 891214 Prologue converted to Version 4.0 format. (BAB)
107C 920501 Reformatted the REFERENCES section. (WRB)
108C***END PROLOGUE DPSIFN
109 INTEGER I, IERR, J, K, KODE, M, MM, MX, N, NMAX, NN, NP, NX, NZ,
110 * FN
111 INTEGER I1MACH
112 DOUBLE PRECISION ANS, ARG, B, DEN, ELIM, EPS, FLN,
113 * FX, RLN, RXSQ, R1M4, R1M5, S, SLOPE, T, TA, TK, TOL, TOLS, TRM,
114 * TRMR, TSS, TST, TT, T1, T2, WDTOL, X, XDMLN, XDMY, XINC, XLN,
115 * XM, XMIN, XQ, YINT
116 DOUBLE PRECISION D1MACH
117 dimension b(22), trm(22), trmr(100), ans(*)
118 SAVE nmax, b
119 DATA nmax /100/
120C-----------------------------------------------------------------------
121C BERNOULLI NUMBERS
122C-----------------------------------------------------------------------
123 DATA b(1), b(2), b(3), b(4), b(5), b(6), b(7), b(8), b(9), b(10),
124 * b(11), b(12), b(13), b(14), b(15), b(16), b(17), b(18), b(19),
125 * b(20), b(21), b(22) /1.00000000000000000d+00,
126 * -5.00000000000000000d-01,1.66666666666666667d-01,
127 * -3.33333333333333333d-02,2.38095238095238095d-02,
128 * -3.33333333333333333d-02,7.57575757575757576d-02,
129 * -2.53113553113553114d-01,1.16666666666666667d+00,
130 * -7.09215686274509804d+00,5.49711779448621554d+01,
131 * -5.29124242424242424d+02,6.19212318840579710d+03,
132 * -8.65802531135531136d+04,1.42551716666666667d+06,
133 * -2.72982310678160920d+07,6.01580873900642368d+08,
134 * -1.51163157670921569d+10,4.29614643061166667d+11,
135 * -1.37116552050883328d+13,4.88332318973593167d+14,
136 * -1.92965793419400681d+16/
137C
138C***FIRST EXECUTABLE STATEMENT DPSIFN
139 ierr = 0
140 nz=0
141 IF (x.LE.0.0d0) ierr=1
142 IF (n.LT.0) ierr=1
143 IF (kode.LT.1 .OR. kode.GT.2) ierr=1
144 IF (m.LT.1) ierr=1
145 IF (ierr.NE.0) RETURN
146 mm=m
147 nx = min(-i1mach(15),i1mach(16))
148 r1m5 = d1mach(5)
149 r1m4 = d1mach(4)*0.5d0
150 wdtol = max(r1m4,0.5d-18)
151C-----------------------------------------------------------------------
152C ELIM = APPROXIMATE EXPONENTIAL OVER AND UNDERFLOW LIMIT
153C-----------------------------------------------------------------------
154 elim = 2.302d0*(nx*r1m5-3.0d0)
155 xln = log(x)
156 41 CONTINUE
157 nn = n + mm - 1
158 fn = nn
159 t = (fn+1)*xln
160C-----------------------------------------------------------------------
161C OVERFLOW AND UNDERFLOW TEST FOR SMALL AND LARGE X
162C-----------------------------------------------------------------------
163 IF (abs(t).GT.elim) GO TO 290
164 IF (x.LT.wdtol) GO TO 260
165C-----------------------------------------------------------------------
166C COMPUTE XMIN AND THE NUMBER OF TERMS OF THE SERIES, FLN+1
167C-----------------------------------------------------------------------
168 rln = r1m5*i1mach(14)
169 rln = min(rln,18.06d0)
170 fln = max(rln,3.0d0) - 3.0d0
171 yint = 3.50d0 + 0.40d0*fln
172 slope = 0.21d0 + fln*(0.0006038d0*fln+0.008677d0)
173 xm = yint + slope*fn
174 mx = int(xm) + 1
175 xmin = mx
176 IF (n.EQ.0) GO TO 50
177 xm = -2.302d0*rln - min(0.0d0,xln)
178 arg = xm/n
179 arg = min(0.0d0,arg)
180 eps = exp(arg)
181 xm = 1.0d0 - eps
182 IF (abs(arg).LT.1.0d-3) xm = -arg
183 fln = x*xm/eps
184 xm = xmin - x
185 IF (xm.GT.7.0d0 .AND. fln.LT.15.0d0) GO TO 200
186 50 CONTINUE
187 xdmy = x
188 xdmln = xln
189 xinc = 0.0d0
190 IF (x.GE.xmin) GO TO 60
191 nx = int(x)
192 xinc = xmin - nx
193 xdmy = x + xinc
194 xdmln = log(xdmy)
195 60 CONTINUE
196C-----------------------------------------------------------------------
197C GENERATE W(N+MM-1,X) BY THE ASYMPTOTIC EXPANSION
198C-----------------------------------------------------------------------
199 t = fn*xdmln
200 t1 = xdmln + xdmln
201 t2 = t + xdmln
202 tk = max(abs(t),abs(t1),abs(t2))
203 IF (tk.GT.elim) GO TO 380
204 tss = exp(-t)
205 tt = 0.5d0/xdmy
206 t1 = tt
207 tst = wdtol*tt
208 IF (nn.NE.0) t1 = tt + 1.0d0/fn
209 rxsq = 1.0d0/(xdmy*xdmy)
210 ta = 0.5d0*rxsq
211 t = (fn+1)*ta
212 s = t*b(3)
213 IF (abs(s).LT.tst) GO TO 80
214 tk = 2.0d0
215 DO 70 k=4,22
216 t = t*((tk+fn+1)/(tk+1.0d0))*((tk+fn)/(tk+2.0d0))*rxsq
217 trm(k) = t*b(k)
218 IF (abs(trm(k)).LT.tst) GO TO 80
219 s = s + trm(k)
220 tk = tk + 2.0d0
221 70 CONTINUE
222 80 CONTINUE
223 s = (s+t1)*tss
224 IF (xinc.EQ.0.0d0) GO TO 100
225C-----------------------------------------------------------------------
226C BACKWARD RECUR FROM XDMY TO X
227C-----------------------------------------------------------------------
228 nx = int(xinc)
229 np = nn + 1
230 IF (nx.GT.nmax) GO TO 390
231 IF (nn.EQ.0) GO TO 160
232 xm = xinc - 1.0d0
233 fx = x + xm
234C-----------------------------------------------------------------------
235C THIS LOOP SHOULD NOT BE CHANGED. FX IS ACCURATE WHEN X IS SMALL
236C-----------------------------------------------------------------------
237 DO 90 i=1,nx
238 trmr(i) = fx**(-np)
239 s = s + trmr(i)
240 xm = xm - 1.0d0
241 fx = x + xm
242 90 CONTINUE
243 100 CONTINUE
244 ans(mm) = s
245 IF (fn.EQ.0) GO TO 180
246C-----------------------------------------------------------------------
247C GENERATE LOWER DERIVATIVES, J.LT.N+MM-1
248C-----------------------------------------------------------------------
249 IF (mm.EQ.1) RETURN
250 DO 150 j=2,mm
251 fn = fn - 1
252 tss = tss*xdmy
253 t1 = tt
254 IF (fn.NE.0) t1 = tt + 1.0d0/fn
255 t = (fn+1)*ta
256 s = t*b(3)
257 IF (abs(s).LT.tst) GO TO 120
258 tk = 4 + fn
259 DO 110 k=4,22
260 trm(k) = trm(k)*(fn+1)/tk
261 IF (abs(trm(k)).LT.tst) GO TO 120
262 s = s + trm(k)
263 tk = tk + 2.0d0
264 110 CONTINUE
265 120 CONTINUE
266 s = (s+t1)*tss
267 IF (xinc.EQ.0.0d0) GO TO 140
268 IF (fn.EQ.0) GO TO 160
269 xm = xinc - 1.0d0
270 fx = x + xm
271 DO 130 i=1,nx
272 trmr(i) = trmr(i)*fx
273 s = s + trmr(i)
274 xm = xm - 1.0d0
275 fx = x + xm
276 130 CONTINUE
277 140 CONTINUE
278 mx = mm - j + 1
279 ans(mx) = s
280 IF (fn.EQ.0) GO TO 180
281 150 CONTINUE
282 RETURN
283C-----------------------------------------------------------------------
284C RECURSION FOR N = 0
285C-----------------------------------------------------------------------
286 160 CONTINUE
287 DO 170 i=1,nx
288 s = s + 1.0d0/(x+nx-i)
289 170 CONTINUE
290 180 CONTINUE
291 IF (kode.EQ.2) GO TO 190
292 ans(1) = s - xdmln
293 RETURN
294 190 CONTINUE
295 IF (xdmy.EQ.x) RETURN
296 xq = xdmy/x
297 ans(1) = s - log(xq)
298 RETURN
299C-----------------------------------------------------------------------
300C COMPUTE BY SERIES (X+K)**(-(N+1)) , K=0,1,2,...
301C-----------------------------------------------------------------------
302 200 CONTINUE
303 nn = int(fln) + 1
304 np = n + 1
305 t1 = (n+1)*xln
306 t = exp(-t1)
307 s = t
308 den = x
309 DO 210 i=1,nn
310 den = den + 1.0d0
311 trm(i) = den**(-np)
312 s = s + trm(i)
313 210 CONTINUE
314 ans(1) = s
315 IF (n.NE.0) GO TO 220
316 IF (kode.EQ.2) ans(1) = s + xln
317 220 CONTINUE
318 IF (mm.EQ.1) RETURN
319C-----------------------------------------------------------------------
320C GENERATE HIGHER DERIVATIVES, J.GT.N
321C-----------------------------------------------------------------------
322 tol = wdtol/5.0d0
323 DO 250 j=2,mm
324 t = t/x
325 s = t
326 tols = t*tol
327 den = x
328 DO 230 i=1,nn
329 den = den + 1.0d0
330 trm(i) = trm(i)/den
331 s = s + trm(i)
332 IF (trm(i).LT.tols) GO TO 240
333 230 CONTINUE
334 240 CONTINUE
335 ans(j) = s
336 250 CONTINUE
337 RETURN
338C-----------------------------------------------------------------------
339C SMALL X.LT.UNIT ROUND OFF
340C-----------------------------------------------------------------------
341 260 CONTINUE
342 ans(1) = x**(-n-1)
343 IF (mm.EQ.1) GO TO 280
344 k = 1
345 DO 270 i=2,mm
346 ans(k+1) = ans(k)/x
347 k = k + 1
348 270 CONTINUE
349 280 CONTINUE
350 IF (n.NE.0) RETURN
351 IF (kode.EQ.2) ans(1) = ans(1) + xln
352 RETURN
353 290 CONTINUE
354 IF (t.GT.0.0d0) GO TO 380
355 nz=0
356 ierr=2
357 RETURN
358 380 CONTINUE
359 nz=nz+1
360 ans(mm)=0.0d0
361 mm=mm-1
362 IF (mm.EQ.0) RETURN
363 GO TO 41
364 390 CONTINUE
365 nz=0
366 ierr=3
367 RETURN
368 END
charNDArray max(char d, const charNDArray &m)
Definition chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition chNDArray.cc:207
subroutine dpsifn(x, n, kode, m, ans, nz, ierr)
Definition dpsifn.f:3