-
Notifications
You must be signed in to change notification settings - Fork 24
Add a scale factor dimension? #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think one could use Unitful as a comprehensive database for defining units and provide an API like:
etc. I set up something like this in LessUnitful.jl |
After thinking more about your proposal - may be this problem can be solved differently. After seeing some discussions around the pacakge, I think for performance reasons, is critical to keep the size of a quantity small. So the way forward may be to define the basic units |
Thanks for the interest @odow, I'm happy to hear you are considering using it! Just to help me understand the feature request, why couldn't you implicitly include the scale parameter inside the value of the quantity? Since the conversion from Unitful to DynamicQuantities uses julia> x_km = 1.5u"km"
1.5 km
julia> x = 1.5u"m"
1.5 m
julia> x_km_dyn = convert(DynamicQuantities.Quantity, x_km)
1500.0 𝐋 ¹
julia> x_dyn = convert(DynamicQuantities.Quantity, x)
1.5 𝐋 ¹ |
One other tricky thing about having a separate x = Quantity(0.2, length=1, scale=2)
y = Quantity(0.02, length=1, scale=3) and checking equality is no longer comparing If you have a |
I don't want to use Unitful. I want DynamicQuantities to be a complete replacement. Our problem is a JuMP user writing something like (hypothetical syntax): using JuMP, DynamicQuantities
m = Dimension(length = 1)
model = Model()
@variable(model, x, unit = m)
# User meant to type distance = 1000 * m, but actually types:
distance = 100 * m
@constraint(model, x >= distance) # No error. Unit typo not caught I'd like instead: using JuMP, DynamicQuantities
m = Dimension(length = 1)
km = Dimension(length = 1, scale = 3)
model = Model()
@variable(model, x, unit = m)
distance = 1km
@constraint(model, x >= distance) # Units don't match
This still permits typos. We want to check that the scale of each variable is the same at the type level. |
The key thing to note is that m = Quantity(1.0, length = 1)
km = 1e3 * m But you could similarly define these with any unit system, so long as you are consistent that "kilo" is 1000x the base unit for each dimension, and so forth. |
Correct. I guess you could have some normalization thing that always ensured the numeric value of the quantity was
I guess this is an open design question. It's useful to explore the space. There probably needs to be a few different attempts to see what works and what doesn't. |
I think this might not be a problem since And, |
This would be handled by JuMP. We'd want to make sure that the left-hand side had the same dimensions as the right-hand side, and if the scale was different, we'd automatically scale to correct it. |
Thanks, I understand a bit better now. It still feels like a fairly niche use-case though, so I'm not sure if it should be added to the struct in DynamicQuantities or not. It would incur ~15% slowdown (7->8) for all users (if not more, due to the extra Why not just use a Maybe we could even have an |
Yeah I guess I haven't thought through the practical implementation details. At a high level, I want the difference between In the near term, I'd encourage you to explore what you think is best for this package. It's useful to have a few opinionated attempts at different approaches. |
I thought about this a bit more. Maybe I'm asking for an orthogonal feature. I'm really asking for: struct ScaledValue{T}
value::T
scale::Int8
end and this could be completely independent of the unit/dimension/quantity discussion. It just happens to most commonly arise when discussing units. So yes, it could go in the |
Hm - isn't this already what Unitful does ? I personally find this too rigid. I think what may be missing here is what Unitful supports with This is essentially parametrized by reference values for all base quantities, maybe something could be done with value types.... |
Yeah. But Unitful has a nasty type signature, which is the reason to move to DynamicQuantities. |
I think your proposed solution of: struct ScaledValue{T}
value::T
scale::Int8
end is a good idea and the best compromise to this. Unitful would indeed let you detect Alternatively as @j-fu requested on #18, we could have an |
Just got the following Idea (not sure if it is good though): put the scaling factor(s) into value type parameters. This would not affect "normal" arithmetics, but allow addition of quantites with different scaling factors only with explicit conversion: Some basic experiment:
I think one would need a scaling factor for each dimension, and this could be some equivalent of Please note that this so far is a quite spontaneous idea. Realization probably would put quite some burden on the compiler. |
Closing this since #32 was merged. Now you can work directly on the units of your choice: julia> q = 100us"cm * kPa"
100.0 cm kPa
julia> q^2
10000.0 cm² kPa² This is ~5x slower than the regular dimensions type, but this is still much faster than Unitful, as it stores the dimensions in a type-stable sparse vector. So I recommend this symbolic form be used for user interfaces, while the expanded version used for calculations. You can convert to regular dimensions from this symbolic dimensions with julia> expand_units(q^2)
1.0e6 kg² s⁻⁴ This works for constants as well. For example, the speed of light: julia> x = us"Constants.c * Hz"
1.0 Hz c
julia> x^2
1.0 Hz² c²
julia> expand_units(x^2)
8.987551787368176e16 m² s⁻⁴ |
We're looking into adding this to JuMP: trulsf/UnitJuMP.jl#18
One kicker is that it'd be nice to be able to talk about micro/milli/kilo/mega etc.
Have you thought about adding a
scale::Int
dimension? Hopefully it'd support something like:The text was updated successfully, but these errors were encountered: