Skip to content

Commit

Permalink
Merge pull request #109 from richardreeve/nightly-fixes
Browse files Browse the repository at this point in the history
Nightly fixes
  • Loading branch information
ajkeller34 authored Dec 14, 2017
2 parents a429e56 + b4b3a7a commit c54ddaf
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 187 deletions.
1 change: 1 addition & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
julia 0.6
Compat 0.33.0
1 change: 1 addition & 0 deletions src/Unitful.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
__precompile__(true)
module Unitful
using Compat

import Base: ==, <, <=, +, -, *, /, //, ^
import Base: show, convert
Expand Down
21 changes: 16 additions & 5 deletions src/dimensions.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
"""
\*(a0::Dimensions, a::Dimensions...)
```
*(a0::Dimensions, a::Dimensions...)
```
Given however many dimensions, multiply them together.
Collect [`Unitful.Dimension`](@ref) objects from the type parameter of the
Expand Down Expand Up @@ -54,7 +57,7 @@ true
end
end

d = (c...)
d = (c...,)
:(Dimensions{$d}())
end

Expand All @@ -69,9 +72,17 @@ end
# Exponentiation is not type-stable for `Dimensions` objects in many cases
^(x::Dimensions{T}, y::Integer) where {T} = *(Dimensions{map(a->a^y, T)}())
^(x::Dimensions{T}, y::Number) where {T} = *(Dimensions{map(a->a^y, T)}())
@generated function Base.literal_pow(::typeof(^), x::Dimensions{T}, ::Type{Val{p}}) where {T,p}
z = *(Dimensions{map(a->a^p, T)}())
:($z)

@static if VERSION < v"0.7.0-DEV.843"
@generated function Base.literal_pow(::typeof(^), x::Dimensions{T}, ::Type{Val{p}}) where {T,p}
z = *(Dimensions{map(a->a^p, T)}())
:($z)
end
else
@generated function Base.literal_pow(::typeof(^), x::Dimensions{T}, ::Val{p}) where {T,p}
z = *(Dimensions{map(a->a^p, T)}())
:($z)
end
end

# Since exponentiation is not type stable, we define a special `inv` method to enable fast
Expand Down
12 changes: 0 additions & 12 deletions src/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,6 @@ function show(io::IO, x::Quantity)
nothing
end

"""
show{T,D,U}(io::IO, ::Type{Quantity{T,D,U}})
Show the type of a unitful quantity in a succinct way. Otherwise,
array summaries are nearly unreadable.
"""
function show(io::IO, ::Type{Quantity{T,D,U}}) where {T,D,U}
print(io, "Quantity{", string(T),
", Dimensions:{", string(D()),
"}, Units:{", string(U()), "}}")
nothing
end

"""
show(io::IO, x::Unitlike)
Call [`Unitful.showrep`](@ref) on each object in the tuple that is the type
Expand Down
4 changes: 2 additions & 2 deletions src/fastmath.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Base.FastMath
import Core.Intrinsics:
sqrt_llvm_fast,
sqrt_llvm,
neg_float_fast,
add_float_fast,
sub_float_fast,
Expand Down Expand Up @@ -161,7 +161,7 @@ pow_fast(x::Quantity, y::Integer) = x^y
pow_fast(x::Quantity, y::Rational) = x^y

sqrt_fast(x::Quantity{T}) where {T <: FloatTypes} =
Quantity(sqrt_llvm_fast(x.val), sqrt(unit(x)))
Quantity(sqrt_llvm(x.val), sqrt(unit(x)))

for f in (:cos, :sin, :tan)
f_fast = fast_op[f]
Expand Down
4 changes: 2 additions & 2 deletions src/logarithm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ Neper-based yield `ln`, and so on. Returns `x->log(base, x)` as a fallback.
function logfn end
logfn(x::LogInfo{N,10}) where {N} = log10
logfn(x::LogInfo{N,2}) where {N} = log2
logfn(x::LogInfo{N,e}) where {N} = log
logfn(x::LogInfo{N,}) where {N} = log
logfn(x::LogInfo{N,B}) where {N,B} = x->log(B,x)

"""
Expand All @@ -360,7 +360,7 @@ Neper-based yield `exp`, and so on. Returns `x->(base)^x` as a fallback.
function expfn end
expfn(x::LogInfo{N,10}) where {N} = exp10
expfn(x::LogInfo{N,2}) where {N} = exp2
expfn(x::LogInfo{N,e}) where {N} = exp
expfn(x::LogInfo{N,}) where {N} = exp
expfn(x::LogInfo{N,B}) where {N,B} = x->B^x

Base.rtoldefault(::Type{Level{L,S,T}}) where {L,S,T} =
Expand Down
42 changes: 28 additions & 14 deletions src/pkgdefaults.jl
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ Unitful.offsettemp(::Unitful.Unit{:Fahrenheit}) = 45967//100

@logscale dB "dB" Decibel 10 10 false
@logscale B "B" Bel 10 1 false
@logscale Np "Np" Neper e 1//2 true
@logscale cNp "cNp" Centineper e 50 true
@logscale Np "Np" Neper 1//2 true
@logscale cNp "cNp" Centineper 50 true

@logunit dBm "dBm" Decibel 1mW
@logunit dBV "dBV" Decibel 1V
Expand Down Expand Up @@ -254,17 +254,31 @@ consider invoking this function in your `.juliarc.jl` file which is loaded when
you open Julia. This function is not exported.
"""
function promote_to_derived()
Unitful.promote_unit(::S, ::T) where {S<:EnergyFreeUnits, T<:EnergyFreeUnits} = Unitful.J
Unitful.promote_unit(::S, ::T) where {S<:ForceFreeUnits, T<:ForceFreeUnits} = Unitful.N
Unitful.promote_unit(::S, ::T) where {S<:PowerFreeUnits, T<:PowerFreeUnits} = Unitful.W
Unitful.promote_unit(::S, ::T) where {S<:PressureFreeUnits, T<:PressureFreeUnits} = Unitful.Pa
Unitful.promote_unit(::S, ::T) where {S<:ChargeFreeUnits, T<:ChargeFreeUnits} = Unitful.C
Unitful.promote_unit(::S, ::T) where {S<:VoltageFreeUnits, T<:VoltageFreeUnits} = Unitful.V
Unitful.promote_unit(::S, ::T) where {S<:ResistanceFreeUnits, T<:ResistanceFreeUnits} = Unitful.Ω
Unitful.promote_unit(::S, ::T) where {S<:CapacitanceFreeUnits, T<:CapacitanceFreeUnits} = Unitful.F
Unitful.promote_unit(::S, ::T) where {S<:InductanceFreeUnits, T<:InductanceFreeUnits} = Unitful.H
Unitful.promote_unit(::S, ::T) where {S<:MagneticFluxFreeUnits, T<:MagneticFluxFreeUnits} = Unitful.Wb
Unitful.promote_unit(::S, ::T) where {S<:BFieldFreeUnits, T<:BFieldFreeUnits} = Unitful.T
Unitful.promote_unit(::S, ::T) where {S<:ActionFreeUnits, T<:ActionFreeUnits} = Unitful.J * Unitful.s
eval(quote
Unitful.promote_unit(::S, ::T) where
{S<:EnergyFreeUnits, T<:EnergyFreeUnits} = Unitful.J
Unitful.promote_unit(::S, ::T) where
{S<:ForceFreeUnits, T<:ForceFreeUnits} = Unitful.N
Unitful.promote_unit(::S, ::T) where
{S<:PowerFreeUnits, T<:PowerFreeUnits} = Unitful.W
Unitful.promote_unit(::S, ::T) where
{S<:PressureFreeUnits, T<:PressureFreeUnits} = Unitful.Pa
Unitful.promote_unit(::S, ::T) where
{S<:ChargeFreeUnits, T<:ChargeFreeUnits} = Unitful.C
Unitful.promote_unit(::S, ::T) where
{S<:VoltageFreeUnits, T<:VoltageFreeUnits} = Unitful.V
Unitful.promote_unit(::S, ::T) where
{S<:ResistanceFreeUnits, T<:ResistanceFreeUnits} = Unitful.Ω
Unitful.promote_unit(::S, ::T) where
{S<:CapacitanceFreeUnits, T<:CapacitanceFreeUnits} = Unitful.F
Unitful.promote_unit(::S, ::T) where
{S<:InductanceFreeUnits, T<:InductanceFreeUnits} = Unitful.H
Unitful.promote_unit(::S, ::T) where
{S<:MagneticFluxFreeUnits, T<:MagneticFluxFreeUnits} = Unitful.Wb
Unitful.promote_unit(::S, ::T) where
{S<:BFieldFreeUnits, T<:BFieldFreeUnits} = Unitful.T
Unitful.promote_unit(::S, ::T) where
{S<:ActionFreeUnits, T<:ActionFreeUnits} = Unitful.J * Unitful.s
end)
nothing
end
36 changes: 25 additions & 11 deletions src/quantities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,13 @@ isless(x::Quantity, y::Quantity) = _isless(promote(x,y)...)
isless(x::Quantity, y::Number) = _isless(promote(x,y)...)
isless(x::Number, y::Quantity) = _isless(promote(x,y)...)

@inline <(x::Quantity{T,D,U}, y::Quantity{T,D,U}) where {T,D,U} = _lt(x,y)
<(x::Quantity, y::Quantity) = _lt(x,y)
@inline _lt(x::Quantity{T,D,U}, y::Quantity{T,D,U}) where {T,D,U} = <(x.val,y.val)
@inline _lt(x::Quantity{T,D,U1}, y::Quantity{T,D,U2}) where {T,D,U1,U2} = <(promote(x,y)...)
@inline _lt(x::Quantity{T,D1,U1}, y::Quantity{T,D2,U2}) where {T,D1,D2,U1,U2} = throw(DimensionError(x,y))
@inline _lt(x,y) = <(x,y)

<(x::Quantity, y::Quantity) = _lt(promote(x,y)...)
<(x::Quantity, y::Number) = _lt(promote(x,y)...)
<(x::Number, y::Quantity) = _lt(promote(x,y)...)
<(x::Quantity, y::Number) = <(promote(x,y)...)
<(x::Number, y::Quantity) = <(promote(x,y)...)

Base.rtoldefault(::Type{Quantity{T,D,U}}) where {T,D,U} = Base.rtoldefault(T)
isapprox(x::Quantity{T,D,U}, y::Quantity{T,D,U}; atol=zero(Quantity{real(T),D,U}), kwargs...) where {T,D,U} =
Expand All @@ -223,7 +222,7 @@ isapprox(x::Quantity, y::Number; kwargs...) = isapprox(promote(x,y)...; kwargs..
isapprox(x::Number, y::Quantity; kwargs...) = isapprox(y, x; kwargs...)

function isapprox(x::AbstractArray{Quantity{T1,D,U1}},
y::AbstractArray{Quantity{T2,D,U2}}; rtol::Real=Base.rtoldefault(T1,T2),
y::AbstractArray{Quantity{T2,D,U2}}; rtol::Real=Base.rtoldefault(T1,T2,0),
atol=zero(Quantity{T1,D,U1}), norm::Function=vecnorm) where {T1,D,U1,T2,U2}

d = norm(x - y)
Expand Down Expand Up @@ -345,15 +344,30 @@ typemin(x::Quantity{T}) where {T} = typemin(T)*unit(x)
typemax(::Type{Quantity{T,D,U}}) where {T,D,U} = typemax(T)*U()
typemax(x::Quantity{T}) where {T} = typemax(T)*unit(x)

Base.literal_pow(::typeof(^), x::Quantity, ::Type{Val{v}}) where {v} =
Quantity(Base.literal_pow(^, x.val, Val{v}),
Base.literal_pow(^, unit(x), Val{v}))
@static if VERSION < v"0.7.0-DEV.843"
Base.literal_pow(::typeof(^), x::Quantity, ::Type{Val{v}}) where {v} =
Quantity(Base.literal_pow(^, x.val, Val{v}),
Base.literal_pow(^, unit(x), Val{v}))
else
Base.literal_pow(::typeof(^), x::Quantity, ::Val{v}) where {v} =
Quantity(Base.literal_pow(^, x.val, Val(v)),
Base.literal_pow(^, unit(x), Val(v)))
end

# All of these are needed for ambiguity resolution
^(x::Quantity, y::Integer) = Quantity((x.val)^y, unit(x)^y)
^(x::Quantity, y::Rational) = Quantity((x.val)^y, unit(x)^y)
^(x::Quantity, y::Real) = Quantity((x.val)^y, unit(x)^y)

Base.rand(r::AbstractRNG, ::Type{Quantity{T,D,U}}) where {T,D,U} = rand(r,T)*U()
Base.ones(Q::Type{<:Quantity}, dims::Tuple) = fill!(Array{Q}(dims), oneunit(Q))
@static if VERSION >= v"0.7.0-DEV.2708" #julia PR 23964
Base.rand(r::AbstractRNG, ::Base.Random.SamplerType{Quantity{T,D,U}}) where {T,D,U} =
rand(r, T) * U()
else
Base.rand(r::AbstractRNG, ::Type{Quantity{T,D,U}}) where {T,D,U} = rand(r,T) * U()
end
@static if VERSION >= v"0.7.0-DEV.2581" #julia PR 24652
Base.ones(Q::Type{<:Quantity}, dims::Tuple) = fill!(Array{Q}(uninitialized, dims), oneunit(Q))
else
Base.ones(Q::Type{<:Quantity}, dims::Tuple) = fill!(Array{Q}(dims), oneunit(Q))
end
Base.ones(a::AbstractArray, Q::Type{<:Quantity}) = fill!(similar(a,Q), oneunit(Q))
17 changes: 9 additions & 8 deletions src/range.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
*(y::Units, r::Range) = *(r,y)
*(r::Range, y::Units) = range(first(r)*y, step(r)*y, length(r))
*(r::Range, y::Units, z::Units...) = *(x, *(y,z...))
using Compat: AbstractRange

*(y::Units, r::AbstractRange) = *(r,y)
*(r::AbstractRange, y::Units) = range(first(r)*y, step(r)*y, length(r))
*(r::AbstractRange, y::Units, z::Units...) = *(x, *(y,z...))

Base.linspace(start::Quantity{<:Real}, stop, len::Integer) =
_linspace(promote(start, stop)..., len)
Expand Down Expand Up @@ -79,11 +81,10 @@ range(a::Quantity{<:Real}, st::Quantity{<:AbstractFloat}, len::Integer) =
range(float(a), st, len)
range(a::Quantity{<:AbstractFloat}, st::Quantity{<:Real}, len::Integer) =
range(a, float(st), len)
range(a::Quantity{<:AbstractFloat}, st::Quantity{<:AbstractFloat}, len::Integer) =
_range(promote(a, st)..., len)
_range(a::T, st::T, len) where {T<:Quantity} = range(a, st, len)
_range(a, st, len) = throw(DimensionError(a, st))

function range(a::Quantity{<:AbstractFloat}, st::Quantity{<:AbstractFloat}, len::Integer)
dimension(a) != dimension(st) && throw(DimensionError(a, st))
range(promote(a, st)..., len)
end
range(a::Quantity, st::Real, len::Integer) = range(promote(a, st)..., len)
range(a::Real, st::Quantity, len::Integer) = range(promote(a, st)..., len)

Expand Down
39 changes: 27 additions & 12 deletions src/units.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
# results in:
# [nm,cm^6,m^6,µs^3,s]

d = (c...)
d = (c...,)
f = typeof(mapreduce(dimension, *, NoDims, d))
:(FreeUnits{$d,$f}())
end
Expand Down Expand Up @@ -107,17 +107,32 @@ true
^(x::FixedUnits{N}, y::Integer) where {N} = *(FixedUnits{map(a->a^y, N), ()}())
^(x::FixedUnits{N}, y::Number) where {N} = *(FixedUnits{map(a->a^y, N), ()}())

@generated function Base.literal_pow(::typeof(^), x::FreeUnits{N}, ::Type{Val{p}}) where {N,p}
y = *(FreeUnits{map(a->a^p, N), ()}())
:($y)
end
@generated function Base.literal_pow(::typeof(^), x::ContextUnits{N,D,P}, ::Type{Val{p}}) where {N,D,P,p}
y = *(ContextUnits{map(a->a^p, N), (), typeof(P()^p)}())
:($y)
end
@generated function Base.literal_pow(::typeof(^), x::FixedUnits{N}, ::Type{Val{p}}) where {N,p}
y = *(FixedUnits{map(a->a^p, N), ()}())
:($y)
@static if VERSION < v"0.7.0-DEV.843"
@generated function Base.literal_pow(::typeof(^), x::FreeUnits{N}, ::Type{Val{p}}) where {N,p}
y = *(FreeUnits{map(a->a^p, N), ()}())
:($y)
end
@generated function Base.literal_pow(::typeof(^), x::ContextUnits{N,D,P}, ::Type{Val{p}}) where {N,D,P,p}
y = *(ContextUnits{map(a->a^p, N), (), typeof(P()^p)}())
:($y)
end
@generated function Base.literal_pow(::typeof(^), x::FixedUnits{N}, ::Type{Val{p}}) where {N,p}
y = *(FixedUnits{map(a->a^p, N), ()}())
:($y)
end
else
@generated function Base.literal_pow(::typeof(^), x::FreeUnits{N}, ::Val{p}) where {N,p}
y = *(FreeUnits{map(a->a^p, N), ()}())
:($y)
end
@generated function Base.literal_pow(::typeof(^), x::ContextUnits{N,D,P}, ::Val{p}) where {N,D,P,p}
y = *(ContextUnits{map(a->a^p, N), (), typeof(P()^p)}())
:($y)
end
@generated function Base.literal_pow(::typeof(^), x::FixedUnits{N}, ::Val{p}) where {N,p}
y = *(FixedUnits{map(a->a^p, N), ()}())
:($y)
end
end

# Since exponentiation is not type stable, we define a special `inv` method to enable fast
Expand Down
Loading

0 comments on commit c54ddaf

Please sign in to comment.