Skip to content

Commit

Permalink
Merge f927953 into 8dcd070
Browse files Browse the repository at this point in the history
  • Loading branch information
ajkeller34 committed Jul 2, 2018
2 parents 8dcd070 + f927953 commit 3a0476a
Show file tree
Hide file tree
Showing 17 changed files with 141 additions and 249 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ os:
- linux
# - osx # locally test on my MacBook Pro; OS X tests take too long on Travis CI
julia:
- 0.6
- 0.7-beta
- nightly
notifications:
email: false
matrix:
allow_failures:
- julia: nightly
# matrix:
# allow_failures:
# - julia: nightly
# uncomment the following lines to override the default test script
# script:
# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
Expand Down
3 changes: 1 addition & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
julia 0.6
Compat 0.57.0
julia 0.7-beta
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7.0-beta-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7.0-beta-win64.exe"

matrix:
allow_failures:
Expand Down
6 changes: 3 additions & 3 deletions docs/src/conversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ themselves. Here's an example.
```jldoctest
julia> using Unitful
julia> Unitful.promote_unit{S<:Unitful.EnergyUnits, T<:Unitful.EnergyUnits}(::S, ::T) = u"g*cm^2/s^2"
julia> Unitful.promote_unit(::S, ::T) where {S<:Unitful.EnergyUnits, T<:Unitful.EnergyUnits} = u"g*cm^2/s^2"
julia> promote(2.0u"J", 1.0u"kg*m^2/s^2")
(2.0e7 g cm^2 s^-2, 1.0e7 g cm^2 s^-2)
julia> Unitful.promote_unit{S<:Unitful.EnergyUnits, T<:Unitful.EnergyUnits}(::S, ::T) = u"J"
julia> Unitful.promote_unit(::S, ::T) where {S<:Unitful.EnergyUnits, T<:Unitful.EnergyUnits} = u"J"
julia> promote(2.0u"J", 1.0u"kg*m^2/s^2")
(2.0 J, 1.0 J)
Expand Down Expand Up @@ -170,7 +170,7 @@ An additional benefit of having a concrete type is that we can dispatch on the
dimensions of the array's elements:

```jldoctest
julia> f{T<:Unitful.Length}(x::AbstractArray{T}) = sum(x)
julia> f(x::AbstractArray{T}) where {T<:Unitful.Length} = sum(x)
f (generic function with 1 method)
julia> f([1.0u"m", 2.0u"cm"])
Expand Down
9 changes: 4 additions & 5 deletions src/Unitful.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
__precompile__(true)
module Unitful
using Compat

import Base: ==, <, <=, +, -, *, /, //, ^
import Base: show, convert
import Base: abs, abs2, angle, float, fma, muladd, inv, sqrt, cbrt
import Base: min, max, floor, ceil, real, imag, conj
import Base: exp, exp10, exp2, expm1, log, log10, log1p, log2
import Base: sin, cos, tan, cot, sec, csc, atan2, cis
import Base: sin, cos, tan, cot, sec, csc, atan, cis

import Base: eps, mod, rem, div, fld, cld, trunc, round, sign, signbit
import Base: isless, isapprox, isinteger, isreal, isinf, isfinite, isnan
Expand All @@ -18,9 +17,9 @@ import Base: getindex, eltype, step, last, first, frexp
import Base: Integer, Rational, typemin, typemax
import Base: steprange_last, unsigned

import Compat.LinearAlgebra: Diagonal, Bidiagonal, Tridiagonal, SymTridiagonal
import Compat.LinearAlgebra: istril, istriu, vecnorm
import Compat: Random
import LinearAlgebra: Diagonal, Bidiagonal, Tridiagonal, SymTridiagonal
import LinearAlgebra: istril, istriu, norm
import Random

export logunit, unit, dimension, uconvert, ustrip, upreferred
export @dimension, @derived_dimension, @refunit, @unit, @u_str
Expand Down
13 changes: 3 additions & 10 deletions src/dimensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,9 @@ end
^(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)}())

@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
@generated function Base.literal_pow(::typeof(^), x::Dimensions{T}, ::Val{p}) where {T,p}
z = *(Dimensions{map(a->a^p, T)}())
:($z)
end

# Since exponentiation is not type stable, we define a special `inv` method to enable fast
Expand Down
2 changes: 1 addition & 1 deletion src/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,5 @@ end
Prints exponents.
"""
function superscript(i::Rational)
i.den == 1 ? "^"*string(i.num) : "^"*replace(string(i),"//","/")
i.den == 1 ? "^" * string(i.num) : "^" * replace(string(i), "//" => "/")
end
10 changes: 4 additions & 6 deletions src/fastmath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Base.FastMath: @fastmath,
le_fast,
pow_fast,
sqrt_fast,
atan2_fast,
atan_fast,
hypot_fast,
max_fast,
min_fast,
Expand Down Expand Up @@ -173,10 +173,8 @@ for f in (:cos, :sin, :tan)
end
end

atan2_fast(x::Quantity{Float32,D,U}, y::Quantity{Float32,D,U}) where {D,U} =
ccall(("atan2f",libm), Float32, (Float32,Float32), x.val, y.val)
atan2_fast(x::Quantity{Float64,D,U}, y::Quantity{Float64,D,U}) where {D,U} =
ccall(("atan2",libm), Float64, (Float64,Float64), x.val, y.val)
atan_fast(x::Quantity{T,D,U}, y::Quantity{T,D,U}) where {T,D,U} =
atan_fast(x.val, y.val)

@fastmath begin
hypot_fast(x::Quantity{T,D,U}, y::Quantity{T,D,U}) where {T <: FloatTypes,D,U} =
Expand All @@ -196,5 +194,5 @@ atan2_fast(x::Quantity{Float64,D,U}, y::Quantity{Float64,D,U}) where {D,U} =
cis_fast(x::DimensionlessQuantity{T,U}) where {T <: FloatTypes,U} =
Complex{T}(cos(x), sin(x))

angle_fast(x::Quantity{T}) where {T <: ComplexTypes} = atan2(imag(x), real(x))
angle_fast(x::Quantity{T}) where {T <: ComplexTypes} = atan(imag(x), real(x))
end
4 changes: 1 addition & 3 deletions src/logarithm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,4 @@ macro _doctables(x)
end)
end

@static if VERSION >= v"0.7.0-DEV.4659"
Base.broadcastable(x::MixedUnits) = Ref(x)
end
Base.broadcastable(x::MixedUnits) = Ref(x)
2 changes: 1 addition & 1 deletion src/pkgdefaults.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const ha = Unitful.FreeUnits{(Unitful.Unit{:Are, Unitful.Dimensions{
@unit L "L" Liter m^3//1000 true
for p in (:y, :z, :a, :f, :p, :n, , , :m, :c, :d,
Symbol(""), :da, :h, :k, :M, :G, :T, :P, :E, :Z, :Y)
eval(Unitful, :(const $(Symbol(p,:l)) = $(Symbol(p,:L))))
Core.eval(Unitful, :(const $(Symbol(p,:l)) = $(Symbol(p,:L))))
end

# Energy
Expand Down
4 changes: 1 addition & 3 deletions src/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,4 @@ Base.promote_rule(::Type{Quantity{T}}, ::Type{Quantity{S,D,U}}) where {T,S,D,U}
Base.promote_rule(::Type{Quantity{S,D,U}}, ::Type{Quantity{T}}) where {T,S,D,U} =
Quantity{promote_type(T,S)}

@static if VERSION >= v"0.7.0-DEV.3591"
Base.promote_typejoin(::Type{T}, ::Type{Quantity{T,D,U}}) where {T,D,U} = Quantity{T}
end
Base.promote_typejoin(::Type{T}, ::Type{Quantity{T,D,U}}) where {T,D,U} = Quantity{T}
40 changes: 13 additions & 27 deletions src/quantities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ for _y in (:sin, :cos, :tan, :cot, :sec, :csc, :cis)
@eval ($_y)(x::DimensionlessQuantity) = ($_y)(uconvert(NoUnits, x))
end

atan2(y::Quantity, x::Quantity) = atan2(promote(y,x)...)
atan2(y::Quantity{T,D,U}, x::Quantity{T,D,U}) where {T,D,U} = atan2(y.val,x.val)
atan2(y::Quantity{T,D1,U1}, x::Quantity{T,D2,U2}) where {T,D1,U1,D2,U2} =
atan(y::Quantity, x::Quantity) = atan(promote(y,x)...)
atan(y::Quantity{T,D,U}, x::Quantity{T,D,U}) where {T,D,U} = atan(y.val,x.val)
atan(y::Quantity{T,D1,U1}, x::Quantity{T,D2,U2}) where {T,D1,U1,D2,U2} =
throw(DimensionError(x,y))

for (f, F) in [(:min, :<), (:max, :>)]
Expand Down Expand Up @@ -203,7 +203,7 @@ 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,0),
atol=zero(Quantity{T1,D,U1}), norm::Function=vecnorm) where {T1,D,U1,T2,U2}
atol=zero(Quantity{T1,D,U1}), norm::Function=norm) where {T1,D,U1,T2,U2}

d = norm(x - y)
if isfinite(d)
Expand Down Expand Up @@ -274,7 +274,7 @@ real(x::Quantity) = Quantity(real(x.val), unit(x))
imag(x::Quantity) = Quantity(imag(x.val), unit(x))
conj(x::Quantity) = Quantity(conj(x.val), unit(x))

@inline vecnorm(x::Quantity, p::Real=2) =
@inline norm(x::Quantity, p::Real=2) =
p == 0 ? (x==zero(x) ? typeof(abs(x))(0) : typeof(abs(x))(1)) : abs(x)

"""
Expand Down Expand Up @@ -324,32 +324,18 @@ 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)

@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
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)))

# 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)

@static if VERSION >= v"0.7.0-DEV.2708" #julia PR 23964
Base.rand(r::Random.AbstractRNG, ::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.4873" #julia PR 24652
Base.ones(Q::Type{<:Quantity}, dims::NTuple{N,Integer}) where {N} =
fill!(Array{Q,N}(undef, map(Base.to_dim, dims)), oneunit(Q))
Base.ones(Q::Type{<:Quantity}, dims::Tuple{}) = fill!(Array{Q}(undef), oneunit(Q))
else
Base.ones(Q::Type{<:Quantity}, dims::Tuple) = fill!(Array{Q}(dims), oneunit(Q))
end
Base.rand(r::Random.AbstractRNG, ::Random.SamplerType{Quantity{T,D,U}}) where {T,D,U} =
rand(r, T) * U()
Base.ones(Q::Type{<:Quantity}, dims::NTuple{N,Integer}) where {N} =
fill!(Array{Q,N}(undef, map(Base.to_dim, dims)), oneunit(Q))
Base.ones(Q::Type{<:Quantity}, dims::Tuple{}) = fill!(Array{Q}(undef), oneunit(Q))
Base.ones(a::AbstractArray, Q::Type{<:Quantity}) = fill!(similar(a,Q), oneunit(Q))
143 changes: 41 additions & 102 deletions src/range.jl
Original file line number Diff line number Diff line change
@@ -1,112 +1,51 @@
using Compat: AbstractRange

@static if VERSION < v"0.7.0-DEV.4003"
import Base.colon
else
const colon = Base.:(:)
end
const colon = Base.:(:)

import Base: ArithmeticRounds
@static if VERSION < v"0.7.0-DEV.3410"
import Base: TypeOrder, HasOrder, TypeArithmetic, ArithmeticOverflows
const OrderStyle = TypeOrder
const Ordered = HasOrder
const ArithmeticStyle = TypeArithmetic
const ArithmeticWraps = ArithmeticOverflows
else
import Base: OrderStyle, Ordered, ArithmeticStyle, ArithmeticWraps
end
import Base: OrderStyle, Ordered, ArithmeticStyle, ArithmeticWraps

*(y::Units, r::AbstractRange) = *(r,y)
*(r::AbstractRange, y::Units, z::Units...) = *(x, *(y,z...))

@static if VERSION < v"0.7.0-DEV.3981"
Base.linspace(start::Quantity{<:Real}, stop, len::Integer) =
_linspace(promote(start, stop)..., len)
Base.linspace(start, stop::Quantity{<:Real}, len::Integer) =
_linspace(promote(start, stop)..., len)
Base.linspace(start::Quantity{<:Real}, stop::Quantity{<:Real}, len::Integer) =
_linspace(promote(start, stop)..., len)
(Base.linspace(start::T, stop::T, len::Integer) where (T<:Quantity{<:Real})) =
LinSpace{T}(start, stop, len)
(Base.linspace(start::T, stop::T, len::Integer) where (T<:Quantity{<:Integer})) =
linspace(Float64, ustrip(start), ustrip(stop), len, 1)*unit(T)
function Base.linspace(start::T, stop::T, len::Integer) where (T<:Quantity{S}
where S<:Union{Float16,Float32,Float64})
linspace(ustrip(start), ustrip(stop), len) * unit(T)
end
function _linspace(start::Quantity{T}, stop::Quantity{T}, len::Integer) where {T}
dimension(start) != dimension(stop) && throw(DimensionError(start, stop))
linspace(start, stop, len)
end

function range(a::T, st::T, len::Integer) where (T<:Quantity{S}
where S<:Union{Float16,Float32,Float64})
return range(ustrip(a), ustrip(st), len) * unit(T)
end
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)
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)

# the following is needed to give sane error messages when doing e.g. range(1°, 2V, 5)
function range(a::T, step, len::Integer) where {T<:Quantity}
dimension(a) != dimension(step) && throw(DimensionError(a,step))
return Base._range(OrderStyle(T), ArithmeticStyle(T), a, step, len)
end

*(r::AbstractRange, y::Units) = range(first(r)*y, step(r)*y, length(r))
else
Base._range(start::Quantity{<:Real}, ::Nothing, stop, len::Integer) =
_range(promote(start, stop)..., len)
Base._range(start, ::Nothing, stop::Quantity{<:Real}, len::Integer) =
_range(promote(start, stop)..., len)
Base._range(start::Quantity{<:Real}, ::Nothing, stop::Quantity{<:Real}, len::Integer) =
_range(promote(start, stop)..., len)
(Base._range(start::T, ::Nothing, stop::T, len::Integer) where (T<:Quantity{<:Real})) =
LinRange{T}(start, stop, len)
(Base._range(start::T, ::Nothing, stop::T, len::Integer) where (T<:Quantity{<:Integer})) =
Base._linspace(Float64, ustrip(start), ustrip(stop), len, 1)*unit(T)
function Base._range(start::T, ::Nothing, stop::T, len::Integer) where (T<:Quantity{S}
Base._range(start::Quantity{<:Real}, ::Nothing, stop, len::Integer) =
_range(promote(start, stop)..., len)
Base._range(start, ::Nothing, stop::Quantity{<:Real}, len::Integer) =
_range(promote(start, stop)..., len)
Base._range(start::Quantity{<:Real}, ::Nothing, stop::Quantity{<:Real}, len::Integer) =
_range(promote(start, stop)..., len)
(Base._range(start::T, ::Nothing, stop::T, len::Integer) where (T<:Quantity{<:Real})) =
LinRange{T}(start, stop, len)
(Base._range(start::T, ::Nothing, stop::T, len::Integer) where (T<:Quantity{<:Integer})) =
Base._linspace(Float64, ustrip(start), ustrip(stop), len, 1)*unit(T)
function Base._range(start::T, ::Nothing, stop::T, len::Integer) where (T<:Quantity{S}
where S<:Union{Float16,Float32,Float64})
range(ustrip(start), stop=ustrip(stop), length=len) * unit(T)
end
function _range(start::Quantity{T}, stop::Quantity{T}, len::Integer) where {T}
dimension(start) != dimension(stop) && throw(DimensionError(start, stop))
Base._range(start, nothing, stop, len)
end
function Base._range(a::T, st::T, ::Nothing, len::Integer) where (T<:Quantity{S}
where S<:Union{Float16,Float32,Float64})
range(ustrip(start), stop=ustrip(stop), length=len) * unit(T)
end
function _range(start::Quantity{T}, stop::Quantity{T}, len::Integer) where {T}
dimension(start) != dimension(stop) && throw(DimensionError(start, stop))
Base._range(start, nothing, stop, len)
end

function Base._range(a::T, st::T, ::Nothing, len::Integer) where (T<:Quantity{S}
where S<:Union{Float16,Float32,Float64})
return Base._range(ustrip(a), ustrip(st), nothing, len) * unit(T)
end
Base._range(a::Quantity{<:Real}, st::Quantity{<:AbstractFloat}, ::Nothing, len::Integer) =
Base._range(float(a), st, nothing, len)
Base._range(a::Quantity{<:AbstractFloat}, st::Quantity{<:Real}, ::Nothing, len::Integer) =
Base._range(a, float(st), nothing, len)
function Base._range(a::Quantity{<:AbstractFloat}, st::Quantity{<:AbstractFloat}, ::Nothing, len::Integer)
dimension(a) != dimension(st) && throw(DimensionError(a, st))
Base._range(promote(a, st)..., nothing, len)
end
Base._range(a::Quantity, st::Real, ::Nothing, len::Integer) =
Base._range(promote(a, st)..., nothing, len)
Base._range(a::Real, st::Quantity, ::Nothing, len::Integer) =
Base._range(promote(a, st)..., nothing, len)

# the following is needed to give sane error messages when doing e.g. range(1°, 2V, 5)
function Base._range(a::T, step, ::Nothing, len::Integer) where {T<:Quantity}
dimension(a) != dimension(step) && throw(DimensionError(a,step))
return Base._rangestyle(OrderStyle(T), ArithmeticStyle(T), a, step, len)
end

*(r::AbstractRange, y::Units) = range(first(r)*y, step=step(r)*y, length=length(r))
return Base._range(ustrip(a), ustrip(st), nothing, len) * unit(T)
end
Base._range(a::Quantity{<:Real}, st::Quantity{<:AbstractFloat}, ::Nothing, len::Integer) =
Base._range(float(a), st, nothing, len)
Base._range(a::Quantity{<:AbstractFloat}, st::Quantity{<:Real}, ::Nothing, len::Integer) =
Base._range(a, float(st), nothing, len)
function Base._range(a::Quantity{<:AbstractFloat}, st::Quantity{<:AbstractFloat}, ::Nothing, len::Integer)
dimension(a) != dimension(st) && throw(DimensionError(a, st))
Base._range(promote(a, st)..., nothing, len)
end
Base._range(a::Quantity, st::Real, ::Nothing, len::Integer) =
Base._range(promote(a, st)..., nothing, len)
Base._range(a::Real, st::Quantity, ::Nothing, len::Integer) =
Base._range(promote(a, st)..., nothing, len)
# the following is needed to give sane error messages when doing e.g. range(1°, 2V, 5)
function Base._range(a::T, step, ::Nothing, len::Integer) where {T<:Quantity}
dimension(a) != dimension(step) && throw(DimensionError(a,step))
return Base._rangestyle(OrderStyle(T), ArithmeticStyle(T), a, step, len)
end
*(r::AbstractRange, y::Units) = range(first(r)*y, step=step(r)*y, length=length(r))

# first promote start and stop, leaving step alone
colon(start::A, step, stop::C) where {A<:Real,C<:Quantity} = colonstartstop(start,step,stop)
Expand Down Expand Up @@ -150,5 +89,5 @@ end
# No need to confuse things by changing the type once units are on there,
# if we can help it.
*(r::StepRangeLen, y::Units) = StepRangeLen(r.ref*y, r.step*y, length(r), r.offset)
*(r::Compat.LinRange, y::Units) = Compat.LinRange(r.start*y, r.stop*y, length(r))
*(r::LinRange, y::Units) = LinRange(r.start*y, r.stop*y, length(r))
*(r::StepRange, y::Units) = StepRange(r.start*y, r.step*y, r.stop*y)

0 comments on commit 3a0476a

Please sign in to comment.