Skip to content

Commit d3b1081

Browse files
committed
Merge branch 'additional-utils' into abstract-types-2
2 parents 88da738 + 2412d55 commit d3b1081

File tree

5 files changed

+46
-11
lines changed

5 files changed

+46
-11
lines changed

src/fixed_rational.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ Base.convert(::Type{Rational{R}}, x::F) where {R,F<:FixedRational} = Rational{R}
4343
Base.convert(::Type{Rational}, x::F) where {F<:FixedRational} = Rational{eltype(F)}(x.num, denom(F))
4444
Base.convert(::Type{AF}, x::F) where {AF<:AbstractFloat,F<:FixedRational} = convert(AF, x.num) / convert(AF, denom(F))
4545
Base.round(::Type{T}, x::F) where {T,F<:FixedRational} = div(convert(T, x.num), convert(T, denom(F)), RoundNearest)
46+
Base.promote(x::Integer, y::F) where {F<:FixedRational} = (F(x), y)
47+
Base.promote(x::F, y::Integer) where {F<:FixedRational} = (x, F(y))
4648
Base.promote(x, y::F) where {F<:FixedRational} = promote(x, convert(Rational, y))
4749
Base.promote(x::F, y) where {F<:FixedRational} = promote(convert(Rational, x), y)
4850
Base.show(io::IO, x::F) where {F<:FixedRational} = show(io, convert(Rational, x))

src/math.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ Base.:+(l, r::AbstractQuantity) = dimension(l) == dimension(r) ? new_quantity(ty
2525
Base.:-(l::AbstractQuantity, r) = l + (-r)
2626
Base.:-(l, r::AbstractQuantity) = l + (-r)
2727

28-
_pow(l::AbstractDimensions{R}, r::R) where {R} = map_dimensions(Base.Fix1(*, r), l)
29-
_pow(l::AbstractQuantity{T,R}, r::R) where {T,R} = new_quantity(typeof(l), ustrip(l)^convert(T, r), _pow(dimension(l), r))
28+
_pow(l::AbstractDimensions, r) = map_dimensions(Base.Fix1(*, r), l)
29+
_pow(l::AbstractQuantity{T}, r) where {T} = new_quantity(typeof(l), ustrip(l)^r, _pow(dimension(l), r))
30+
_pow_as_T(l::AbstractQuantity{T}, r) where {T} = new_quantity(typeof(l), ustrip(l)^convert(T, r), _pow(l.dimensions, r))
31+
Base.:^(l::AbstractDimensions{R}, r::Integer) where {R} = _pow(l, r)
3032
Base.:^(l::AbstractDimensions{R}, r::Number) where {R} = _pow(l, tryrationalize(R, r))
31-
Base.:^(l::AbstractQuantity{T,R}, r::Number) where {T,R} = _pow(l, tryrationalize(R, r))
33+
Base.:^(l::AbstractQuantity{T,R}, r::Integer) where {T,R} = _pow(l, r)
34+
Base.:^(l::AbstractQuantity{T,R}, r::Number) where {T,R} = _pow_as_T(l, tryrationalize(R, r))
3235

3336
Base.inv(d::AbstractDimensions) = map_dimensions(-, d)
3437
Base.inv(q::AbstractQuantity) = new_quantity(typeof(q), inv(ustrip(q)), inv(dimension(q)))

src/units.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ end
1515
function _add_prefixes(base_unit::Symbol, prefixes)
1616
all_prefixes = (
1717
f=1e-15, p=1e-12, n=1e-9, μ=1e-6, u=1e-6, m=1e-3, c=1e-2, d=1e-1,
18-
k=1e3, M=1e6, G=1e9, T=1e12, P=1e15
18+
k=1e3, M=1e6, G=1e9
1919
)
2020
expr = Expr(:block)
2121
for (prefix, value) in zip(keys(all_prefixes), values(all_prefixes))
@@ -90,11 +90,6 @@ const bar = 100 * kPa
9090

9191
@add_prefixes bar ()
9292

93-
## Energy
94-
const eV = 1.602176634e-19 * J
95-
96-
@add_prefixes eV (m, k, M, G, T)
97-
9893
# Do not wish to define Gaussian units, as it changes
9994
# some formulas. Safer to force user to work exclusively in one unit system.
10095

@@ -109,9 +104,13 @@ corresponding `Quantity` object. For example, `uparse("m/s")`
109104
would be parsed to `Quantity(1.0, length=1, time=-1)`.
110105
"""
111106
function uparse(s::AbstractString)
112-
return eval(Meta.parse(s))::Quantity{DEFAULT_VALUE_TYPE,DEFAULT_DIM_TYPE}
107+
return as_quantity(eval(Meta.parse(s)))::Quantity{DEFAULT_VALUE_TYPE,DEFAULT_DIM_TYPE}
113108
end
114109

110+
as_quantity(q::Quantity) = q
111+
as_quantity(x::Number) = Quantity(convert(DEFAULT_VALUE_TYPE, x), DEFAULT_DIM_TYPE)
112+
as_quantity(x) = error("Unexpected type evaluated: $(typeof(x))")
113+
115114
"""
116115
@u_str(s::AbstractString)
117116

src/utils.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ Base.iszero(q::AbstractQuantity) = iszero(ustrip(q))
4040
Base.getindex(d::AbstractDimensions, k::Symbol) = getfield(d, k)
4141
Base.:(==)(l::AbstractDimensions, r::AbstractDimensions) = all_dimensions(==, l, r)
4242
Base.:(==)(l::AbstractQuantity, r::AbstractQuantity) = ustrip(l) == ustrip(r) && dimension(l) == dimension(r)
43+
Base.:(==)(l, r::AbstractQuantity) = ustrip(l) == ustrip(r) && dimension(l) == dimension(r)
44+
Base.:(==)(l::AbstractQuantity, r) = ustrip(l) == ustrip(r) && dimension(l) == dimension(r)
45+
Base.isless(l::AbstractQuantity, r::AbstractQuantity) = dimension(l) == dimension(r) ? isless(ustrip(l), ustrip(r)) : throw(DimensionError(l, r))
46+
Base.isless(l::AbstractQuantity, r) = dimension(l) == dimension(r) ? isless(ustrip(l), r) : throw(DimensionError(l, r))
47+
Base.isless(l, r::AbstractQuantity) = dimension(l) == dimension(r) ? isless(l, ustrip(r)) : throw(DimensionError(l, r))
4348
Base.isapprox(l::AbstractQuantity, r::AbstractQuantity; kws...) = isapprox(ustrip(l), ustrip(r); kws...) && dimension(l) == dimension(r)
4449
Base.length(::AbstractDimensions) = 1
4550
Base.length(::AbstractQuantity) = 1
@@ -54,7 +59,7 @@ Base.one(::Type{Quantity{T}}) where {T} = one(Quantity{T,DEFAULT_DIM_TYPE})
5459
Base.one(::Type{Quantity}) = one(Quantity{DEFAULT_VALUE_TYPE})
5560
Base.one(::Type{Dimensions{R}}) where {R} = Dimensions{R}()
5661
Base.one(::Type{Dimensions}) = one(Dimensions{DEFAULT_DIM_TYPE})
57-
Base.one(q::Quantity) = one(typeof(q))
62+
Base.one(q::Quantity) = Quantity(one(ustrip(q)), one(dimension(q)))
5863
Base.one(d::Dimensions) = one(typeof(d))
5964

6065
# Additive identities:

test/unittests.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ end
200200
@test one(Dimensions()) == Dimensions()
201201
@test typeof(one(Quantity)) == Quantity{DEFAULT_VALUE_TYPE,DEFAULT_DIM_TYPE}
202202
@test ustrip(one(Quantity)) === one(DEFAULT_VALUE_TYPE)
203+
@test typeof(one(Quantity(ones(32, 32)))) == Quantity{Matrix{Float64},DEFAULT_DIM_TYPE}
204+
@test dimension(one(Quantity(ones(32, 32), length=1))) == Dimensions()
203205

204206
x = Quantity(1, length=1)
205207

@@ -218,6 +220,19 @@ end
218220
@test cbrt(z) == Quantity(cbrt(-52), length=1 // 3, mass=2 // 3)
219221

220222
@test 1.0 * (Dimensions(length=3)^2) == Quantity(1.0, length=6)
223+
224+
x = 0.9u"km/s"
225+
y = 0.3 * x
226+
@test x > y
227+
@test y < x
228+
229+
x = Quantity(1.0)
230+
231+
@test x == 1.0
232+
@test x >= 1.0
233+
@test x < 2.0
234+
235+
@test_throws DimensionError x < 1.0u"m"
221236
end
222237

223238
@testset "Manual construction" begin
@@ -278,4 +293,15 @@ end
278293
z = u"yr"
279294
@test utime(z) == 1
280295
@test ustrip(z) 60 * 60 * 24 * 365.25
296+
297+
# Test type stability of extreme range of units
298+
@test typeof(u"1") == Quantity{Float64,DEFAULT_DIM_TYPE}
299+
@test typeof(u"1f0") == Quantity{Float64,DEFAULT_DIM_TYPE}
300+
@test typeof(u"s"^2) == Quantity{Float64,DEFAULT_DIM_TYPE}
301+
@test typeof(u"") == Quantity{Float64,DEFAULT_DIM_TYPE}
302+
@test typeof(u"Gyr") == Quantity{Float64,DEFAULT_DIM_TYPE}
303+
@test typeof(u"fm") == Quantity{Float64,DEFAULT_DIM_TYPE}
304+
@test typeof(u"fm"^2) == Quantity{Float64,DEFAULT_DIM_TYPE}
305+
306+
@test_throws LoadError eval(:(u":x"))
281307
end

0 commit comments

Comments
 (0)