Skip to content

Commit bf35743

Browse files
committed
Constraint uconvert
1 parent 519356b commit bf35743

File tree

3 files changed

+53
-18
lines changed

3 files changed

+53
-18
lines changed

README.md

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,13 @@ julia> room_temp = 100kPa
9090
```
9191

9292
Note that `Units` is an exported submodule, so you can
93-
also access this as `Units.kPa`.
93+
also access this as `Units.kPa`. You may like to define
94+
95+
```julia
96+
julia> const U = Units; const C = Constants;
97+
```
98+
99+
so that you can simply write, say, `U.kPa` or `C.m_e`.
94100

95101
This supports a wide range of SI base and derived units, with common
96102
prefixes.
@@ -243,20 +249,7 @@ julia> using DynamicQuantities.SymbolicConstants: h
243249

244250
Note that `SymbolicUnits` and `SymbolicConstants` are exported,
245251
so you can simply access these as `SymbolicUnits.cm` and `SymbolicConstants.h`,
246-
respectively. I like to work with these like so:
247-
248-
```julia
249-
julia> const u = DynamicQuantities.SymbolicUnits;
250-
251-
julia> const C = DynamicQuantities.SymbolicConstants;
252-
```
253-
254-
so that I can simply write things like:
255-
256-
```julia
257-
julia> u.yr * C.c |> uexpand |> uconvert(u.km)
258-
```
259-
252+
respectively.
260253

261254
### Arrays
262255

src/symbolic_dimensions.jl

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,23 +171,55 @@ uexpand(q::QuantityArray) = uexpand.(q)
171171
Convert a quantity `q` with base SI units to the symbolic units of `qout`, for `q` and `qout` with compatible units.
172172
Mathematically, the result has value `q / uexpand(qout)` and units `dimension(qout)`.
173173
"""
174-
function uconvert(qout::UnionAbstractQuantity{<:Any, <:AbstractSymbolicDimensions}, q::UnionAbstractQuantity{<:Any, <:Dimensions})
174+
function uconvert(qout::UnionAbstractQuantity{<:Any, <:SymbolicDimensions}, q::UnionAbstractQuantity{<:Any, <:Dimensions})
175175
@assert isone(ustrip(qout)) "You passed a quantity with a non-unit value to uconvert."
176176
qout_expanded = uexpand(qout)
177177
dimension(q) == dimension(qout_expanded) || throw(DimensionError(q, qout_expanded))
178178
new_val = ustrip(q) / ustrip(qout_expanded)
179179
new_dim = dimension(qout)
180180
return new_quantity(typeof(q), new_val, new_dim)
181181
end
182-
function uconvert(qout::UnionAbstractQuantity{<:Any,<:AbstractSymbolicDimensions}, q::QuantityArray{<:Any,<:Any,<:Dimensions})
182+
function uconvert(qout::UnionAbstractQuantity{<:Any,<:SymbolicDimensions}, q::QuantityArray{<:Any,<:Any,<:Dimensions})
183183
@assert isone(ustrip(qout)) "You passed a quantity with a non-unit value to uconvert."
184184
qout_expanded = uexpand(qout)
185185
dimension(q) == dimension(qout_expanded) || throw(DimensionError(q, qout_expanded))
186186
new_array = ustrip(q) ./ ustrip(qout_expanded)
187187
new_dim = dimension(qout)
188188
return QuantityArray(new_array, new_dim, quantity_type(q))
189189
end
190-
# TODO: Method for converting SymbolicDimensions -> SymbolicDimensions
190+
191+
# Ensure we always do operations with SymbolicDimensions:
192+
function uconvert(
193+
qout::UnionAbstractQuantity{T,<:SymbolicDimensionsSingleton{R}},
194+
q::Union{
195+
<:UnionAbstractQuantity{<:Any,<:Dimensions},
196+
<:QuantityArray{<:Any,<:Any,<:Dimensions},
197+
},
198+
) where {T,R}
199+
return uconvert(
200+
convert(
201+
with_type_parameters(
202+
typeof(qout),
203+
T,
204+
with_type_parameters(SymbolicDimensions, R),
205+
),
206+
qout,
207+
),
208+
q,
209+
)
210+
end
211+
212+
# Allow user to convert SymbolicDimensions -> SymbolicDimensions
213+
function uconvert(
214+
qout::UnionAbstractQuantity{<:Any,<:AbstractSymbolicDimensions{R}},
215+
q::Union{
216+
<:UnionAbstractQuantity{<:Any,<:AbstractSymbolicDimensions},
217+
<:QuantityArray{<:Any,<:Any,<:AbstractSymbolicDimensions},
218+
},
219+
) where {R}
220+
return uconvert(qout, uexpand(q))
221+
end
222+
191223

192224
"""
193225
uconvert(qout::UnionAbstractQuantity{<:Any, <:AbstractSymbolicDimensions})

test/unittests.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,16 @@ end
17531753
@test map_dimensions(+, SymbolicDimensions(dimension(km)), dimension(m)).km == 1
17541754
@test map_dimensions(+, SymbolicDimensions(dimension(km)), dimension(m)).m == 1
17551755
@test map_dimensions(+, SymbolicDimensions(dimension(km)), dimension(m)).cm == 0
1756+
1757+
# Note that we avoid converting to SymbolicDimensionsSingleton for uconvert:
1758+
@test km |> uconvert(us"m") == 1000m
1759+
@test km |> uconvert(us"m") isa Quantity{T,SymbolicDimensions{R}} where {T,R}
1760+
@test [km, km] isa Vector{Quantity{T,SymbolicDimensionsSingleton{R}}} where {T,R}
1761+
@test [km^2, km] isa Vector{Quantity{T,SymbolicDimensions{R}}} where {T,R}
1762+
1763+
# Symbolic dimensions retain symbols:
1764+
@test QuantityArray([km, km]) |> uconvert(us"m") == [1000m, 1000m]
1765+
@test QuantityArray([km, km]) |> uconvert(us"m") != [km, km]
17561766
end
17571767

17581768
@testset "Test div" begin

0 commit comments

Comments
 (0)