Skip to content

Commit 8fc718f

Browse files
make pFqdrummond more efficient
specify that U uses drummond 2F0 for the time being add tests for #55
1 parent 98d6991 commit 8fc718f

File tree

3 files changed

+35
-43
lines changed

3 files changed

+35
-43
lines changed

src/confluent.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ const M = _₁F₁
1717
"""
1818
Compute Tricomi's confluent hypergeometric function `U(a, b, z) ∼ z⁻ᵃ ₂F₀([a, a-b+1]; []; -z⁻¹)`.
1919
"""
20-
function U(a, b, z)
21-
return z^-a*pFq([a, a-b+1], typeof(z)[], -inv(z))
20+
function U(a, b, z; kwds...)
21+
return z^-a*drummond2F0(a, a-b+1, -inv(z); kwds...)
2222
end

src/drummond.jl

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function drummond2F0(α::T1, β::T2, z::T3; kmax::Int = 10_000) where {T1, T2, T
129129
Nhi /=+2)*+2)
130130
Dhi /=+2)*+2)
131131
k = 2
132-
while k < kmax && errcheck(Tmid, Thi, 10eps(real(T)))
132+
while k < 3 || (k < kmax && errcheck(Tmid, Thi, 10eps(real(T))))
133133
Nhi, Nmid, Nlo = ((k+2)*ζ-+k+1)*+k+1)-k*+β+2k+1))*Nhi - k*+β+3k-ζ)*Nmid - k*(k-1)*Nlo, Nhi, Nmid
134134
Dhi, Dmid, Dlo = ((k+2)*ζ-+k+1)*+k+1)-k*+β+2k+1))*Dhi - k*+β+3k-ζ)*Dmid - k*(k-1)*Dlo, Dhi, Dmid
135135
Thi, Tmid, Tlo = Nhi/Dhi, Thi, Tmid
@@ -293,20 +293,16 @@ function pFqdrummond(α::AbstractVector{T1}, β::AbstractVector{T2}, z::T3; kmax
293293
p = length(α)
294294
q = length(β)
295295
r = max(p+1, q+2)
296-
C = zeros(T, r)
297-
C[1] = one(T)
298-
= zeros(T, r)
299-
Ĉ[1] = one(T)
296+
err = one(real(T))
297+
for j in 1:p
298+
err *= absα[j]+1
299+
end
300300
P = zeros(T, p+1)
301301
t = one(T)
302302
for j in 1:p
303303
t *= α[j]+1
304304
end
305305
P[1] = t
306-
err = one(real(T))
307-
for j in 1:p
308-
err *= absα[j]+1
309-
end
310306
Q = zeros(T, q+2)
311307
t = one(T)
312308
for j in 1:q
@@ -328,29 +324,25 @@ function pFqdrummond(α::AbstractVector{T1}, β::AbstractVector{T2}, z::T3; kmax
328324
end
329325
t1 = zero(T)
330326
for j in 0:min(k, q+1)
331-
t1 += Ĉ[j+1]*Q[j+1]*N[r-j]
327+
t1 += Q[j+1]*N[r-j]
332328
end
333329
if k q+1
334-
if p > q
335-
t1 += Q[k+1]
336-
else
337-
t1 += Q[k+1] / T(factorial(k+1))
338-
end
330+
t1 += Q[k+1]
339331
end
340332
t2 = zero(T)
341-
t2 += Ĉ[1]*P[1]*N[r]
333+
t2 += P[1]*N[r]
342334
for j in 1:min(k, p)
343-
t2 += P[j+1]*(C[j+1]*N[r-j+1] + Ĉ[j+1]*N[r-j])
335+
t2 += P[j+1]*(N[r-j+1] + N[r-j])
344336
end
345337
N[r+1] = ζ*t1-t2
346338
t1 = zero(T)
347339
for j in 0:min(k, q+1)
348-
t1 += Ĉ[j+1]*Q[j+1]*D[r-j]
340+
t1 += Q[j+1]*D[r-j]
349341
end
350342
t2 = zero(T)
351-
t2 += Ĉ[1]*P[1]*D[r]
343+
t2 += P[1]*D[r]
352344
for j in 1:min(k, p)
353-
t2 += P[j+1]*(C[j+1]*D[r-j+1] + Ĉ[j+1]*D[r-j])
345+
t2 += P[j+1]*(D[r-j+1] + D[r-j])
354346
end
355347
D[r+1] = ζ*t1-t2
356348
R[r+1] = N[r+1]/D[r+1]
@@ -360,29 +352,17 @@ function pFqdrummond(α::AbstractVector{T1}, β::AbstractVector{T2}, z::T3; kmax
360352
N[r+1] /= P[1]
361353
D[r+1] /= P[1]
362354
k += 1
363-
if p > q
364-
for j in min(k, max(p, q+1)):-1:1
365-
C[j+1] += C[j]
366-
Ĉ[j+1] += Ĉ[j]
367-
end
368-
else
369-
for j in min(k, max(p, q+1)):-1:1
370-
C[j+1] = (C[j+1]*(k+1-j) + C[j])/(k+1)
371-
Ĉ[j+1] = (Ĉ[j+1]*(k-j) + Ĉ[j])/(k+1)
372-
end
373-
Ĉ[1] = Ĉ[1]*k/(k+1)
355+
err = one(real(T))
356+
for j in 1:p
357+
err *= absα[j]+k+1
374358
end
375359
t = one(T)
376360
for j in 1:p
377361
t *= α[j]+k+1
378362
end
379-
err = one(real(T))
380363
for j in 1:p
381-
err *= absα[j]+k+1
382-
end
383-
for j in 2:p+1
384-
s = t - P[j-1]
385-
P[j-1] = t
364+
s = ((k-j+1)*t - k*P[j])/j
365+
P[j] = t
386366
t = s
387367
end
388368
P[p+1] = t
@@ -391,9 +371,9 @@ function pFqdrummond(α::AbstractVector{T1}, β::AbstractVector{T2}, z::T3; kmax
391371
t *= β[j]+k+1
392372
end
393373
t *= k+2
394-
for j in 2:q+2
395-
s = t - Q[j-1]
396-
Q[j-1] = t
374+
for j in 1:q+1
375+
s = ((k-j+1)*t - k*Q[j])/j
376+
Q[j] = t
397377
t = s
398378
end
399379
Q[q+2] = t

test/runtests.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using HypergeometricFunctions, Test
22
import LinearAlgebra: norm
3-
import HypergeometricFunctions: _₂F₁general, iswellpoised # not exported
3+
import HypergeometricFunctions: _₂F₁general, iswellpoised, U
44

55
import HypergeometricFunctions: drummond0F0, drummond1F0, drummond0F1,
66
drummond2F0, drummond1F1, drummond0F2,
@@ -462,3 +462,15 @@ end
462462
@test _₂F₁(1, 0, 3, -1) _₂F₁(1.0, 0, 3, -1) 1.0
463463
end
464464
end
465+
466+
@testset "U" begin
467+
# From #55
468+
for (S, T) in ((Float64, BigFloat),)
469+
b = 0
470+
z = T(1)/3
471+
x = S(z)
472+
for a in S(1):S(0.5):S(7)
473+
@test U(a,b,x) S(U(a,b,z))
474+
end
475+
end
476+
end

0 commit comments

Comments
 (0)