diff --git a/.travis.yml b/.travis.yml index e0ea53d..dd5a7e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,7 @@ os: - linux - osx julia: - - 0.3 - - 0.4 + - 0.6 - nightly notifications: email: false diff --git a/REQUIRE b/REQUIRE index df77a41..3f3349d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,2 +1,2 @@ -julia 0.3 -Compat +julia 0.6 +SpecialFunctions diff --git a/src/NumericFuns.jl b/src/NumericFuns.jl index 14d518b..d1802a9 100644 --- a/src/NumericFuns.jl +++ b/src/NumericFuns.jl @@ -1,7 +1,5 @@ module NumericFuns - using Compat - export # mathfuns diff --git a/src/functors.jl b/src/functors.jl index 80b1d4d..ba64461 100644 --- a/src/functors.jl +++ b/src/functors.jl @@ -4,11 +4,13 @@ # ################################################# -abstract Functor{N} # N is the number of arguments +using SpecialFunctions # erf -typealias UnaryFunctor Functor{1} -typealias BinaryFunctor Functor{2} -typealias TernaryFunctor Functor{3} +abstract type Functor{N} end # N is the number of arguments + +const UnaryFunctor = Functor{1} +const BinaryFunctor = Functor{2} +const TernaryFunctor = Functor{3} ## macros for defining functors @@ -37,7 +39,7 @@ macro functor2(F, fun, T) end default_functorsym(f::Symbol) = - (fstr = string(f); symbol(string(uppercase(fstr[1]), fstr[2:end], "Fun"))) + (fstr = string(f); Symbol(string(uppercase(fstr[1]), fstr[2:end], "Fun"))) macro functor1a(fun, T) F = default_functorsym(fun) @@ -70,7 +72,6 @@ macro functor1a_ord(fun, T) immutable $eF{OT<:Real} <: Functor{1} order::OT end - $eF{OT<:Real}(ord::OT) = $eF{OT}(ord) NumericFuns.evaluate(f::$eF, x::$eT) = $efun(f.order, x) end end @@ -128,7 +129,7 @@ export BitwiseNot, BitwiseAnd, BitwiseOr, BitwiseXor @functor1(BitwiseNot, ~, Integer) @functor2(BitwiseAnd, &, Integer) @functor2(BitwiseOr, |, Integer) -@functor2(BitwiseXor, $, Integer) +@functor2(BitwiseXor, ⊻, Integer) ## arithmetic functions @@ -285,7 +286,7 @@ export AsinhFun, AcoshFun, AtanhFun, AcothFun, AsechFun, AcschFun export ErfFun, ErfcFun, ErfinvFun, ErfcinvFun, ErfiFun, ErfcxFun export GammaFun, LgammaFun, DigammaFun, EtaFun, ZetaFun, BetaFun, LbetaFun -export AiryFun, AiryprimeFun, AiryaiFun, AiryaiprimeFun, AirybiFun, AirybiprimeFun +export AiryaiFun, AiryaiprimeFun, AirybiFun, AirybiprimeFun export Besselj0Fun, Besselj1Fun, Bessely0Fun, Bessely1Fun export BesseliFun, BesseljFun, BesselkFun, BesselyFun @@ -309,8 +310,6 @@ export Hankelh1Fun, Hankelh2Fun @functor2a beta Real @functor2a lbeta Real -@functor1a airy Number -@functor1a airyprime Number @functor1a airyai Number @functor1a airyaiprime Number @functor1a airybi Number diff --git a/src/mathfuns.jl b/src/mathfuns.jl index 74d8c16..e3ca20c 100644 --- a/src/mathfuns.jl +++ b/src/mathfuns.jl @@ -29,16 +29,4 @@ logsumexp{T<:AbstractFloat}(x::T, y::T) = x > y ? x + log1p(exp(y - x)) : y + lo logsumexp{T<:Real}(x::T, y::T) = logsumexp(float(x), float(y)) logsumexp(x::Real, y::Real) = logsumexp(promote(x, y)...) -@vectorize_1arg Number sqr -@vectorize_1arg Number rcp -@vectorize_1arg Real rsqrt -@vectorize_1arg Real rcbrt - -@vectorize_1arg Real xlogx -@vectorize_2arg Real xlogy -@vectorize_1arg Real logistic -@vectorize_1arg Real logit -@vectorize_1arg Real softplus -@vectorize_1arg Real invsoftplus - const sigmoid = logistic diff --git a/src/rtypes.jl b/src/rtypes.jl index 3a3ad7f..d68025e 100644 --- a/src/rtypes.jl +++ b/src/rtypes.jl @@ -9,6 +9,7 @@ ## fptype # @compat fptype{T<:Union{Bool,Int8,Int16,UInt8,UInt16}}(::Type{T}) = Float32 +fptype(::Type{Bool}) = Float64 fptype{T<:Integer}(::Type{T}) = Float64 fptype{T<:AbstractFloat}(::Type{T}) = T @@ -90,8 +91,8 @@ result_type{T<:Number}(::SqrFun, ::Type{T}) = arithtype(T) # real & imag -@compat result_type{T<:Real}(::Union{RealFun,ImagFun}, ::Type{T}) = T -@compat result_type{T<:Real}(::Union{RealFun,ImagFun}, ::Type{Complex{T}}) = T +result_type{T<:Real}(::Union{RealFun,ImagFun}, ::Type{T}) = T +result_type{T<:Real}(::Union{RealFun,ImagFun}, ::Type{Complex{T}}) = T # sign & signbit @@ -100,7 +101,7 @@ result_type{T<:Real}(::SignbitFun, ::Type{T}) = Bool # add & subtract -@compat result_type{T1<:Number,T2<:Number}(::Union{Add,Subtract}, ::Type{T1}, ::Type{T2}) = arithtype(T1, T2) +result_type{T1<:Number,T2<:Number}(::Union{Add,Subtract}, ::Type{T1}, ::Type{T2}) = arithtype(T1, T2) # multiply @@ -123,7 +124,7 @@ result_type{T1<:Integer,T2<:Integer}(::Divide, ::Type{T1}, ::Type{T2}) = promote_type(fptype(T1), fptype(T2)) result_type{T1<:Real,T2<:Complex}(op::Divide, ::Type{T1}, ::Type{T2}) = - result_type(Multiply(), T1, fptype(T2)) + fptype(result_type(Multiply(), T1, T2)) result_type{T1<:Real,T2<:Real}(op::Divide, ::Type{Complex{T1}}, ::Type{T2}) = Complex{result_type(op, T1, T2)} @@ -170,29 +171,22 @@ result_type{T<:Real, Tx<:Real}(::FixAbsPow{T}, ::Type{Tx}) = result_type(Pow(), # max & min -@compat result_type{T<:Real}(::Union{MaxFun,MinFun}, ::Type{T}, ::Type{T}) = T -@compat result_type{T1<:Real,T2<:Real}(::Union{MaxFun,MinFun}, ::Type{T1}, ::Type{T2}) = promote_type(T1, T2) +result_type{T<:Real}(::Union{MaxFun,MinFun}, ::Type{T}, ::Type{T}) = T +result_type{T1<:Real,T2<:Real}(::Union{MaxFun,MinFun}, ::Type{T1}, ::Type{T2}) = promote_type(T1, T2) # quotient & module -@compat result_type{T1<:Real,T2<:Real}(::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = promote_type(T1, T2) +result_type{T1<:Real,T2<:Real}(::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = promote_type(T1, T2) -if VERSION >= v"0.4-dev" - @compat result_type{T1<:Signed,T2<:Unsigned}(op::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = - signedtype(result_type(op, unsignedtype(T1), T2)) - @compat result_type{T1<:Unsigned,T2<:Signed}(op::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = - result_type(op, T1, unsignedtype(T2)) -else - @compat result_type{T1<:Signed,T2<:Unsigned}(::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = - signedtype(promote_type(T1, T2)) - @compat result_type{T1<:Unsigned,T2<:Signed}(::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = - unsignedtype(promote_type(T1, T2)) -end +result_type{T1<:Signed,T2<:Unsigned}(op::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = + signedtype(result_type(op, unsignedtype(T1), T2)) +result_type{T1<:Unsigned,T2<:Signed}(op::Union{DivFun,RemFun}, ::Type{T1}, ::Type{T2}) = + result_type(op, T1, unsignedtype(T2)) result_type{T1<:Real,T2<:Real}(::FldFun, ::Type{T1}, ::Type{T2}) = arithtype(T1, T2) -@compat result_type{T1<:Union{Unsigned,Bool}, T2<:Union{Unsigned,Bool}}(::FldFun, ::Type{T1}, ::Type{T2}) = +result_type{T1<:Union{Unsigned,Bool}, T2<:Union{Unsigned,Bool}}(::FldFun, ::Type{T1}, ::Type{T2}) = promote_type(T1, T2) result_type{T1<:Signed,T2<:Unsigned}(::FldFun, ::Type{T1}, ::Type{T2}) = @@ -225,46 +219,46 @@ result_type(::Or, ::Type{Bool}, ::Type{Bool}) = Bool result_type{T<:Integer}(::BitwiseNot, ::Type{T}) = T -@compat result_type{T1<:Integer,T2<:Integer}(::Union{BitwiseAnd,BitwiseOr,BitwiseXor}, ::Type{T1}, ::Type{T2}) = +result_type{T1<:Integer,T2<:Integer}(::Union{BitwiseAnd,BitwiseOr,BitwiseXor}, ::Type{T1}, ::Type{T2}) = promote_type(T1, T2) # comparison -@compat result_type{T1<:Real,T2<:Real}(::Union{LT,GT,LE,GE}, ::Type{T1}, ::Type{T2}) = Bool -@compat result_type{T1<:Number,T2<:Number}(::Union{EQ,NE}, ::Type{T1}, ::Type{T2}) = Bool +result_type{T1<:Real,T2<:Real}(::Union{LT,GT,LE,GE}, ::Type{T1}, ::Type{T2}) = Bool +result_type{T1<:Number,T2<:Number}(::Union{EQ,NE}, ::Type{T1}, ::Type{T2}) = Bool # rounding -@compat result_type{T<:Real}(::Union{FloorFun, CeilFun, TruncFun, RoundFun}, ::Type{T}) = T -@compat result_type{T<:Integer}(::Union{IfloorFun, IceilFun, ItruncFun, IroundFun}, ::Type{T}) = T -@compat result_type{T<:AbstractFloat}(::Union{IfloorFun, IceilFun, ItruncFun, IroundFun}, ::Type{T}) = Int64 +result_type{T<:Real}(::Union{FloorFun, CeilFun, TruncFun, RoundFun}, ::Type{T}) = T +result_type{T<:Integer}(::Union{IfloorFun, IceilFun, ItruncFun, IroundFun}, ::Type{T}) = T +result_type{T<:AbstractFloat}(::Union{IfloorFun, IceilFun, ItruncFun, IroundFun}, ::Type{T}) = Int64 # number classification -@compat result_type{T<:Real}(::Union{IsnanFun, IsinfFun, IsfiniteFun}, ::Type{T}) = Bool +result_type{T<:Real}(::Union{IsnanFun, IsinfFun, IsfiniteFun}, ::Type{T}) = Bool # algebraic functions -@compat result_type{T<:Number}(::Union{SqrtFun,CbrtFun,RsqrtFun,RcbrtFun}, ::Type{T}) = fptype(T) -result_type{T1<:Real,T2<:Real}(::HypotFun, ::Type{T1}, ::Type{T2}) = promote_type(fptype(T1), fptype(T2)) +result_type{T<:Number}(::Union{SqrtFun,CbrtFun,RsqrtFun,RcbrtFun}, ::Type{T}) = fptype(T) +result_type{T1<:Real,T2<:Real}(::HypotFun, ::Type{T1}, ::Type{T2}) = fptype(promote_type(T1, T2)) # exponential & logarithm -@compat result_type{T<:Number}(::Union{ExpFun,Exp2Fun,Exp10Fun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{LogFun,Log2Fun,Log10Fun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Real}(::Union{Expm1Fun,Log1pFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{ExpFun,Exp2Fun,Exp10Fun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{LogFun,Log2Fun,Log10Fun}, ::Type{T}) = fptype(T) +result_type{T<:Real}(::Union{Expm1Fun,Log1pFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Real}(::Union{XlogxFun,LogisticFun,LogitFun,SoftplusFun,InvsoftplusFun}, ::Type{T}) = fptype(T) +result_type{T<:Real}(::Union{XlogxFun,LogisticFun,LogitFun,SoftplusFun,InvsoftplusFun}, ::Type{T}) = fptype(T) result_type{T1<:Real,T2<:Real}(::XlogyFun, ::Type{T1}, ::Type{T2}) = fptype(promote_type(T1, T2)) result_type{T1<:Real,T2<:Real}(::LogsumexpFun, ::Type{T1}, ::Type{T2}) = fptype(promote_type(T1, T2)) # trigonometric functions -@compat result_type{T<:Number}(::Union{SinFun,CosFun,TanFun,CotFun,SecFun,CscFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{AsinFun,AcosFun,AtanFun,AcotFun,AsecFun,AcscFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{SincFun,CoscFun,SinpiFun,CospiFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{SindFun,CosdFun,TandFun,CotdFun,SecdFun,CscdFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{AsindFun,AcosdFun,AtandFun,AcotdFun,AsecdFun,AcscdFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{SinFun,CosFun,TanFun,CotFun,SecFun,CscFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{AsinFun,AcosFun,AtanFun,AcotFun,AsecFun,AcscFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{SincFun,CoscFun,SinpiFun,CospiFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{SindFun,CosdFun,TandFun,CotdFun,SecdFun,CscdFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{AsindFun,AcosdFun,AtandFun,AcotdFun,AsecdFun,AcscdFun}, ::Type{T}) = fptype(T) result_type{T<:Integer}(::SincFun, ::Type{T}) = T if VERSION < v"0.4-dev" @@ -276,36 +270,35 @@ result_type{T1<:Real,T2<:Real}(::Atan2Fun, ::Type{T1}, ::Type{T2}) = promote_typ # hyperbolic functions -@compat result_type{T<:Number}(::Union{SinhFun,CoshFun,TanhFun,CothFun,SechFun,CschFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{AsinhFun,AcoshFun,AtanhFun,AcothFun,AsechFun,AcschFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{SinhFun,CoshFun,TanhFun,CothFun,SechFun,CschFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{AsinhFun,AcoshFun,AtanhFun,AcothFun,AsechFun,AcschFun}, ::Type{T}) = fptype(T) # erf & friends -@compat result_type{T<:Number}(::Union{ErfFun,ErfcFun,ErfiFun,ErfcxFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{ErfinvFun,ErfcinvFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{ErfFun,ErfcFun,ErfiFun,ErfcxFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{ErfinvFun,ErfcinvFun}, ::Type{T}) = fptype(T) # gamma, beta, & friends -@compat result_type{T<:Number}(::Union{GammaFun,LgammaFun,EtaFun,ZetaFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Integer}(::Union{EtaFun,ZetaFun}, ::Type{T}) = Float64 - -@compat result_type(::Union{GammaFun,LgammaFun}, ::Type{Complex64}) = Complex128 +result_type{T<:Number}(::Union{GammaFun,LgammaFun,EtaFun,ZetaFun}, ::Type{T}) = fptype(T) +result_type{T<:Integer}(::Union{EtaFun,ZetaFun}, ::Type{T}) = Float64 result_type{T<:AbstractFloat}(::DigammaFun, ::Type{T}) = T result_type{T<:Integer}(::DigammaFun, ::Type{T}) = Float64 -@compat result_type{T1<:Real,T2<:Real}(::Union{BetaFun,LbetaFun}, ::Type{T1}, ::Type{T2}) = +result_type{T1<:Real,T2<:Real}(::Union{BetaFun,LbetaFun}, ::Type{T1}, ::Type{T2}) = promote_type(fptype(T1),fptype(T2)) -@compat result_type{T1<:Integer,T2<:Integer}(::Union{BetaFun,LbetaFun}, ::Type{T1}, ::Type{T2}) = Float64 +result_type{T1<:Integer,T2<:Integer}(::Union{BetaFun,LbetaFun}, ::Type{T1}, ::Type{T2}) = Float64 # airy & friends -@compat result_type{T<:Number}(::Union{AiryFun,AiryprimeFun,AiryaiFun,AiryaiprimeFun,AirybiFun,AirybiprimeFun},::Type{T}) = +result_type{T<:Number}(::Union{AiryaiFun,AiryaiprimeFun,AirybiFun,AirybiprimeFun},::Type{T}) = fptype(T) # bessel & friends -@compat result_type{T<:Number}(::Union{Besselj0Fun, Besselj1Fun, Bessely0Fun, Bessely1Fun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{BesseliFun, BesseljFun, BesselkFun, BesselyFun}, ::Type{T}) = fptype(T) -@compat result_type{T<:Number}(::Union{Hankelh1Fun, Hankelh2Fun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{Besselj0Fun, Besselj1Fun, Bessely0Fun, Bessely1Fun}, ::Type{T}) = fptype(T) +result_type(::Union{Besselj0Fun, Besselj1Fun, Bessely0Fun, Bessely1Fun}, ::Type{Complex64}) = Complex128 +result_type{T<:Number}(::Union{BesseliFun, BesseljFun, BesselkFun, BesselyFun}, ::Type{T}) = fptype(T) +result_type{T<:Number}(::Union{Hankelh1Fun, Hankelh2Fun}, ::Type{T}) = fptype(T) diff --git a/test/functors.jl b/test/functors.jl index 825e270..56ea577 100644 --- a/test/functors.jl +++ b/test/functors.jl @@ -61,7 +61,7 @@ println(" bitwise operators") for (F, sf) in [(BitwiseAnd, &), (BitwiseOr, |), - (BitwiseXor, $)] + (BitwiseXor, ⊻)] @test evaluate(F(), 5, 9) == sf(5, 9) end @@ -150,7 +150,7 @@ println(" special functions") for (Fun, sf) in [(ErfFun(), erf), (GammaFun(), gamma), - (AiryFun(), airy), + (AiryaiFun(), airyai), (Besselj0Fun(), besselj0), (BesseljFun(2), x -> besselj(2, x))] diff --git a/test/mathfuns.jl b/test/mathfuns.jl index 749beac..6e419e8 100644 --- a/test/mathfuns.jl +++ b/test/mathfuns.jl @@ -9,23 +9,23 @@ using Base.Test @test rcbrt(8) === 0.5 @test xlogx(0) === 0.0 -@test_approx_eq xlogx(2) 2.0 * log(2.0) +@test xlogx(2) ≈ 2.0 * log(2.0) @test xlogy(0, 1) === 0.0 -@test_approx_eq xlogy(2, 3) 2.0 * log(3.0) +@test xlogy(2, 3) ≈ 2.0 * log(3.0) -@test_approx_eq logistic(2) 1.0 / (1.0 + exp(-2.0)) -@test_approx_eq logit(0.5) 0.0 -@test_approx_eq logit(sigmoid(2)) 2.0 +@test logistic(2) ≈ 1.0 / (1.0 + exp(-2.0)) +@test logit(0.5) ≈ 0.0 +@test logit(sigmoid(2)) ≈ 2.0 -@test_approx_eq softplus(2.0) log(1.0 + exp(2.0)) -@test_approx_eq softplus(-2.0) log(1.0 + exp(-2.0)) -@test_approx_eq softplus(10000) 10000.0 -@test_approx_eq softplus(-10000) 0.0 +@test softplus(2.0) ≈ log(1.0 + exp(2.0)) +@test softplus(-2.0) ≈ log(1.0 + exp(-2.0)) +@test softplus(10000) ≈ 10000.0 +@test softplus(-10000) ≈ 0.0 -@test_approx_eq invsoftplus(softplus(2.0)) 2.0 -@test_approx_eq invsoftplus(softplus(-2.0)) -2.0 +@test invsoftplus(softplus(2.0)) ≈ 2.0 +@test invsoftplus(softplus(-2.0)) ≈ -2.0 -@test_approx_eq logsumexp(2.0, 3.0) log(exp(2.0) + exp(3.0)) -@test_approx_eq logsumexp(10002, 10003) 10000 + logsumexp(2.0, 3.0) +@test logsumexp(2.0, 3.0) ≈ log(exp(2.0) + exp(3.0)) +@test logsumexp(10002, 10003) ≈ 10000 + logsumexp(2.0, 3.0) diff --git a/test/rtypes.jl b/test/rtypes.jl index 8a1a169..12c85fb 100644 --- a/test/rtypes.jl +++ b/test/rtypes.jl @@ -250,7 +250,7 @@ end println(" airy & friends") -for F in [AiryFun,AiryprimeFun,AiryaiFun,AiryaiprimeFun,AirybiFun,AirybiprimeFun] +for F in [AiryaiFun,AiryaiprimeFun,AirybiFun,AirybiprimeFun] for T in numerictypes_r check_rtype(F(), T) end