From 8cf418fad5648a17c16d0db915b8aba778200671 Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sat, 14 Oct 2023 17:07:33 +0100 Subject: [PATCH 1/2] Add `uconvert` method for `QuantityArray` --- src/symbolic_dimensions.jl | 9 +++++++++ test/unittests.jl | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/symbolic_dimensions.jl b/src/symbolic_dimensions.jl index af5926a7..c5a3cfc6 100644 --- a/src/symbolic_dimensions.jl +++ b/src/symbolic_dimensions.jl @@ -106,6 +106,7 @@ function expand_units(q::Q) where {T,R,D<:SymbolicDimensions{R},Q<:AbstractQuant return convert(constructor_of(Q){T,Dimensions{R}}, q) end expand_units(q::QuantityArray) = expand_units.(q) +# TODO: Make the array-based one more efficient """ uconvert(qout::AbstractQuantity{<:Any, <:SymbolicDimensions}, q::AbstractQuantity{<:Any, <:Dimensions}) @@ -121,6 +122,14 @@ function uconvert(qout::AbstractQuantity{<:Any, <:SymbolicDimensions}, q::Abstra new_dim = dimension(qout) return new_quantity(typeof(q), new_val, new_dim) end +function uconvert(qout::AbstractQuantity{<:Any,<:SymbolicDimensions}, q::QuantityArray{<:Any,<:Any,<:Dimensions}) + qout_expanded = expand_units(qout) + dimension(q) == dimension(qout_expanded) || throw(DimensionError(q, qout_expanded)) + new_array = ustrip(q) ./ ustrip(qout_expanded) + new_dim = dimension(qout) + return QuantityArray(new_array, new_dim, quantity_type(q)) +end +# TODO: Method for converting SymbolicDimensions -> SymbolicDimensions """ uconvert(qout::AbstractQuantity{<:Any, <:SymbolicDimensions}) diff --git a/test/unittests.jl b/test/unittests.jl index bc3327c3..8ccc7e48 100644 --- a/test/unittests.jl +++ b/test/unittests.jl @@ -613,6 +613,22 @@ end qs = uconvert(convert(Quantity{Float16}, us"g"), 5 * q) @test typeof(qs) <: Quantity{Float16,<:SymbolicDimensions{<:Any}} @test qs ≈ 7.5us"g" + + # Arrays + x = [1.0, 2.0, 3.0] .* u"kg" + xs = x .|> uconvert(us"g") + @test typeof(xs) <: Vector{<:Quantity{Float64,<:SymbolicDimensions{<:Any}}} + @test xs[2] ≈ 2000us"g" + + x_qa = QuantityArray(x) + xs_qa = x_qa .|> uconvert(us"g") + @test typeof(xs_qa) <: QuantityArray{Float64,1,<:SymbolicDimensions{<:Any}} + @test xs_qa[2] ≈ 2000us"g" + + # Without vectorized call: + xs_qa2 = x_qa |> uconvert(us"g") + @test typeof(xs_qa2) <: QuantityArray{Float64,1,<:SymbolicDimensions{<:Any}} + @test xs_qa2[2] ≈ 2000us"g" end @testset "Test ambiguities" begin From 3333cd9733748c2c8b6074f648ac098f90f62189 Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sun, 15 Oct 2023 03:03:06 +0100 Subject: [PATCH 2/2] Add missing assert statement --- src/symbolic_dimensions.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/symbolic_dimensions.jl b/src/symbolic_dimensions.jl index c5a3cfc6..51db8e96 100644 --- a/src/symbolic_dimensions.jl +++ b/src/symbolic_dimensions.jl @@ -123,6 +123,7 @@ function uconvert(qout::AbstractQuantity{<:Any, <:SymbolicDimensions}, q::Abstra return new_quantity(typeof(q), new_val, new_dim) end function uconvert(qout::AbstractQuantity{<:Any,<:SymbolicDimensions}, q::QuantityArray{<:Any,<:Any,<:Dimensions}) + @assert isone(ustrip(qout)) "You passed a quantity with a non-unit value to uconvert." qout_expanded = expand_units(qout) dimension(q) == dimension(qout_expanded) || throw(DimensionError(q, qout_expanded)) new_array = ustrip(q) ./ ustrip(qout_expanded)