-
Couldn't load subscription status.
- Fork 122
Define helpers for unitful interfaces. #698
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
base: master
Are you sure you want to change the base?
Conversation
This commit adds two simple functions `similar_dims` (and `similar_units`)
that return a `Quantity` type with the dimensions (and units)
constrained to those of the parameters
I found myself trying to write simulation code with strongly typed
interfaces, i.e. including information about the units. Initially I
wrote my interfaces like so:
```julia
const Meters = typeof(1.0m);
circumference_of_circle(r::Meters) = pi*r^2
```
However, when trying to autodiff through this code, I run into a
problem, because `Meters` has the numerical type `Float64` baked in, and
autodiff evaluates on a type `Quantity{Dual{Float64}}` (roughly).
We can instead define `Meters` like so:
```julia
const Meters{T<:Real} = Quantity{T, dimension(1.0m), unit(1.0m)}
circumference_of_circle(r::Meters{T}) where {T} = pi*r^2
circumference_of_circle(r::Quantity{T, dimension(1.0m), unit(1.0m)}) where {T} = pi*r^2
```
but I thought a better approach would be to provide some syntactic sugar
to this "unit constraint".
With this PR, we can write
```julia
circumference_of_circle(r::similar_dims(u"m")) where {T} = pi*r^2
circumference_of_circle(r::similar_units(u"m")) where {T} = pi*r^2
```
The difference is that the first one only constrains the dimension, and
the latter constrains both dimension and unit (i.e. doesn't allow e.g. `km`).
I'm happy to receive any feedback on the idea and the naming.
Other names could be e.g. `quantity_with_dims` (but too long for my
taste), or `dims_as` etc., but `similar` is already Julia lingo and
feels appropriate in this context.
|
Instead of
Is there a reason for only allowing |
Rewrite the tests as type-checks only as suggested in the PR review. Co-authored-by: Sebastian Stock <42280794+sostock@users.noreply.github.com>
|
Thanks for the review. To your points:
That is true for "atomic" dimensions, but becomes much more difficult for any composite dimensions (e.g. energy). julia> kinetic_energy(mass::WithUnits(kg), velocity::WithUnits(m/s))::WithUnits(J) = mass*velocity^2 |> x->uconvert(J, x)
julia> kinetic_energy(1000kg, uconvert(m/s, 100km/hr))
62500000//81 J
import Uniful: Length, Time
kinetic_energy(mass::Mass, velocity::Length/Time) = mass*velocity^2
That is true, and until I read your comment I have also never considered non-real unitful quantities.
|
That is true, I can get to that still. There seems to be |
Using complex numbers for electrical units like voltage, current, or impedance is a very common case in electrical engineering.
Sure. It is "only" a way of concise representation of complex relations. But then, most of the mathematics is "only" a way of concise representation of complex relations.
Complex numbers can be equally used to represent oscillation processes of any nature, be it mechanical or electromagnetic. Both length (displacement) and current can be "complex-valued" in this sense. |
Summary
This commit adds two simple functions
WithDims(andWithUnits) that return aQuantitytype with the dimensions (and units) constrained to those of the parametersWith this PR, we can write
The difference between
WithDimsandWithUnitsthe two is that the first one only constrains the dimension, and the latter constrains both dimension and unit (i.e. doesn't allow e.g.km) -- see Units vs Dims.Rationale
I found myself trying to write simulation code with strongly typed interfaces, i.e. including information about the units. Initially I wrote my interfaces like so:
However, when trying to autodiff through this code, I run into a problem, because
Metershas the numerical typeFloat64baked in, and autodiff evaluates on a typeQuantity{Dual{Float64}}(roughly).We can instead define
Meterslike so:but I thought a better approach would be to provide some syntactic sugar to this "unit constraint".
This led to the construction of the syntactic sugar described in the summary.
I'm happy to receive any feedback on the idea and the naming. Other names could be e.g.
quantity_with_dims(but too long for my taste), ordims_asetc., butsimilaris already Julia lingo and feels appropriate in this context.