diff --git a/Project.toml b/Project.toml index 7ee04f5..ad88084 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "HypergeometricFunctions" uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.6" +version = "0.3.7" [deps] DualNumbers = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" diff --git a/README.md b/README.md index 4cbfccb..c38173a 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,4 @@ A Julia package for calculating hypergeometric functions -This package implements the generalized hypergeometric function `pFq([a1,…,am], [b1,…,bn], z)`. In particular, the Gauss hypergeometric function is available as `_₂F₁(a, b, c, z)`, and also `_₃F₂([a1, a2, a3], [b1, b2], z)`. +This package implements the generalized hypergeometric function `pFq([a1,…,am], [b1,…,bn], z)`. In particular, the Gauss hypergeometric function is available as `_₂F₁(a, b, c, z)`, Kummer's confluent hypergeometric function is available as `_₁F₁(a, b, z)` and `HypergeometricFunctions.M(a, b, z)`, as well as `_₃F₂([a1, a2, a3], [b1, b2], z)`. diff --git a/src/HypergeometricFunctions.jl b/src/HypergeometricFunctions.jl index a180a1f..c83c0c0 100644 --- a/src/HypergeometricFunctions.jl +++ b/src/HypergeometricFunctions.jl @@ -7,10 +7,11 @@ module HypergeometricFunctions using DualNumbers, LinearAlgebra, SpecialFunctions -export _₂F₁, _₃F₂, pFq +export _₁F₁, _₂F₁, _₃F₂, pFq include("specialfunctions.jl") include("gauss.jl") +include("kummer.jl") include("generalized.jl") include("drummond.jl") include("weniger.jl") diff --git a/src/generalized.jl b/src/generalized.jl index f3d3d0b..0976272 100644 --- a/src/generalized.jl +++ b/src/generalized.jl @@ -10,6 +10,8 @@ function pFq(α::AbstractVector, β::AbstractVector, z; kwds...) return exp(z) elseif length(α) == 1 && length(β) == 0 return exp(-α[1]*log1p(-z)) + elseif length(α) == 1 && length(β) == 1 + return _₁F₁(α[1], β[1], float(z)) elseif length(α) == 2 && length(β) == 1 return _₂F₁(α[1], α[2], β[1], float(z)) elseif abs(z) ≤ ρ diff --git a/src/kummer.jl b/src/kummer.jl new file mode 100644 index 0000000..cc57bc0 --- /dev/null +++ b/src/kummer.jl @@ -0,0 +1,12 @@ +""" +Compute Kummer's confluent hypergeometric function `₁F₁(a; b; z)`. +""" +function _₁F₁(a, b, z) + if real(z) ≥ 0 + return _₁F₁maclaurin(a, b, z) + else + return exp(z)*_₁F₁(b-a, b, -z) + end +end + +const M = _₁F₁ diff --git a/src/specialfunctions.jl b/src/specialfunctions.jl index 393819f..21c3452 100644 --- a/src/specialfunctions.jl +++ b/src/specialfunctions.jl @@ -147,7 +147,7 @@ function unsafe_gamma(x::BigFloat) return z end unsafe_gamma(z::Dual) = (r = realpart(z);w = unsafe_gamma(r); dual(w, w*digamma(r)*dualpart(z))) -unsafe_gamma(z) = gamma(z) +unsafe_gamma(z) = gamma(z) """ @lanczosratio(z, ϵ, c₀, c...) @@ -492,6 +492,17 @@ function _₂F₁taylor(a::Number, b::Number, c::Number, z::Number) return S₁ end +function _₁F₁maclaurin(a::Number, b::Number, z::Number) + T = float(promote_type(typeof(a), typeof(b), typeof(z))) + S₀, S₁, j = one(T), one(T)+a*z/b, 1 + while errcheck(S₀, S₁, 10eps(real(T))) || j ≤ 1 + rⱼ = (a+j)/((b+j)*(j+1)) + S₀, S₁ = S₁, S₁+(S₁-S₀)*rⱼ*z + j += 1 + end + return S₁ +end + function _₃F₂maclaurin(a₁, a₂, a₃, b₁, b₂, z) T = float(promote_type(typeof(a₁), typeof(a₂), typeof(a₃), typeof(b₁), typeof(b₂), typeof(z))) S₀, S₁, j = one(T), one(T)+(a₁*a₂*a₃*z)/(b₁*b₂), 1