Skip to content

Commit

Permalink
move [l]gamma, [l]beta and lfact to SpecialFunctions.jl
Browse files Browse the repository at this point in the history
fix #27459
  • Loading branch information
fredrikekre committed Jun 7, 2018
1 parent 91d2071 commit e2710dd
Show file tree
Hide file tree
Showing 16 changed files with 50 additions and 325 deletions.
8 changes: 0 additions & 8 deletions base/combinatorics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@ else
factorial(n::Union{Int8,UInt8,Int16,UInt16,Int32,UInt32}) = factorial(Int64(n))
end

function gamma(n::Union{Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64})
n < 0 && throw(DomainError(n, "`n` must not be negative."))
n == 0 && return Inf
n <= 2 && return 1.0
n > 20 && return gamma(Float64(n))
@inbounds return Float64(_fact_table64[n-1])
end


# Basic functions for working with permutations

Expand Down
13 changes: 13 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,19 @@ end
@deprecate_moved varm "StatsBase"
@deprecate_moved linreg "StatsBase"

# ?? more special functions to SpecialFunctions.jl
@deprecate_moved gamma "SpecialFunctions"
@deprecate_moved lgamma "SpecialFunctions"
@deprecate_moved beta "SpecialFunctions"
@deprecate_moved lbeta "SpecialFunctions"
@deprecate_moved lfact "SpecialFunctions"
function factorial(x::Number)
error("""factorial(x::Number) has been moved to the package SpecialFunctions.jl.
Run `Pkg.add("SpecialFunctions")` to install it, restart Julia,
and then run `using SpecialFunctions` to load it.
""")
end

# issue #27093
# in src/jlfrontend.scm a call to `@deprecate` is generated for per-module `eval(m, x)`
@eval Core Main.Base.@deprecate(eval(e), Core.eval(Main, e))
Expand Down
6 changes: 0 additions & 6 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ export
floor,
fma,
frexp,
gamma,
gcd,
gcdx,
hypot,
Expand All @@ -285,7 +284,6 @@ export
leading_ones,
leading_zeros,
lfact,
lgamma,
log,
log10,
log1p,
Expand Down Expand Up @@ -348,10 +346,6 @@ export
,
,

# specfun
beta,
lbeta,

# arrays
axes,
broadcast!,
Expand Down
5 changes: 2 additions & 3 deletions base/fastmath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ const fast_op =
:exp => :exp_fast,
:expm1 => :expm1_fast,
:hypot => :hypot_fast,
:lgamma => :lgamma_fast,
:log10 => :log10_fast,
:log1p => :log1p_fast,
:log2 => :log2_fast,
Expand Down Expand Up @@ -276,7 +275,7 @@ sqrt_fast(x::FloatTypes) = sqrt_llvm(x)
const libm = Base.libm_name

for f in (:acosh, :asinh, :atanh, :cbrt, :cos,
:cosh, :exp2, :expm1, :lgamma, :log10, :log1p, :log2,
:cosh, :exp2, :expm1, :log10, :log1p, :log2,
:log, :sin, :sinh, :tan, :tanh)
f_fast = fast_op[f]
@eval begin
Expand Down Expand Up @@ -377,7 +376,7 @@ end
# fall-back implementations and type promotion

for f in (:acos, :acosh, :angle, :asin, :asinh, :atan, :atanh, :cbrt,
:cis, :cos, :cosh, :exp10, :exp2, :exp, :expm1, :lgamma,
:cis, :cos, :cosh, :exp10, :exp2, :exp, :expm1,
:log10, :log1p, :log2, :log, :sin, :sinh, :sqrt, :tan,
:tanh)
f_fast = fast_op[f]
Expand Down
24 changes: 24 additions & 0 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,30 @@ function isqrt(x::Union{Int64,UInt64,Int128,UInt128})
s*s > x ? s-1 : s
end

"""
factorial(n::Integer)
Factorial of `n`. If `n` is an [`Integer`](@ref), the factorial is computed as an
integer (promoted to at least 64 bits). Note that this may overflow if `n` is not small,
but you can use `factorial(big(n))` to compute the result exactly in arbitrary precision.
# Examples
```jldoctest
julia> factorial(6)
720
julia> factorial(21)
ERROR: OverflowError: 21 is too large to look up in the table
Stacktrace:
[...]
julia> factorial(21.0)
5.109094217170944e19
julia> factorial(big(21))
51090942171709440000
```
"""
function factorial(n::Integer)
n < 0 && throw(DomainError(n, "`n` must be nonnegative."))
f::typeof(n*n) = 1
Expand Down
9 changes: 4 additions & 5 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export sin, cos, sincos, tan, sinh, cosh, tanh, asin, acos, atan,
rad2deg, deg2rad,
log, log2, log10, log1p, exponent, exp, exp2, exp10, expm1,
cbrt, sqrt, significand,
lgamma, hypot, gamma, lfact, max, min, minmax, ldexp, frexp,
hypot, lfact, max, min, minmax, ldexp, frexp,
clamp, clamp!, modf, ^, mod2pi, rem2pi,
beta, lbeta, @evalpoly
@evalpoly

import .Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin,
acos, atan, asinh, acosh, atanh, sqrt, log2, log10,
Expand Down Expand Up @@ -484,7 +484,7 @@ Stacktrace:
```
"""
log1p(x)
for f in (:log2, :log10, :lgamma)
for f in (:log2, :log10)
@eval begin
@inline ($f)(x::Float64) = nan_dom_err(ccall(($(string(f)), libm), Float64, (Float64,), x), x)
@inline ($f)(x::Float32) = nan_dom_err(ccall(($(string(f, "f")), libm), Float32, (Float32,), x), x)
Expand Down Expand Up @@ -1037,15 +1037,14 @@ include("special/exp.jl")
include("special/exp10.jl")
include("special/hyperbolic.jl")
include("special/trig.jl")
include("special/gamma.jl")
include("special/rem_pio2.jl")
include("special/log.jl")

# `missing` definitions for functions in this module
for f in (:(acos), :(acosh), :(asin), :(asinh), :(atan), :(atanh),
:(sin), :(sinh), :(cos), :(cosh), :(tan), :(tanh),
:(exp), :(exp2), :(expm1), :(log), :(log10), :(log1p),
:(log2), :(exponent), :(sqrt), :(gamma), :(lgamma))
:(log2), :(exponent), :(sqrt))
@eval $(f)(::Missing) = missing
end

Expand Down
25 changes: 3 additions & 22 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,17 @@ import
isfinite, isinf, isnan, ldexp, log, log2, log10, max, min, mod, modf,
nextfloat, prevfloat, promote_rule, rem, rem2pi, round, show, float,
sum, sqrt, string, print, trunc, precision, exp10, expm1,
gamma, lgamma, log1p,
log1p,
eps, signbit, sin, cos, sincos, tan, sec, csc, cot, acos, asin, atan,
cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh,
cbrt, typemax, typemin, unsafe_trunc, realmin, realmax, rounding,
setrounding, maxintfloat, widen, significand, frexp, tryparse, iszero,
isone, big, beta, RefValue
isone, big, RefValue

import .Base.Rounding: rounding_raw, setrounding_raw

import .Base.GMP: ClongMax, CulongMax, CdoubleMax, Limb

import .Base.Math.lgamma_r

import .Base.FastMath.sincos_fast

version() = VersionNumber(unsafe_string(ccall((:mpfr_get_version,:libmpfr), Ptr{Cchar}, ())))
Expand Down Expand Up @@ -655,7 +653,7 @@ function sum(arr::AbstractArray{BigFloat})
end

# Functions for which NaN results are converted to DomainError, following Base
for f in (:sin, :cos, :tan, :sec, :csc, :acos, :asin, :atan, :acosh, :asinh, :atanh, :gamma)
for f in (:sin, :cos, :tan, :sec, :csc, :acos, :asin, :atan, :acosh, :asinh, :atanh)
@eval begin
function ($f)(x::BigFloat)
isnan(x) && return x
Expand All @@ -667,28 +665,11 @@ for f in (:sin, :cos, :tan, :sec, :csc, :acos, :asin, :atan, :acosh, :asinh, :at
end
end

# log of absolute value of gamma function
const lgamma_signp = Ref{Cint}()
function lgamma(x::BigFloat)
z = BigFloat()
ccall((:mpfr_lgamma,:libmpfr), Cint, (Ref{BigFloat}, Ref{Cint}, Ref{BigFloat}, Int32), z, lgamma_signp, x, ROUNDING_MODE[])
return z
end

lgamma_r(x::BigFloat) = (lgamma(x), lgamma_signp[])

function atan(y::BigFloat, x::BigFloat)
z = BigFloat()
ccall((:mpfr_atan2, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, y, x, ROUNDING_MODE[])
return z
end
if version() >= v"4.0.0"
function beta(y::BigFloat, x::BigFloat)
z = BigFloat()
ccall((:mpfr_beta, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, y, x, ROUNDING_MODE[])
return z
end
end

# Utility functions
==(x::BigFloat, y::BigFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), x, y) != 0
Expand Down
27 changes: 0 additions & 27 deletions base/number.jl
Original file line number Diff line number Diff line change
Expand Up @@ -321,33 +321,6 @@ oneunit(::Type{T}) where {T} = T(one(T))

_default_type(::Type{Number}) = Int

"""
factorial(n)
Factorial of `n`. If `n` is an [`Integer`](@ref), the factorial is computed as an
integer (promoted to at least 64 bits). Note that this may overflow if `n` is not small,
but you can use `factorial(big(n))` to compute the result exactly in arbitrary precision.
If `n` is not an `Integer`, `factorial(n)` is equivalent to [`gamma(n+1)`](@ref).
# Examples
```jldoctest
julia> factorial(6)
720
julia> factorial(21)
ERROR: OverflowError: 21 is too large to look up in the table
Stacktrace:
[...]
julia> factorial(21.0)
5.109094217170944e19
julia> factorial(big(21))
51090942171709440000
```
"""
factorial(x::Number) = gamma(x + 1) # fallback for x not Integer

"""
big(T::Type)
Expand Down
Loading

0 comments on commit e2710dd

Please sign in to comment.