Add: julia-0.6.2
Former-commit-id: ccc667cf67d569f3fb3df39aa57c2134755a7551
This commit is contained in:
134
julia-0.6.2/share/julia/base/special/exp.jl
Normal file
134
julia-0.6.2/share/julia/base/special/exp.jl
Normal file
@@ -0,0 +1,134 @@
|
||||
# Based on FreeBSD lib/msun/src/e_exp.c
|
||||
# which is made available under the following licence
|
||||
|
||||
## Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. Permission
|
||||
## to use, copy, modify, and distribute this software is freely granted,
|
||||
## provided that this notice is preserved.
|
||||
|
||||
# Method
|
||||
# 1. Argument reduction: Reduce x to an r so that |r| <= 0.5*ln(2). Given x,
|
||||
# find r and integer k such that
|
||||
# x = k*ln(2) + r, |r| <= 0.5*ln(2).
|
||||
# Here r is represented as r = hi - lo for better accuracy.
|
||||
#
|
||||
# 2. Approximate exp(r) by a special rational function on [0, 0.5*ln(2)]:
|
||||
# R(r^2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r^4/360 + ...
|
||||
#
|
||||
# A special Remez algorithm on [0, 0.5*ln(2)] is used to generate a
|
||||
# polynomial to approximate R.
|
||||
#
|
||||
# The computation of exp(r) thus becomes
|
||||
# 2*r
|
||||
# exp(r) = 1 + ----------
|
||||
# R(r) - r
|
||||
# r*c(r)
|
||||
# = 1 + r + ----------- (for better accuracy)
|
||||
# 2 - c(r)
|
||||
# where
|
||||
# c(r) = r - (P1*r^2 + P2*r^4 + ... + P5*r^10 + ...).
|
||||
#
|
||||
# 3. Scale back: exp(x) = 2^k * exp(r)
|
||||
|
||||
# log(2)
|
||||
const LN2 = 6.931471805599453094172321214581765680755001343602552541206800094933936219696955e-01
|
||||
# log2(e)
|
||||
const LOG2E = 1.442695040888963407359924681001892137426646
|
||||
|
||||
# log(2) into upper and lower
|
||||
LN2U(::Type{Float64}) = 6.93147180369123816490e-1
|
||||
LN2U(::Type{Float32}) = 6.9313812256f-1
|
||||
|
||||
LN2L(::Type{Float64}) = 1.90821492927058770002e-10
|
||||
LN2L(::Type{Float32}) = 9.0580006145f-6
|
||||
|
||||
# max and min arguments for exponential fucntions
|
||||
MAXEXP(::Type{Float64}) = 7.09782712893383996732e2 # log 2^1023*(2-2^-52)
|
||||
MAXEXP(::Type{Float32}) = 88.72283905206835f0 # log 2^127 *(2-2^-23)
|
||||
|
||||
# one less than the min exponent since we can sqeeze a bit more from the exp function
|
||||
MINEXP(::Type{Float64}) = -7.451332191019412076235e2 # log 2^-1075
|
||||
MINEXP(::Type{Float32}) = -103.97207708f0 # log 2^-150
|
||||
|
||||
@inline exp_kernel(x::Float64) = @horner(x, 1.66666666666666019037e-1,
|
||||
-2.77777777770155933842e-3, 6.61375632143793436117e-5,
|
||||
-1.65339022054652515390e-6, 4.13813679705723846039e-8)
|
||||
|
||||
@inline exp_kernel(x::Float32) = @horner(x, 1.6666625440f-1, -2.7667332906f-3)
|
||||
|
||||
# for values smaller than this threshold just use a Taylor expansion
|
||||
@eval exp_small_thres(::Type{Float64}) = $(2.0^-28)
|
||||
@eval exp_small_thres(::Type{Float32}) = $(2.0f0^-13)
|
||||
|
||||
"""
|
||||
exp(x)
|
||||
|
||||
Compute the natural base exponential of `x`, in other words ``e^x``.
|
||||
"""
|
||||
function exp(x::T) where T<:Union{Float32,Float64}
|
||||
xa = reinterpret(Unsigned, x) & ~sign_mask(T)
|
||||
xsb = signbit(x)
|
||||
|
||||
# filter out non-finite arguments
|
||||
if xa > reinterpret(Unsigned, MAXEXP(T))
|
||||
if xa >= exponent_mask(T)
|
||||
xa & significand_mask(T) != 0 && return T(NaN)
|
||||
return xsb ? T(0.0) : T(Inf) # exp(+-Inf)
|
||||
end
|
||||
x > MAXEXP(T) && return T(Inf)
|
||||
x < MINEXP(T) && return T(0.0)
|
||||
end
|
||||
|
||||
# This implementation gives 2.7182818284590455 for exp(1.0) when T ==
|
||||
# Float64, which is well within the allowable error; however,
|
||||
# 2.718281828459045 is closer to the true value so we prefer that answer,
|
||||
# given that 1.0 is such an important argument value.
|
||||
if x == T(1.0) && T == Float64
|
||||
return 2.718281828459045235360
|
||||
end
|
||||
|
||||
if xa > reinterpret(Unsigned, T(0.5)*T(LN2)) # |x| > 0.5 log(2)
|
||||
# argument reduction
|
||||
if xa < reinterpret(Unsigned, T(1.5)*T(LN2)) # |x| < 1.5 log(2)
|
||||
if xsb
|
||||
k = -1
|
||||
hi = x + LN2U(T)
|
||||
lo = -LN2L(T)
|
||||
else
|
||||
k = 1
|
||||
hi = x - LN2U(T)
|
||||
lo = LN2L(T)
|
||||
end
|
||||
else
|
||||
n = round(T(LOG2E)*x)
|
||||
k = unsafe_trunc(Int,n)
|
||||
hi = muladd(n, -LN2U(T), x)
|
||||
lo = n*LN2L(T)
|
||||
end
|
||||
r = hi - lo
|
||||
|
||||
# compute approximation on reduced argument
|
||||
z = r*r
|
||||
p = r - z*exp_kernel(z)
|
||||
y = T(1.0) - ((lo - (r*p)/(T(2.0) - p)) - hi)
|
||||
|
||||
# scale back
|
||||
if k > -significand_bits(T)
|
||||
# multiply by 2.0 first to prevent overflow, which helps extends the range
|
||||
k == exponent_max(T) && return y * T(2.0) * T(2.0)^(exponent_max(T) - 1)
|
||||
twopk = reinterpret(T, rem(exponent_bias(T) + k, fpinttype(T)) << significand_bits(T))
|
||||
return y*twopk
|
||||
else
|
||||
# add significand_bits(T) + 1 to lift the range outside the subnormals
|
||||
twopk = reinterpret(T, rem(exponent_bias(T) + significand_bits(T) + 1 + k, fpinttype(T)) << significand_bits(T))
|
||||
return y * twopk * T(2.0)^(-significand_bits(T) - 1)
|
||||
end
|
||||
elseif xa < reinterpret(Unsigned, exp_small_thres(T)) # |x| < exp_small_thres
|
||||
# Taylor approximation for small x
|
||||
return T(1.0) + x
|
||||
else
|
||||
# primary range with k = 0, so compute approximation directly
|
||||
z = x*x
|
||||
p = x - z*exp_kernel(z)
|
||||
return T(1.0) - ((x*p)/(p - T(2.0)) - x)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user