sostock / unitfulequivalences.jl Goto Github PK
View Code? Open in Web Editor NEWAn extension of Unitful.jl for converting between equivalent quantities
License: Other
An extension of Unitful.jl for converting between equivalent quantities
License: Other
In water treatment, for example, it is common to treat mg/l
as ppm
. Currently, UnitfulEquivalences.jl
does not allow equivalences involving nondimensional quantities such as concentration. I managed to do that with two dispatches of edconvert
:
@equivalence DensityConcentration
function edconvert(d::dimtype(Unitful.Density), x::Unitful.Quantity{T,D,U}, e::DensityConcentration) where {T,D,U}
D == NoDims ? x * 1u"kg/L" : throw(_eqconversion_error(d, D, e))
end
function edconvert(d::Unitful.Dimensions{()}, x::Unitful.Quantity{T,D,U}, e::DensityConcentration) where {T,D,U}
D == Unitful.π/Unitful.π^3 ? x * 1u"L/kg" : throw(_eqconversion_error(d, D, e))
end
But since it is a direct relation, it would be nice to be able to define them at once with something like
@equivalence DensityConcentration
@eqrelation DensityConcentration Unitful.Density / Unitful.NoDims = 1u"kg/l"
I extended dimtype
with dimtype(::Unitful.Dimensions{()}) = typeof(Unitful.NoDims)
(despite the type piracy warning) so it could handle nondimensional quantities, but it was not enough since apparently edrelation
also complains about Unitful.NoDims
as the second argument. I think this is also related to the fact that I had to use Unitful.Quantity{T,D,U}
in my first edconvert
solution above.
As for the second edconvert
, the following code also works for the conversion from Density
to NoDims
, without the need for Unitful.Quantity{T,D,U}
, but for some reason that I do not understand it also gives me a warning of type piracy:
edconvert(d::Unitful.Dimensions{()}, x::Unitful.Density, e::DensityConcentration) = x * 1u"L/kg"
So I guess this is a "feature request" to allow one nondimensional quantity in @eqrelation
.
I've been working on adding functional equivalences more general than the proportional and anti-proportional equivalences. I've managed to make it work with the same macro, with the arguments arranged as
@eqrelation name a = f(b)
where a
and b
are dimensions as in the (anti-)proportional equivalences and f
is a function with the proper dimensions. The current form for (anti-)proportional equivalences still work fine alongside this.
I am not attempting to do a PR now, but I wanted to show you how this is going so we can discuss whether you think this looks good or not. You can see how I have implemented this in my repo, in the branch
https://github.com/rmsrosa/UnitfulEquivalences.jl/tree/functional-equivalences
although this branch is not up to date with you main branch.
I have added a couple of made-up examples in runtests.jl
.
It is experimental for now. I should add the Plato-sg conversion in runtests.jl
. I have figured a way out of the fact that both are non-dimensional, without adding an artificial dimension to them, but at the cost of using separate equivalence names for each direction of the conversion.
I am pretty happy with what I have done, but I wish I knew how to implement directly simpler relations like, say f(b) = c b^2 + d
, by simply writing
@eqrelation name a = c * b^2 + c
where b
and c
are some known constant units, or even just a = b^2
, but I don't yet know how to have the code figure out from the expression c * b^2 + d
that b
is the variable and that the function is f(b) = c * b^2 + d
, and so on.
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
Hello, again,
I just crossed by this project today, when looking for something else:
https://yt-project.org/doc/analyzing/units/unit_equivalencies.html
It is for python. I don't know the status of it. But there are many equivalences there. Don't know whether you would like to implement them, but I thought I should share it with you.
By the way, I am working on this package here and I thank you for the things I learned with you that I eventually used on it: UnitfulCurrencies.jl.
Cheers!
Hi,
Why do you need to define cΒ²
for
const cΒ² = Quantity(convert(Int64, ustrip(c0)), unit(c0))^2
@eqrelation MassEnergy Energy/Mass = cΒ²
instead of just using directly c0^2
:
@eqrelation MassEnergy Energy/Mass = c0^2
?
@equivalence
does not do much more than @eqrelation
, it just defines the struct before adding the relation. That doesnβt seem like it provides much value. I see two options:
@equivalence
to only define the struct. Users would then write
@equivalence MassEnergy
@eqrelation MassEnergy Unitful.Energy/Unitful.Mass = Unitful.c0^2
@equivalence
provides much value either.@equivalence
, the user would then write
struct MassEnergy <: Equivalence end
@eqrelation MassEnergy Unitful.Energy/Unitful.Mass = Unitful.c0^2
I currently prefer option 2.
(@v1.9) pkg> activate --temp
Activating new project at `/tmp/jl_Eysq8z`
julia> using Unitful
julia> using UnitfulEquivalences
julia> x = 2.0u"eV"
2.0 eV
julia> uconvert(u"eV", x, Spectral())
ERROR: ArgumentError: Spectral(frequency=:linear, wavelength=:linear, wavenumber=:linear) defines no equivalence between dimensions π^2 π π^-2 and π^2 π π^-2.
Stacktrace:
[1] edconvert(d::Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1), Unitful.Dimension{:Mass}(1//1), Unitful.Dimension{:Time}(-2//1))}, x::Quantity{Float64, π^2 π π^-2, Unitful.FreeUnits{(eV,), π^2 π π^-2, nothing}}, e::Spectral{:linear, :linear, :linear})
@ UnitfulEquivalences ~/.julia/packages/UnitfulEquivalences/JvL7D/src/UnitfulEquivalences.jl:32
[2] uconvert(u::Unitful.FreeUnits{(eV,), π^2 π π^-2, nothing}, x::Quantity{Float64, π^2 π π^-2, Unitful.FreeUnits{(eV,), π^2 π π^-2, nothing}}, e::Spectral{:linear, :linear, :linear})
@ UnitfulEquivalences ~/.julia/packages/UnitfulEquivalences/JvL7D/src/UnitfulEquivalences.jl:54
[3] top-level scope
@ REPL[8]:1
(jl_Eysq8z) pkg> status
Status `/tmp/jl_Eysq8z/Project.toml`
[1986cc42] Unitful v1.16.3
[da9c4bc3] UnitfulEquivalences v0.2.0
I'd expect UnitfulEquivalences
to accept generic conversions (even within the same dimensions),
to allow for generic programming (i.e. if my core functions would ustrip(u"eV", x, Spectral())
for internal usage,
and work whether the user passed x
in nm
or eV
or meV
for instance).
Workaround:
custom_ustrip(dest_unit, x) =
if dimension(x) == dimension(dest_unit)
# plain Unitful ustrip
Unitful.ustrip(dest_unit, x)
else
UnitfulEquivalences.ustrip(dest_unit, x, UnitfulEquivalences.Spectral())
end
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.